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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
from flask import Blueprint, request, make_response
from flask_socketio import SocketIO, emit, Namespace, join_room
from game.voerbak_connector import bord
from db import cursor, connection
from socket_io import io
from hierarchy import io_auth_required
import time
import json
games = {}
def participants_only(func):
'''
listener should have two parameters:
listener(data: socket.io.data, user_id: str, game: game)
listener should only be executed if the request comes from one of
the game participants (player_1_id | player_2_id)
'''
def wrapper(data, user_id):
game_id = data["game_id"]
if not game_id or \
not game_id in games:
return
game = games[game_id]
if game.player_1_id != user_id and \
game.player_2_id != user_id:
return
return func(data, user_id, game)
wrapper.__name__ = func.__name__
return wrapper
class game:
def __init__(self, game_id, io, player_1_id, player_2_id):
self.game_id = game_id
self.room = "game-" + game_id
self.board = bord(7, 6)
self.io = io
self.player_1_id = player_1_id
self.player_2_id = player_2_id
# drop a disc in `column`
def move(self, user_id, column):
if len(self.board.win_positions) > 0: return
if self.board.board_full: return
move = self.player_1_id if self.board.player_1 else self.player_2_id
if user_id != move: return
self.board.drop_fisje(column)
io.emit("fieldUpdate", {"field": self.board.board}, room=self.room)
now = int(time.time() * 1000)
cursor.execute(
"update games set last_activity = ?, moves = moves || ? || ',' where game_id = ?",
[now, column, self.game_id]
)
connection.commit()
if len(self.board.win_positions) > 0 or self.board.board_full:
outcome = "d"
if not self.board.board_full:
winner = self.board.board[int(self.board.win_positions[0][0])]
outcome = "w" if winner == "2" else "l"
io.emit(
"finish", {
"winPositions": self.board.win_positions,
"boardFull": self.board.board_full
},
room=self.room
)
self.close("finished", outcome)
return
io.emit("turnUpdate", {"player1": self.board.player_1}, room=self.room)
def resign(self):
self.board.kill_voerbak()
io.emit("resign", room=self.room)
self.close("resign", "d")
def close(self, new_status, outcome):
cursor.execute(
" ".join(
[
"update games set", "moves = moves || '0',",
"duration = ?,", "status = ?,", "outcome = ?",
"where game_id = ?"
]
), [
int(time.time() * 1000) - cursor.execute(
"select started from games where game_id = ?",
[self.game_id]
).fetchone()[0], new_status, outcome, self.game_id
]
)
connection.commit()
games.pop(self.game_id)
@io.on("newMove")
@io_auth_required("none")
@participants_only
def new_move(data, user_id, game):
move = data.get("move")
if not move: return
game.move(user_id, move)
@io.on("resign")
@io_auth_required("none")
@participants_only
def resign(data, user_id, game):
game.resign()
@io.on("registerGameListener")
def register_game_listener(data):
game_id = data.get("game_id")
if not game_id: return
join_room("game-" + game_id)
|