-
Notifications
You must be signed in to change notification settings - Fork 0
/
GoBoard.py
129 lines (109 loc) · 4.58 KB
/
GoBoard.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
from GoPoint import Point
from GoMove import Move
EMPTY, BLACK, WHITE = range(0, 3)
class Board:
def __init__(self, size, board_arr):
self.board_size = size
self.board_grid = board_arr
def __eq__(self, other):
for i in range(self.board_size):
for j in range(self.board_size):
if self.board_grid[i][j] != other.board_grid[i][j]:
return False
return True
def point_on_grid(self, point: Point):
return 0 <= point.x < self.board_size and 0 <= point.y < self.board_size
def coord_is_empty(self, point: Point):
return self.board_grid[point.x][point.y] == EMPTY
def get_point_neighbors(self, point):
return list(filter(self.point_on_grid, point.get_neighbors()))
def get_neighbor_connections(self, point):
neighbors = self.get_point_neighbors(point)
connected_stones = []
for neighbor_stone in neighbors:
if self.board_grid[neighbor_stone.x][neighbor_stone.y] == self.board_grid[point.x][point.y]:
connected_stones.append(neighbor_stone)
return connected_stones
def get_connection_chain(self, point):
stack_stones = [point]
connection_chain = []
while stack_stones:
curr_point = stack_stones.pop()
connection_chain.append(curr_point)
neighbor_connections = self.get_neighbor_connections(curr_point)
for stone in neighbor_connections:
if stone not in stack_stones and stone not in connection_chain:
stack_stones.append(stone)
return connection_chain
def has_liberty(self, point):
connection_chain = self.get_connection_chain(point)
for stone in connection_chain:
neighbors = self.get_point_neighbors(stone)
for neighbor_point in neighbors:
if self.board_grid[neighbor_point.x][neighbor_point.y] == 0:
return True
return False
def get_liberty(self, move: Move):
if move.is_pass:
return 4
point = move.point
liberty = 0
connection_chain = self.get_connection_chain(point)
for stone in connection_chain:
neighbors = self.get_point_neighbors(stone)
for neighbor_point in neighbors:
if self.board_grid[neighbor_point.x][neighbor_point.y] == EMPTY:
liberty += 1
return liberty
def find_adj_dead(self, point):
dead_stones = set()
curr_player = self.board_grid[point.x][point.y]
neighbor_points = self.get_point_neighbors(point)
for point in neighbor_points:
if self.board_grid[point.x][point.y] == 3 - curr_player and not self.has_liberty(point):
connected_chain = self.get_connection_chain(point)
for stone in connected_chain:
dead_stones.add(stone)
return dead_stones
def remove_stones(self, set_stones):
for stone in set_stones:
self.board_grid[stone.x][stone.y] = EMPTY
def get_point_color(self, point):
return self.board_grid[point.x][point.y]
def place_stone(self, move: Move, player):
point = move.point
self.board_grid[point.x][point.y] = player
dead_stones = self.find_adj_dead(point)
self.remove_stones(dead_stones)
def valid_move_check(self, move: Move):
point = move.point
return self.point_on_grid(point) and self.coord_is_empty(point)
def fills_own_eye(self, move: Move):
if move.is_pass:
return False
point = move.point
player = self.board_grid[point.x][point.y]
for neighbor in point.get_neighbors():
if self.point_on_grid(neighbor):
if self.get_point_color(neighbor) != player:
return False
diagonal_stones = point.get_diagonals()
opponent_diagonals = 0
for stone in diagonal_stones:
if not self.point_on_grid(stone):
opponent_diagonals += 1
break
for stone in diagonal_stones:
if self.point_on_grid(stone):
if self.get_point_color(stone) == 3 - player:
opponent_diagonals += 1
if opponent_diagonals > 1:
return False
return True
# def suicidal_move(self, move, player):
# point = move.point
# self.place_stone(point, player)
# return not self.has_liberty(point)
# def violate_ko(self, other_board):
# if self.board_grid == other_board:
# return True