-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBoard.py
152 lines (129 loc) · 5.19 KB
/
Board.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
145
146
147
148
149
150
151
152
class Board():
# list of all 8 directions on the board, as (x,y) offsets
__directions = [(1,1),(1,0),(1,-1),(0,-1),(-1,-1),(-1,0),(-1,1),(0,1)]
def __init__(self, n):
"Set up initial board configuration."
self.n = n
# Create the empty board array.
self.pieces = [None]*self.n
for i in range(self.n):
self.pieces[i] = [0]*self.n
# Set up the initial 4 pieces.
self.pieces[int(self.n/2)-1][int(self.n/2)] = 1
self.pieces[int(self.n/2)][int(self.n/2)-1] = 1
self.pieces[int(self.n/2)-1][int(self.n/2)-1] = -1;
self.pieces[int(self.n/2)][int(self.n/2)] = -1;
# add [][] indexer syntax to the Board
def __getitem__(self, index):
return self.pieces[index]
def countDiff(self, color):
"""Counts the # pieces of the given color
(1 for white, -1 for black, 0 for empty spaces)"""
count = 0
for y in range(self.n):
for x in range(self.n):
if self[x][y]==color:
count += 1
if self[x][y]==-color:
count -= 1
return count
def get_legal_moves(self, color):
"""Returns all the legal moves for the given color.
(1 for white, -1 for black
"""
moves = set() # stores the legal moves.
# Get all the squares with pieces of the given color.
for y in range(self.n):
for x in range(self.n):
if self[x][y]==color:
newmoves = self.get_moves_for_square((x,y))
moves.update(newmoves)
return list(moves)
def has_legal_moves(self, color):
for y in range(self.n):
for x in range(self.n):
if self[x][y]==color:
newmoves = self.get_moves_for_square((x,y))
if len(newmoves)>0:
return True
return False
def get_moves_for_square(self, square):
"""Returns all the legal moves that use the given square as a base.
That is, if the given square is (3,4) and it contains a black piece,
and (3,5) and (3,6) contain white pieces, and (3,7) is empty, one
of the returned moves is (3,7) because everything from there to (3,4)
is flipped.
"""
(x,y) = square
# determine the color of the piece.
color = self[x][y]
# skip empty source squares.
if color==0:
return None
# search all possible directions.
moves = []
for direction in self.__directions:
move = self._discover_move(square, direction)
if move:
# print(square,move,direction)
moves.append(move)
# return the generated move list
return moves
def execute_move(self, move, color):
"""Perform the given move on the board; flips pieces as necessary.
color gives the color pf the piece to play (1=white,-1=black)
"""
#Much like move generation, start at the new piece's square and
#follow it on all 8 directions to look for a piece allowing flipping.
# Add the piece to the empty square.
# print(move)
flips = [flip for direction in self.__directions
for flip in self._get_flips(move, direction, color)]
assert len(list(flips))>0
for x, y in flips:
#print(self[x][y],color)
self[x][y] = color
def _discover_move(self, origin, direction):
""" Returns the endpoint for a legal move, starting at the given origin,
moving by the given increment."""
x, y = origin
color = self[x][y]
flips = []
for x, y in Board._increment_move(origin, direction, self.n):
if self[x][y] == 0:
if flips:
# print("Found", x,y)
return (x, y)
else:
return None
elif self[x][y] == color:
return None
elif self[x][y] == -color:
# print("Flip",x,y)
flips.append((x, y))
def _get_flips(self, origin, direction, color):
""" Gets the list of flips for a vertex and direction to use with the
execute_move function """
#initialize variables
flips = [origin]
for x, y in Board._increment_move(origin, direction, self.n):
#print(x,y)
if self[x][y] == 0:
return []
if self[x][y] == -color:
flips.append((x, y))
elif self[x][y] == color and len(flips) > 0:
#print(flips)
return flips
return []
@staticmethod
def _increment_move(move, direction, n):
# print(move)
""" Generator expression for incrementing moves """
move = list(map(sum, zip(move, direction)))
#move = (move[0]+direction[0], move[1]+direction[1])
while all(map(lambda x: 0 <= x < n, move)):
#while 0<=move[0] and move[0]<n and 0<=move[1] and move[1]<n:
yield move
move=list(map(sum,zip(move,direction)))
#move = (move[0]+direction[0],move[1]+direction[1])