-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.py
143 lines (120 loc) · 3.52 KB
/
server.py
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
# Compile core.cpp
print("Compiling...")
import cppyy
cppyy.cppdef(open("core.cpp").read())
import cppyy.gbl as core
print("Compiled.")
import json
MINIMAX_DEPTH = 7
board = core.Board()
# Utility function to convert a move to a dict
def move_to_dict(move: core.Move) -> dict:
return {
"x": move.placedTile.x,
"y": move.placedTile.y,
"flipped": [
{"x": flipped.x, "y": flipped.y} for flipped in move.flippedTiles
]
}
# Start a new game with a fresh board
def start(json: dict):
global board
board = core.Board()
return {
"success": True,
"board": str(board.toString()),
"isBlackTurn": board.isBlackTurn
}
# Get the current board
def get_board(json: dict):
return {
"success": True,
"board": str(board.toString()),
"isBlackTurn": board.isBlackTurn,
"scoreBlack": board.evaluateScore()
}
# Register a move on the board (made by the player)
def register_move(json: dict):
x = int(json["x"])
y = int(json["y"])
move = core.Move(core.TilePosition(x, y), [])
board.setFlippedTiles(move)
# Validate move
if board.array[y][x] != " ":
return {
"success": False,
"message": "Invalid move. Field is not empty."
}
elif len(move.flippedTiles) == 0:
return {
"success": False,
"message": "Invalid move. No tiles get flipped."
}
# Register move
board.makeMove(move)
return {
"success": True,
"board": str(board.toString())
}
# Get all possible moves for the current player
def get_moves(json: dict):
return {
"success": True,
"moves": [move_to_dict(move) for move in board.getPossibleMoves()]
}
# Let the AI make a move
def ai_move(json: dict):
move = core.getBestMove(board, MINIMAX_DEPTH)
board.makeMove(move)
return {
"success": True,
"move": move_to_dict(move),
"board": str(board.toString())
}
# Map shared keys to functions
from shared import Functions
FUNCTIONS_MAP = {
Functions.START: start,
Functions.GET_BOARD: get_board,
Functions.REGISTER_MOVE: register_move,
Functions.GET_MOVES: get_moves,
Functions.AI_MOVE: ai_move
}
# Listen for connection requests from the EV3
import socket
s = None
client = None
def listen():
global s, client
# Create socket and bind to port 3000
s = socket.socket()
ip = socket.gethostbyname(socket.gethostname())
s.bind((ip, 3000))
# Listen for connection
print("Listening on", ip)
s.listen(1)
# Accept connection
client, address = s.accept()
print("Connected to", address)
# Main loop
if __name__ == "__main__":
while True:
# If no client is connected, listen for a connection
if client is None:
listen()
try:
# Receive data and parse it as JSON to a dict
data = client.recv(1024).decode("utf-8")
data = json.loads(data)
print("Received:", data)
# Find the function to execute
requested_function = FUNCTIONS_MAP.get(data["function"])
if requested_function is not None:
# Execute the function and send the response back to the EV3
response = requested_function(data["parameters"])
client.send(bytes(json.dumps(response), "utf-8"))
else:
print("Unknown function:", data)
except:
client = None
print("Connection lost.")