-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.py
More file actions
199 lines (158 loc) · 6.3 KB
/
Copy pathserver.py
File metadata and controls
199 lines (158 loc) · 6.3 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
from dataclasses import dataclass
from enum import Enum
import asyncio
import json
import websockets
class Bbool(str, Enum):
false = "false"
true = "true"
@dataclass
class Piece:
id: int # Maybe not necessary
x_pos: float # distance of left edge to board in percent
y_pos: float # distance of top edge to board in percent
z_pos: int = 0 # css z of element
height: float|Bbool = Bbool.false # Height in percent of board
width: float|Bbool = Bbool.false # Width in percent of board
image_url: str|Bbool = Bbool.false
dragable: bool = False #True := Can be draged when active, False := Can be clicked when active
owner_id: int|Bbool = Bbool.false # Piece is interactable when it is "owner"'s turn or if "owner" is true
hover_text: str|Bbool = Bbool.false
@dataclass
class Player:
id: int # Maybe not necessary
colour: str # Colour in the "#rrggbb" format
class Move:
player_id: int
piece_id: int
to_x: float
to_y: float
def __init__(self, player_id, piece_id, to_x, to_y) -> None:
self.player_id = player_id
self.piece_id = piece_id
self.to_x = to_x
self.to_y = to_y
def to_json(self):
return '{"type":"move","piece_id":'+str(self.piece_id)+',"to_x":'+str(self.to_x)+',"to_y":'+str(self.to_y)+'}'
class Board:
players: list[Player]
pieces: list[Piece]
current_player: int|Bbool
moves: list[Move]
def __init__(self) -> None:
callback[0](self)
def to_json(self) -> str:
# retval = '{"players":'+self.players+'"current_player":'+str(self.current_player)+'}'
players = ''
for player in self.players:
players += json.dumps(player.__dict__) + ','
pieces = ''
for piece in self.pieces:
pieces += json.dumps(piece.__dict__) + ','
current_player = '"'+self.current_player.name+'"' if isinstance(self.current_player, Bbool) else str(self.current_player)
retval = '{"type":"board","players":['+players.rstrip(',')+'],"pieces":['+pieces.rstrip(',')+'],"current_player":'+current_player+'}'
return retval
clients = []
callback = [] # 0: on_create 1: on_move; 2: on_cmd
async def broadcast_move(move:Move):
board.moves.append(move)
for client in clients:
await client.send(move.to_json())
async def broadcast_board():
for client in clients:
await client.send(board.to_json())
async def broadcast_text(text:str):
for client in clients:
await client.send('{"type":"text","content":"'+text+'"}')
async def handler(websocket):
clients.append(websocket)
try:
await websocket.send(board.to_json())
async for message in websocket:
await on_message(message)
finally:
clients.remove(websocket)
print(len(clients))
async def startup_server(on_create_function, on_move_function, on_cmd_function):
global board
callback.append(on_create_function)
callback.append(on_move_function)
callback.append(on_cmd_function)
board = Board()
async with websockets.serve(handler, "", 8001):
await asyncio.Future() # run forever
async def on_message(message_str: str):
try:
message = json.loads(message_str)
except:
await broadcast_text("No Json found in message")
else:
if "type" in message:
if message["type"] == "set_move": #{"type":"set_move","player_id":0,"piece_id":0,"to_x":0,"to_y":12.5}
move = move_from_json(message)
await callback[1](move)
if message["type"] == "set_cmd": #{"type":"set_cmd","cmd":"restart"}
await callback[2](message["cmd"])
def move_from_json(message: dict) -> Move:
return Move(message["player_id"],message["piece_id"],message["to_x"],message["to_y"])
##### -------------------------- DEMO Implementations
async def main():
await startup_server(on_create, on_move, on_cmd)
def on_create(board:Board):
board.players = [Player(0,"#FFFFFF"), Player(1,"#000000")]
board.pieces = []
add_piece_square(board.pieces,0,0,"board/maple.jpg",-10,8,8,False)
add_piece_square(board.pieces,0,0,"cburnett/bR.svg")
add_piece_square(board.pieces,1,0,"cburnett/bN.svg")
add_piece_square(board.pieces,2,0,"cburnett/bB.svg")
add_piece_square(board.pieces,3,0,"cburnett/bQ.svg")
add_piece_square(board.pieces,4,0,"cburnett/bK.svg")
add_piece_square(board.pieces,5,0,"cburnett/bB.svg")
add_piece_square(board.pieces,6,0,"cburnett/bN.svg")
add_piece_square(board.pieces,7,0,"cburnett/bR.svg")
for i in range(8):
add_piece_square(board.pieces,i,1,"cburnett/bP.svg")
for i in range(8):
add_piece_square(board.pieces,i,6,"cburnett/wP.svg")
add_piece_square(board.pieces,0,7,"cburnett/wR.svg")
add_piece_square(board.pieces,1,7,"cburnett/wN.svg")
add_piece_square(board.pieces,2,7,"cburnett/wB.svg")
add_piece_square(board.pieces,3,7,"cburnett/wQ.svg")
add_piece_square(board.pieces,4,7,"cburnett/wK.svg")
add_piece_square(board.pieces,5,7,"cburnett/wB.svg")
add_piece_square(board.pieces,6,7,"cburnett/wN.svg")
add_piece_square(board.pieces,7,7,"cburnett/wR.svg")
board.current_player = Bbool.false
board.moves = []
def add_piece_square(pieces:list[Piece],x:float,y:float,img:str,z:int=0,size_x:float=1,size_y:float=1,dragable:bool=True):
n=8
x_gap_left = 10
x_gap_right = 10
y_gap_top = 10
y_gap_bot = 10
pieces.append(Piece(len(pieces),
x_gap_left+(100-x_gap_left-x_gap_right)*x/n,
y_gap_top+(100-y_gap_top-y_gap_bot)*y/n,
z,
(100-x_gap_left-x_gap_right)*size_x/n,
(100-y_gap_top-y_gap_bot)*size_y/n,
img,
dragable))
async def on_move(input_move:Move):
move = Move(input_move.player_id, input_move.piece_id,
round((input_move.to_x-10)/10)*10+10,
round((input_move.to_y-10)/10)*10+10)
board.pieces[move.piece_id].x_pos = move.to_x
board.pieces[move.piece_id].y_pos = move.to_y
await broadcast_move(move)
async def on_cmd(cmd:str):
if cmd == "restart":
global board
board = Board()
await broadcast_board()
await broadcast_text("Reset Complete<br><hr>")
else:
await broadcast_text("Unknown cmd")
if __name__ == "__main__":
asyncio.run(main())
#python -m websockets ws://localhost:8001/