-
Notifications
You must be signed in to change notification settings - Fork 2
/
protocol.py
144 lines (112 loc) · 3.23 KB
/
protocol.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
144
import math
import re
from constants import *
MOVING_PATTERN = re.compile(r"M,(\d+\.?\d*),([A-H][1-8])")
def parseMovingPatternMatch(match):
assert match is not None
end_time, pos = float(match.group(1)), match.group(2)
return end_time, pos
def createMovingPattern(end_time, pos):
return "M," + str(end_time) + "," + pos
SLEEPING_PATTERN = re.compile(r"S,(\d+\.?\d*),([A-H][1-8])")
def parseSleepingPatternMatch(match):
assert match is not None
end_time, pos = float(match.group(1)), match.group(2)
return end_time, pos
def createSleepingPattern(end_time, pos):
return "S," + str(end_time) + "," + pos
def coord(s):
if len(s) != 2:
return None, None
letter = ord(s[0]) - ord('A')
number = int(s[1]) - 1
if number < 0 or number >= 8:
return None, None
if letter < 0 or letter >= 8:
return None, None
return letter, number
def pos(a, i):
return chr(a + ord('A')) + str(i + 1)
def distance(from_pos, to_pos):
fa, fi = coord(from_pos)
ta, ti = coord(to_pos)
return math.sqrt((fa - ta)**2 + (fi - ti)**2)
class Piece:
def __init__(self, state):
color_type, action = state.split(";")
self.color, self.type = color_type.split(",")
self.color = int(self.color)
self.type = int(self.type)
moving_match = MOVING_PATTERN.match(action)
if moving_match is None:
self.moving = False
sleeping_match = SLEEPING_PATTERN.match(action)
if sleeping_match is None:
self.pos = action
self.sleeping = False
else:
self.end_time, self.pos = parseSleepingPatternMatch(
sleeping_match)
self.sleeping = True
else:
self.end_time, self.pos = parseMovingPatternMatch(moving_match)
self.moving = True
self.sleeping = False
assert (not self.sleeping or not self.moving)
def state(self):
repr = str(self.color) + "," + str(self.type)
repr += ";"
if self.moving:
repr += createMovingPattern(self.end_time, self.pos)
elif self.sleeping:
repr += createSleepingPattern(self.end_time, self.pos)
else:
repr += self.pos
return repr
def move(self, to_pos, current_time):
seconds_to_move = distance(self.pos, to_pos) / SQUARES_PER_SECOND
self.end_time = current_time + seconds_to_move
self.pos = to_pos
self.moving = True
self.sleeping = False
a, i = coord(to_pos)
# Promotion check.
if self.type == PAWN and ((self.color == WHITE and i == 7) or
(self.color == BLACK and i == 0)):
self.type = QUEEN
def sleep(self):
assert (self.moving)
self.end_time += SLEEPING_TIME
self.moving = False
self.sleeping = True
def static(self):
self.end_time = None
self.moving = False
self.sleeping = False
def __str__(self):
s = ""
if self.color == WHITE:
s += "White "
elif self.color == BLACK:
s += "Black "
if self.type == ROOK:
s += "rook "
elif self.type == KNIGHT:
s += "knight "
elif self.type == BISHOP:
s += "bishop "
elif self.type == KING:
s += "king "
elif self.type == QUEEN:
s += "queen "
elif self.type == PAWN:
s += "pawn "
if self.moving:
s += "moving to {} until {}".format(self.pos, self.end_time)
elif self.sleeping:
s += "sleeping at {} until {}".format(self.pos, self.end_time)
else:
s += "static at {}".format(self.pos)
return s
def __repr__(self):
return "<" + str(self) + ">"