ultimate_tictactoe_server/game_manager.py

186 lines
4.8 KiB
Python
Raw Normal View History

2019-03-10 00:29:52 +01:00
#!/usr/bin/env python3
import asyncio
import websockets
import json
player_id_queue = set()
sockets = {}
player_games = {}
async def register_user(id, socket):
if id in player_id_queue:
return False
player_id_queue.add(id)
sockets[id] = socket
await matchmaking()
return True
async def unregister_user(id):
if id in player_id_queue:
player_id_queue.remove(id)
del(sockets[id])
elif id in player_games:
# we have an active game and have to end it
await player_games[id]._on_end_game(id)
del(player_games[id])
async def process_message(id, json):
if id in player_games:
await player_games[id].processPlayerMessage(id, json)
async def create_new_match():
p_a = player_id_queue.pop()
p_b = player_id_queue.pop()
s_a = sockets[p_a]
s_b = sockets[p_b]
del(sockets[p_a])
del(sockets[p_b])
new_game = GameManager(p_a, p_b, p_a, s_a, s_b)
player_games[p_a] = new_game
player_games[p_b] = new_game
await new_game.startMatch()
async def matchmaking():
if len(player_id_queue) < 2:
# we need at least 2 users for that
return
else:
asyncio.ensure_future(create_new_match())
class GameManager(object):
def __init__(self, player_a_id, player_b_id, start_player, socket_a, socket_b):
self.player_a_id = player_a_id
self.player_b_id = player_b_id
self.socket_a = socket_a
self.socket_b = socket_b
self.current_player = start_player
self.game_finished = False
async def startMatch(self):
print("match starts")
start_msg_a = {
'type': 'game_starts',
'data': {
'msg': '...',
'opponent_name': self.player_b_id,
'is_first_move': True
}
}
start_msg_b = {
'type': 'game_starts',
'data': {
'msg': '...',
'opponent_name': self.player_a_id,
'is_first_move': False
}
}
await self.socket_a.send(json.dumps(start_msg_a))
await self.socket_b.send(json.dumps(start_msg_b))
print("start message send to all players")
async def processPlayerMessage(self, player_id, json_str):
if len(json_str) > 4096:
# something is fishy here
print("received strange message from client")
print("received message: " + json_str)
try:
json_dict = json.loads(json_str)
type = json_dict['type']
data = json_dict['data']
if type == "move":
await self._on_move(player_id, data)
elif type == "end_game":
await self._on_end_game(player_id)
except Exception as e:
print("" + str(e) + ": received wrong formated message")
async def _on_move(self, player_id, move_data):
response = {'type': 'move_response'}
response_data = {}
opponent_response = {'type': 'move'}
opponent_response_data = {}
opponent_response_data['sub_x'] = move_data['sub_x']
opponent_response_data['sub_y'] = move_data['sub_y']
opponent_response_data['x'] = move_data['x']
opponent_response_data['y'] = move_data['y']
opponent_response['data'] = opponent_response_data
if player_id == self.current_player:
is_a = (self.player_a_id == player_id)
current_socket = self.socket_a if is_a else self.socket_b
opponent_socket = self.socket_b if is_a else self.socket_a
response_data['success'] = True
response_data['msg'] = "move successful"
response['data'] = response_data
await opponent_socket.send(json.dumps(opponent_response))
await current_socket.send(json.dumps(response))
# switch player
self.current_player = self.player_b_id if is_a else self.player_a_id
else:
print("received move from wrong player")
is_a = (self.player_a_id == player_id)
current_socket = self.socket_a if is_a else self.socket_b
response_data["success"] = False
response_data["msg"] = "not your turn!"
response['data'] = response_data
await current_socket.send(json.dumps(response))
async def _on_end_game(self, player_id):
if self.game_finished:
return
is_a = (self.player_a_id == player_id)
opponent_socket = self.socket_b if is_a else self.socket_a
opponent_response = {'type': 'end_game'}
opponent_response['data'] = {'msg': 'game closed by opponent'}
await opponent_socket.send(json.dumps(opponent_response))
self.game_finished = True