66 lines
1.6 KiB
Python
66 lines
1.6 KiB
Python
#!/usr/bin/env python
|
|
|
|
import asyncio
|
|
import itertools
|
|
import json
|
|
|
|
from websockets.asyncio.server import serve
|
|
|
|
from connect4 import PLAYER1, PLAYER2, Connect4
|
|
|
|
|
|
async def handler(websocket):
|
|
# Initialize a Connect Four game.
|
|
game = Connect4()
|
|
|
|
# Players take alternate turns, using the same browser.
|
|
turns = itertools.cycle([PLAYER1, PLAYER2])
|
|
player = next(turns)
|
|
|
|
async for message in websocket:
|
|
# Parse a "play" event from the UI.
|
|
event = json.loads(message)
|
|
assert event["type"] == "play"
|
|
column = event["column"]
|
|
|
|
try:
|
|
# Play the move.
|
|
row = game.play(player, column)
|
|
except ValueError as exc:
|
|
# Send an "error" event if the move was illegal.
|
|
event = {
|
|
"type": "error",
|
|
"message": str(exc),
|
|
}
|
|
await websocket.send(json.dumps(event))
|
|
continue
|
|
|
|
# Send a "play" event to update the UI.
|
|
event = {
|
|
"type": "play",
|
|
"player": player,
|
|
"column": column,
|
|
"row": row,
|
|
}
|
|
await websocket.send(json.dumps(event))
|
|
|
|
# If move is winning, send a "win" event.
|
|
if game.winner is not None:
|
|
event = {
|
|
"type": "win",
|
|
"player": game.winner,
|
|
}
|
|
await websocket.send(json.dumps(event))
|
|
|
|
# Alternate turns.
|
|
player = next(turns)
|
|
|
|
|
|
async def main():
|
|
async with serve(handler, "", 8001) as server:
|
|
await server.serve_forever()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|