fix: example client bug fixes & handle ping/pongs on server
This commit is contained in:
13
README.md
13
README.md
@@ -1 +1,14 @@
|
|||||||
# Connect4 Moderator - Server
|
# Connect4 Moderator - Server
|
||||||
|
|
||||||
|
A WebSocket server for the Connect4 Moderator.
|
||||||
|
|
||||||
|
An example client can be found in the [`example_client.py`](https://github.com/joshuafhiggins/connect4-moderator-server/blob/main/example_client.py) file.
|
||||||
|
|
||||||
|
In order to run the example you need:
|
||||||
|
- Python 3
|
||||||
|
- `pip install websockets`
|
||||||
|
- `pip install pip-system-certs`
|
||||||
|
|
||||||
|
To run the example, run `python example_client.py`.
|
||||||
|
|
||||||
|
The visual client for observing games/tournaments as well as managing games can be found at [`connect4-moderator-observer`](https://github.com/joshuafhiggins/connect4-moderator-observer).
|
||||||
@@ -7,13 +7,7 @@ class Slot(Enum):
|
|||||||
RED = 1
|
RED = 1
|
||||||
BLUE = 2
|
BLUE = 2
|
||||||
|
|
||||||
# Global board state (6 columns x 5 rows)
|
def calculate_move(opponent_move, board, our_color, opponent_color):
|
||||||
board = [[Slot.NONE] * 5 for _ in range(6)]
|
|
||||||
|
|
||||||
our_color = None
|
|
||||||
opponent_color = None
|
|
||||||
|
|
||||||
def calculate_move(opponent_move):
|
|
||||||
if opponent_move is not None:
|
if opponent_move is not None:
|
||||||
print(f"Opponent played column {opponent_move}")
|
print(f"Opponent played column {opponent_move}")
|
||||||
# TODO: Implement your move calculation logic here instead
|
# TODO: Implement your move calculation logic here instead
|
||||||
@@ -21,25 +15,30 @@ def calculate_move(opponent_move):
|
|||||||
return int(input("Column: "))
|
return int(input("Column: "))
|
||||||
|
|
||||||
async def gameloop (socket):
|
async def gameloop (socket):
|
||||||
while socket.open: # While game is active, continually anticipate messages
|
board = [[Slot.NONE] * 5 for _ in range(6)]
|
||||||
|
our_color = Slot.NONE
|
||||||
|
opponent_color = Slot.NONE
|
||||||
|
while True: # While game is active, continually anticipate messages
|
||||||
message = (await socket.recv()).split(':') # Receive message from server
|
message = (await socket.recv()).split(':') # Receive message from server
|
||||||
|
print(f"Received message: {message}")
|
||||||
|
|
||||||
match message[0]:
|
match message[0]:
|
||||||
case 'CONNECT:ACK':
|
case 'CONNECT':
|
||||||
await socket.send('READY')
|
await socket.send('READY')
|
||||||
|
|
||||||
case 'GAMESTART': # Game has started
|
case 'GAME':
|
||||||
if message[1] == '1':
|
if message[1] == 'START':
|
||||||
our_color = Slot.RED
|
if message[2] == '1':
|
||||||
opponent_color = Slot.BLUE
|
our_color = Slot.RED
|
||||||
col = calculate_move(None) # calculate_move is some arbitrary function you have created to figure out the next move
|
opponent_color = Slot.BLUE
|
||||||
await socket.send(f'PLAY:{col}') # Send your move to the sever
|
col = calculate_move(None, board, our_color, opponent_color) # calculate_move is some arbitrary function you have created to figure out the next move
|
||||||
else:
|
await socket.send(f'PLAY:{col}') # Send your move to the sever
|
||||||
our_color = Slot.BLUE
|
else:
|
||||||
opponent_color = Slot.RED
|
our_color = Slot.BLUE
|
||||||
|
opponent_color = Slot.RED
|
||||||
|
|
||||||
case 'OPPONENT': # Opponent has gone; calculate next move
|
case 'OPPONENT': # Opponent has gone; calculate next move
|
||||||
col = calculate_move(message[1]) # Give your function your opponent's move
|
col = calculate_move(message[1], board, our_color, opponent_color) # Give your function your opponent's move
|
||||||
await socket.send(f'PLAY:{col}') # Send your move to the sever
|
await socket.send(f'PLAY:{col}') # Send your move to the sever
|
||||||
|
|
||||||
case 'WIN' | 'LOSS' | 'DRAW' | 'TERMINATED': # Game has ended
|
case 'WIN' | 'LOSS' | 'DRAW' | 'TERMINATED': # Game has ended
|
||||||
@@ -47,10 +46,17 @@ async def gameloop (socket):
|
|||||||
board = [[Slot.NONE] * 5 for _ in range(6)]
|
board = [[Slot.NONE] * 5 for _ in range(6)]
|
||||||
our_color = None
|
our_color = None
|
||||||
opponent_color = None
|
opponent_color = None
|
||||||
|
await socket.send('READY')
|
||||||
|
|
||||||
|
case 'KICK':
|
||||||
|
print("You have been kicked from the game")
|
||||||
|
break
|
||||||
|
|
||||||
case 'ERROR':
|
case 'ERROR':
|
||||||
print(f"Error: {':'.join(message[1:])}")
|
print(f"{message[0]}: {':'.join(message[1:])}")
|
||||||
exit()
|
break
|
||||||
|
|
||||||
|
await socket.close()
|
||||||
|
|
||||||
async def join_server(username):
|
async def join_server(username):
|
||||||
async with websockets.connect(f'wss://connect4.abunchofknowitalls.com') as socket: # Establish websocket connection
|
async with websockets.connect(f'wss://connect4.abunchofknowitalls.com') as socket: # Establish websocket connection
|
||||||
|
|||||||
@@ -379,13 +379,13 @@ async fn handle_connection(
|
|||||||
info!("Client {} disconnected", addr);
|
info!("Client {} disconnected", addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Ok(_) => {
|
Ok(Message::Ping(b)) => { let _ = tx.send(Message::Pong(b)); }
|
||||||
let _ = send(&tx, "ERROR:UNKNOWN");
|
Ok(Message::Binary(_)) => { let _ = send(&tx, "ERROR:UNKNOWN"); }
|
||||||
}
|
Ok(_) => { info!("Received pong/frame? Something fishy is happening") },
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("WebSocket error for {}: {}", addr, e);
|
error!("WebSocket error for {}: {}", addr, e);
|
||||||
break;
|
break;
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user