-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.py
66 lines (50 loc) · 2.2 KB
/
server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
from netcode import ServerChannel
from board import Board, Tile, deserialize_place
def wait_for_players(channel: ServerChannel) -> dict[Tile, str]:
print("[INFO] Waiting for players...")
clients: set[str] = set()
while len(clients) < 2:
message = channel.receive_any()
if message.tag == "connected":
clients.add(message.sender)
elif message.tag == "disconnected":
clients.discard(message.sender)
black_uid = clients.pop()
white_uid = clients.pop()
return {Tile.BLACK: black_uid, Tile.WHITE: white_uid}
def game_loop(channel: ServerChannel, players: dict[Tile, str]):
print("[INFO] Starting the game!")
board = Board()
turn = Tile.BLACK
while board.winner() == Tile.EMPTY:
messages = channel.flush_mailbox()
for message in messages:
if message.tag == "disconnected" and message.sender in players.values:
print(f"[INFO] Player ({message.sender}) left the game!")
winner = Tile.WHITE if players[Tile.BLACK] == message.sender else Tile.BLACK
print(f"[INFO] Game finished, winner: {winner}")
channel.broadcast("winner", winner.value)
return
print(f"[INFO] Starting {turn}'s turn!")
print("[INFO] Sending board state...")
channel.broadcast("board", board.serialize())
channel.receive_matching(lambda m: m.sender == players[turn] and m.tag == "board-ack")
move = None
while move is None:
print("[INFO] Waiting for player's move...")
channel.send_to_client(players[turn], "your-turn", turn.value)
message = channel.receive_matching(lambda m: m.sender == players[turn] and m.tag == "place")
move = deserialize_place(message.content)
row, col = move
board.place(row, col, turn)
turn = turn.opposite()
winner = board.winner()
print(f"[INFO] Game finished, winner: {winner}")
channel.broadcast("winner", winner.value)
def main():
print("[INFO] Starting...")
with ServerChannel() as channel:
players = wait_for_players(channel)
game_loop(channel, players)
if __name__ == "__main__":
main()