Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
Menteur
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PLN
Menteur
Commits
a9a2cae1
Unverified
Commit
a9a2cae1
authored
Apr 19, 2020
by
PLN (Algolia)
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Refactor async, works until givehand
parent
02b95030
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
97 additions
and
65 deletions
+97
-65
app.py
server/app.py
+1
-2
lobby.py
server/game/lobby.py
+70
-41
manager.py
server/game/manager.py
+1
-1
game.py
server/model/game.py
+12
-11
ws.py
server/ws.py
+13
-10
No files found.
server/app.py
View file @
a9a2cae1
...
@@ -36,8 +36,7 @@ async def hello_world():
...
@@ -36,8 +36,7 @@ async def hello_world():
@router.get
(
"/reset"
)
@router.get
(
"/reset"
)
async
def
reset
(
async
def
reset
(
):
):
lobby
.
reset
()
return
lobby
.
reset
()
return
"Done."
app
.
include_router
(
router
)
app
.
include_router
(
router
)
...
...
server/game/lobby.py
View file @
a9a2cae1
import
asyncio
import
json
import
json
from
typing
import
List
,
Dict
,
Optional
from
typing
import
List
,
Dict
,
Optional
...
@@ -37,30 +38,48 @@ class LobbyManager(ClientManager):
...
@@ -37,30 +38,48 @@ class LobbyManager(ClientManager):
def
players_ready
(
self
):
def
players_ready
(
self
):
return
[
self
.
lobby
[
k
]
for
k
,
m
in
self
.
metadata
.
items
()
if
m
.
ready
]
return
[
self
.
lobby
[
k
]
for
k
,
m
in
self
.
metadata
.
items
()
if
m
.
ready
]
async
def
new_player
(
self
,
player
:
Player
,
sid
:
str
)
->
str
:
def
new_player
(
self
,
player
:
Player
,
sid
:
str
)
->
str
:
self
.
lobby
[
player
.
name
]
=
player
self
.
lobby
[
player
.
name
]
=
player
self
.
players
.
append
(
player
)
self
.
metadata
[
player
.
name
]
=
Metadata
(
sid
=
sid
)
self
.
metadata
[
player
.
name
]
=
Metadata
(
sid
=
sid
)
print
(
f
"Added {player} to a lobby with {len(self.lobby)} players."
)
print
(
f
"Added {player} to a lobby with {len(self.lobby)} players."
)
return
f
"Bienvenu, {player}! Il y a {len(self.lobby)} joueurs en ligne."
return
f
"Bienvenu, {player}! Il y a {len(self.lobby)} joueurs en ligne."
def
wants_to_play
(
self
,
player
:
Player
):
def
wants_to_play
(
self
,
player
:
Player
):
"""
Notes that a player wants to play, starting a game if others too.
"""
self
.
metadata
[
player
.
name
]
.
ready
=
True
self
.
metadata
[
player
.
name
]
.
ready
=
True
print
(
f
"
{player} ready to play! ({self.nb_ready} people ready)
"
)
print
(
f
"
Lobby | {player} wants to play!
"
)
async
def
announces
(
self
,
player
:
Player
,
announce
:
Announce
):
ready
=
self
.
players_ready
# FIXME: Call this message on incoming "ANNOUNCE"
return
ready
async
def
maybe_start_game
(
self
):
print
(
"Should we start a game?"
)
ready
=
self
.
players_ready
if
len
(
ready
)
>
1
:
await
self
.
start_game
(
ready
)
print
(
f
"Lobby: Game started. with {ready}."
)
def
just_announced
(
self
,
player
:
Player
,
announce
:
Announce
):
meta
=
self
.
metadata
[
player
.
name
]
meta
=
self
.
metadata
[
player
.
name
]
meta
.
last_announce
=
announce
meta
.
last_announce
=
announce
meta
.
fresh_announce
=
True
meta
.
fresh_announce
=
True
print
(
f
"{player} ready to play! ({self.nb_ready} people ready)"
)
print
(
f
"{player} announced {announce}!"
)
async
def
start_game
(
self
,
players
:
Optional
[
List
[
Player
]]
=
None
,
max_players
=
2
):
if
not
players
:
players
=
self
.
players_ready
[:
max_players
]
game
=
Game
(
players
,
manager
=
self
)
self
.
games
.
append
(
game
)
def
start_game
(
self
,
max_players
=
2
):
players
=
self
.
players_ready
[:
max_players
]
self
.
games
.
append
(
Game
(
players
,
manager
=
self
))
for
p
in
players
:
for
p
in
players
:
self
.
metadata
[
p
.
name
]
.
ready
=
False
self
.
metadata
[
p
.
name
]
.
ready
=
False
print
(
f
"Game started : {' vs '.join([p.name for p in players])}"
)
print
(
f
"Game started : {' vs '.join([p.name for p in players])}"
)
await
game
.
new_game
()
def
reset
(
self
):
def
reset
(
self
):
players
=
len
(
self
.
players
)
players
=
len
(
self
.
players
)
...
@@ -72,27 +91,27 @@ class LobbyManager(ClientManager):
...
@@ -72,27 +91,27 @@ class LobbyManager(ClientManager):
self
.
send
(
p
,
MessageToPlayer
.
Reset
)
self
.
send
(
p
,
MessageToPlayer
.
Reset
)
self
.
sio
.
disconnect
(
m
.
sid
)
self
.
sio
.
disconnect
(
m
.
sid
)
self
.
lobby
.
clear
()
self
.
lobby
.
clear
()
self
.
players
.
clear
()
self
.
metadata
.
clear
()
self
.
metadata
.
clear
()
self
.
games
.
clear
()
self
.
games
.
clear
()
print
(
f
"Reset done, {players} players, {games} games."
)
print
(
f
"Reset done, {players} players, {games} games."
)
return
msg
return
msg
def
send
(
self
,
to
:
Player
,
message
:
MessageToPlayer
,
extra
=
None
):
async
def
send
(
self
,
to
:
Player
,
message
:
MessageToPlayer
,
extras
=
None
):
data
=
{
message
:
message
.
name
}
sid
=
self
.
metadata
[
to
.
name
]
.
sid
if
extra
:
data
=
{
"message"
:
str
(
message
.
name
)}
data
[
"extra"
]
=
extra
if
extras
:
self
.
sio
.
send
(
message
)
data
[
"extra"
]
=
extras
pass
print
(
f
"MSGOUT|{sid} ({to.name}), {data}"
)
await
self
.
sio
.
emit
(
'messageChannel'
,
json
.
dumps
(
data
),
room
=
sid
)
def
handle_message
(
self
,
sid
,
data
):
async
def
handle_message
(
self
,
sid
,
data
):
message
=
None
message
=
None
extras
=
{
"players"
:
[
p
.
name
for
p
in
self
.
players
]}
extras
=
{
"players"
:
[
p
.
name
for
p
in
self
.
players
]}
print
(
f
"Lobby| Received message from {sid}: {data}."
)
sender
=
self
.
which_player
(
sid
)
sender
=
self
.
which_player
(
sid
)
if
sender
:
print
(
f
"Lobby| Found sender: {sender.name}
"
)
print
(
f
"MSGIN| {sid} ({sender.name}): {data}.
"
)
for
option
in
MessageFromPlayer
:
for
option
in
MessageFromPlayer
:
if
option
.
value
in
data
:
if
option
.
value
in
data
:
...
@@ -100,34 +119,44 @@ class LobbyManager(ClientManager):
...
@@ -100,34 +119,44 @@ class LobbyManager(ClientManager):
if
option
==
MessageFromPlayer
.
Waiting
:
if
option
==
MessageFromPlayer
.
Waiting
:
self
.
metadata
[
sender
.
name
]
.
ready
=
False
self
.
metadata
[
sender
.
name
]
.
ready
=
False
print
(
f
"
MSG|Player {sender.name} waiting, while {extras} ready.
"
)
print
(
f
"
Lobby| Player {sender.name} waiting
"
)
if
len
(
self
.
players_ready
)
>
1
:
message
=
MessageToPlayer
.
ReadyToStart
\
message
=
MessageToPlayer
.
ReadyToStart
if
len
(
self
.
players_ready
)
>
1
else
MessageToPlayer
.
Waiting
elif
option
==
MessageFromPlayer
.
Ready
:
elif
option
==
MessageFromPlayer
.
Ready
:
self
.
wants_to_play
(
player
=
sender
)
print
(
f
"Lobby|Player {sender.name} ready"
)
print
(
f
"MSG|Players ready: {extras}."
)
gamers
=
self
.
wants_to_play
(
player
=
sender
)
if
gamers
:
print
(
f
"Game ready! gamers={gamers}"
)
message
=
MessageToPlayer
.
NewGame
extras
[
"playersPlaying"
]
=
[
p
.
name
for
p
in
gamers
]
else
:
print
(
f
"Still alone ready!"
)
message
=
MessageToPlayer
.
ReadyToStart
extras
[
"playersReady"
]
=
[
p
.
name
for
p
in
self
.
players_ready
]
message
=
MessageToPlayer
.
ReadyToStart
\
if
len
(
self
.
players_ready
)
>
1
else
MessageToPlayer
.
Waiting
extras
[
"playersReady"
]
=
[
p
.
name
for
p
in
self
.
players_ready
]
elif
option
==
MessageFromPlayer
.
Bet
:
elif
option
==
MessageFromPlayer
.
Bet
:
# FIXME vraie annonce, pas juste carre d'as lol
# FIXME vraie annonce, pas juste carre d'as lol
self
.
announces
(
player
=
sender
,
announce
=
Announce
(
bet
=
CARRE_ACE
)
announce
=
Announce
(
bet
=
CARRE_ACE
))
self
.
just_announced
(
player
=
sender
,
game
:
Game
=
self
.
game_with
(
sender
)
announce
=
announce
)
# TODO: connect with current game, return appropriate message
print
(
f
"Lobby| Player {sender.name} just announced {announce}."
)
extras
[
"youBet"
]
=
announce
.
bet
elif
option
==
MessageFromPlayer
.
Menteur
:
elif
option
==
MessageFromPlayer
.
Menteur
:
self
.
announces
(
player
=
sender
,
announce
=
Announce
())
self
.
just_announced
(
player
=
sender
,
announce
=
Announce
())
# TODO: connect with current game, return appropriate messag
e
extras
[
"youBet"
]
=
Fals
e
body
=
{
"message"
:
message
.
name
if
message
else
"none"
}
if
message
:
if
extras
:
game
=
asyncio
.
create_task
(
self
.
maybe_start_game
())
body
[
"extras"
]
=
extras
await
self
.
send
(
sender
,
message
,
extras
)
return
json
.
dumps
(
body
)
await
game
def
which_player
(
self
,
sid
)
->
Player
:
def
which_player
(
self
,
sid
)
->
Player
:
sender
:
Optional
[
Player
]
=
None
sender
:
Optional
[
Player
]
=
None
...
@@ -139,8 +168,8 @@ class LobbyManager(ClientManager):
...
@@ -139,8 +168,8 @@ class LobbyManager(ClientManager):
def
game_with
(
self
,
player
:
Player
)
->
Game
:
def
game_with
(
self
,
player
:
Player
)
->
Game
:
return
[
g
for
g
in
self
.
games
if
player
in
g
.
players
][
0
]
return
[
g
for
g
in
self
.
games
if
player
in
g
.
players
][
0
]
def
send_waiting_for
(
self
,
player
:
Player
):
async
def
send_waiting_for
(
self
,
player
:
Player
):
game
=
self
.
game_with
(
player
)
game
=
self
.
game_with
(
player
)
self
.
send
(
player
,
MessageToPlayer
.
YourTurn
,
extra
=
{
"bet"
:
game
.
current_bet
})
await
self
.
send
(
player
,
MessageToPlayer
.
YourTurn
,
extras
=
{
"bet"
:
game
.
current_bet
})
for
p
in
[
p
for
p
in
game
.
players
if
p
!=
player
]:
for
p
in
[
p
for
p
in
game
.
players
if
p
!=
player
]:
self
.
send
(
p
,
MessageToPlayer
.
Waiting
,
extra
=
{
"waitingFor"
:
p
.
name
})
await
self
.
send
(
p
,
MessageToPlayer
.
Waiting
,
extras
=
{
"waitingFor"
:
p
.
name
})
server/game/manager.py
View file @
a9a2cae1
...
@@ -19,7 +19,7 @@ class ClientManager(ABC):
...
@@ -19,7 +19,7 @@ class ClientManager(ABC):
self
.
send
(
p
,
message
)
self
.
send
(
p
,
message
)
@abstractmethod
@abstractmethod
def
send
(
self
,
async
def
send
(
self
,
to
:
Player
,
to
:
Player
,
message
:
MessageToPlayer
,
message
:
MessageToPlayer
,
extra
=
None
):
extra
=
None
):
...
...
server/model/game.py
View file @
a9a2cae1
...
@@ -25,7 +25,7 @@ class Game:
...
@@ -25,7 +25,7 @@ class Game:
self
.
current_bet
:
Optional
[
Hand
]
=
None
self
.
current_bet
:
Optional
[
Hand
]
=
None
self
.
manager
=
manager
self
.
manager
=
manager
def
message
(
self
,
message
:
MessageToPlayer
,
async
def
message
(
self
,
message
:
MessageToPlayer
,
*
to
:
Player
,
*
to
:
Player
,
extra
=
None
extra
=
None
)
->
None
:
)
->
None
:
...
@@ -33,7 +33,7 @@ class Game:
...
@@ -33,7 +33,7 @@ class Game:
if
not
to
:
if
not
to
:
to
=
self
.
players
to
=
self
.
players
for
player
in
to
:
for
player
in
to
:
self
.
manager
.
send
(
player
,
message
,
extra
)
await
self
.
manager
.
send
(
player
,
message
,
extra
)
@property
@property
def
global_hand
(
self
)
->
Hand
:
def
global_hand
(
self
)
->
Hand
:
...
@@ -41,6 +41,7 @@ class Game:
...
@@ -41,6 +41,7 @@ class Game:
return
Hand
(
cards
=
all_cards
)
return
Hand
(
cards
=
all_cards
)
async
def
new_game
(
self
):
async
def
new_game
(
self
):
print
(
f
"Game starting with {self.players}!"
)
self
.
deck
.
reset
()
self
.
deck
.
reset
()
while
len
(
self
.
players
)
>
1
:
while
len
(
self
.
players
)
>
1
:
...
@@ -48,14 +49,14 @@ class Game:
...
@@ -48,14 +49,14 @@ class Game:
if
self
.
defeats
[
loser
]
==
5
:
if
self
.
defeats
[
loser
]
==
5
:
print
(
f
"{loser} is eliminated!"
)
print
(
f
"{loser} is eliminated!"
)
self
.
message
(
MessageToPlayer
.
Lose
,
loser
)
await
self
.
message
(
MessageToPlayer
.
Lose
,
loser
)
self
.
players
.
remove
(
loser
)
self
.
players
.
remove
(
loser
)
else
:
else
:
print
(
f
"{loser} lost the round, now playing with {self.defeats[loser] + 1} cards!"
)
print
(
f
"{loser} lost the round, now playing with {self.defeats[loser] + 1} cards!"
)
winner
=
self
.
players
[
0
]
winner
=
self
.
players
[
0
]
self
.
message
(
MessageToPlayer
.
Win
,
winner
)
await
self
.
message
(
MessageToPlayer
.
Win
,
winner
)
self
.
message
(
MessageToPlayer
.
WinnerIs
,
extra
=
winner
)
await
self
.
message
(
MessageToPlayer
.
WinnerIs
,
extra
=
winner
)
print
(
f
"Game over - {winner.name} wins with {len(winner.hand)} cards!"
)
print
(
f
"Game over - {winner.name} wins with {len(winner.hand)} cards!"
)
async
def
new_turn
(
self
)
->
Player
:
async
def
new_turn
(
self
)
->
Player
:
...
@@ -67,7 +68,7 @@ class Game:
...
@@ -67,7 +68,7 @@ class Game:
# Distribution
# Distribution
self
.
deck
.
reset
()
self
.
deck
.
reset
()
self
.
message
(
MessageToPlayer
.
WaitTurn
)
await
self
.
message
(
MessageToPlayer
.
WaitTurn
)
for
current_player
in
self
.
players
:
for
current_player
in
self
.
players
:
current_player
.
clear
()
current_player
.
clear
()
count_player_cards
=
self
.
defeats
[
current_player
]
+
1
count_player_cards
=
self
.
defeats
[
current_player
]
+
1
...
@@ -77,7 +78,7 @@ class Game:
...
@@ -77,7 +78,7 @@ class Game:
current_player
.
give
(
card
)
current_player
.
give
(
card
)
print
(
f
"{card}"
)
print
(
f
"{card}"
)
self
.
message
(
MessageToPlayer
.
GiveHand
,
current_player
,
extra
=
current_player
.
hand
)
await
self
.
message
(
MessageToPlayer
.
GiveHand
,
current_player
,
extra
=
current_player
.
hand
)
print
(
f
"Cards sent."
)
print
(
f
"Cards sent."
)
# Tour
# Tour
...
@@ -88,7 +89,7 @@ class Game:
...
@@ -88,7 +89,7 @@ class Game:
if
loser
is
not
None
:
if
loser
is
not
None
:
self
.
players
.
remove
(
loser
)
self
.
players
.
remove
(
loser
)
self
.
players
.
insert
(
0
,
loser
)
self
.
players
.
insert
(
0
,
loser
)
self
.
message
(
MessageToPlayer
.
LoseRound
,
extra
=
loser
.
name
)
await
self
.
message
(
MessageToPlayer
.
LoseRound
,
extra
=
loser
.
name
)
return
loser
return
loser
last_player
=
current_player
last_player
=
current_player
...
@@ -142,14 +143,14 @@ class Game:
...
@@ -142,14 +143,14 @@ class Game:
print
(
f
"| {current_player}'s turn >"
)
print
(
f
"| {current_player}'s turn >"
)
if
not
self
.
current_bet
:
# First player, has to bet something
if
not
self
.
current_bet
:
# First player, has to bet something
self
.
message
(
MessageToPlayer
.
YourTurn
,
current_player
,
extra
=
self
.
current_bet
)
await
self
.
message
(
MessageToPlayer
.
YourTurn
,
current_player
,
extra
=
self
.
current_bet
)
while
not
self
.
current_bet
:
# Ask a valid bet
while
not
self
.
current_bet
:
# Ask a valid bet
# FIXME: Wait for player announce? Maybe just sleep 10?
# FIXME: Wait for player announce? Maybe just sleep 10?
announce
=
await
current_player
.
announce
(
self
.
current_bet
)
announce
=
await
current_player
.
announce
(
self
.
current_bet
)
if
announce
.
bet
:
if
announce
.
bet
:
self
.
current_bet
=
announce
.
bet
self
.
current_bet
=
announce
.
bet
print
(
f
"{current_player} starts the round: {self.current_bet}"
)
print
(
f
"{current_player} starts the round: {self.current_bet}"
)
self
.
message
(
MessageToPlayer
.
Announce
,
extra
=
{
"player"
:
current_player
,
"announce"
:
announce
})
await
self
.
message
(
MessageToPlayer
.
Announce
,
extra
=
{
"player"
:
current_player
,
"announce"
:
announce
})
else
:
else
:
print
(
f
"You cannot say Menteur on first round, {current_player}!"
)
print
(
f
"You cannot say Menteur on first round, {current_player}!"
)
...
@@ -160,7 +161,7 @@ class Game:
...
@@ -160,7 +161,7 @@ class Game:
print
(
"CARRE D'AS!"
)
print
(
"CARRE D'AS!"
)
announce
=
Announce
()
# MENTEUR obligatoire
announce
=
Announce
()
# MENTEUR obligatoire
else
:
else
:
self
.
message
(
MessageToPlayer
.
YourTurn
,
current_player
,
extra
=
self
.
current_bet
)
await
self
.
message
(
MessageToPlayer
.
YourTurn
,
current_player
,
extra
=
self
.
current_bet
)
announce
=
current_player
.
announce
(
self
.
current_bet
)
announce
=
current_player
.
announce
(
self
.
current_bet
)
if
announce
.
bet
:
if
announce
.
bet
:
...
...
server/ws.py
View file @
a9a2cae1
...
@@ -3,8 +3,7 @@ from typing import Optional
...
@@ -3,8 +3,7 @@ from typing import Optional
import
socketio
import
socketio
from
server.game.lobby
import
LobbyManager
from
server.game.lobby
import
LobbyManager
,
Metadata
from
server.game.message
import
MessageToPlayer
from
server.model.hand
import
Hand
from
server.model.hand
import
Hand
from
server.model.players
import
Player
,
Announce
from
server.model.players
import
Player
,
Announce
...
@@ -23,34 +22,38 @@ class ClientPlayer(Player):
...
@@ -23,34 +22,38 @@ class ClientPlayer(Player):
self
.
ready
=
False
self
.
ready
=
False
async
def
announce
(
self
,
current_bet
:
Optional
[
Hand
])
->
Announce
:
async
def
announce
(
self
,
current_bet
:
Optional
[
Hand
])
->
Announce
:
announce
=
None
metadata
:
Metadata
=
self
.
lobby
.
metadata
[
self
.
name
]
while
not
self
.
lobby
.
metadata
[
self
.
name
]
.
fresh_announce
:
print
(
f
"Asking Client {self.name} for announce..."
,
end
=
""
)
lobby
.
send_waiting_for
(
self
)
while
not
metadata
.
last_announce
and
metadata
.
fresh_announce
:
await
lobby
.
send_waiting_for
(
self
)
print
(
"."
,
end
=
""
)
sleep
(
2
)
sleep
(
2
)
return
lobby
.
last_announces
[
self
]
print
(
f
" {metadata.last_announce.bet}!"
)
return
metadata
.
last_announce
@sio.event
@sio.event
async
def
connect
(
sid
,
environ
):
async
def
connect
(
sid
,
environ
):
print
(
"[WS] Connect "
,
sid
,
environ
)
print
(
"[WS] Connect "
,
sid
,
environ
)
player
=
ClientPlayer
(
lobby
)
player
=
ClientPlayer
(
lobby
)
reply
:
str
=
await
lobby
.
new_player
(
player
,
sid
)
reply
:
str
=
lobby
.
new_player
(
player
,
sid
)
await
sio
.
emit
(
'messageChannel'
,
reply
,
room
=
sid
)
await
sio
.
emit
(
'messageChannel'
,
reply
,
room
=
sid
)
@sio.event
@sio.event
async
def
message
(
sid
,
data
):
async
def
message
(
sid
,
data
):
print
(
"[WS] Message "
,
data
)
print
(
"[WS] Message "
,
data
)
await
sio
.
emit
(
'messageChannel'
,
lobby
.
handle_message
(
sid
,
data
),
room
=
sid
)
await
lobby
.
handle_message
(
sid
,
data
)
@sio.on
(
"pingServer"
)
@sio.on
(
"pingServer"
)
async
def
ping_server
(
sid
,
data
):
async
def
ping_server
(
sid
,
data
):
print
(
"[WS] Ping received:"
,
data
)
print
(
"[WS] Ping received:"
,
data
)
await
sio
.
emit
(
'messageChannel'
,
"PONG"
)
await
sio
.
emit
(
'messageChannel'
,
"PONG"
,
room
=
sid
)
@sio.event
@sio.event
def
disconnect
(
sid
):
def
disconnect
(
sid
):
print
(
'[WS] Disconnect '
,
sid
)
print
(
'[WS] Disconnect '
,
sid
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment