rearrange the sequence of functions of Go and GoEnv before merging

This commit is contained in:
Dong Yan 2017-12-20 00:16:24 +08:00
parent 232204d797
commit 2a9d949510
2 changed files with 91 additions and 104 deletions

View File

@ -17,70 +17,6 @@ class Go:
def __init__(self, **kwargs): def __init__(self, **kwargs):
self.game = kwargs['game'] self.game = kwargs['game']
def _bfs(self, vertex, color, block, status):
block.append(vertex)
status[self.game._flatten(vertex)] = True
nei = self._neighbor(vertex)
for n in nei:
if not status[self.game._flatten(n)]:
if self.game.board[self.game._flatten(n)] == color:
self._bfs(n, color, block, status)
def _find_block(self, vertex):
block = []
status = [False] * (self.game.size ** 2)
color = self.game.board[self.game._flatten(vertex)]
self._bfs(vertex, color, block, status)
for b in block:
for n in self._neighbor(b):
if self.game.board[self.game._flatten(n)] == utils.EMPTY:
return False, block
return True, block
def _find_boarder(self, vertex):
block = []
status = [False] * (self.game.size ** 2)
self._bfs(vertex, utils.EMPTY, block, status)
border = []
for b in block:
for n in self._neighbor(b):
if not (n in block):
border.append(n)
return border
def _is_qi(self, color, vertex):
nei = self._neighbor(vertex)
for n in nei:
if self.game.board[self.game._flatten(n)] == utils.EMPTY:
return True
self.game.board[self.game._flatten(vertex)] = color
for n in nei:
if self.game.board[self.game._flatten(n)] == utils.another_color(color):
can_kill, block = self._find_block(n)
if can_kill:
self.game.board[self.game._flatten(vertex)] = utils.EMPTY
return True
### can not suicide
can_kill, block = self._find_block(vertex)
if can_kill:
self.game.board[self.game._flatten(vertex)] = utils.EMPTY
return False
self.game.board[self.game._flatten(vertex)] = utils.EMPTY
return True
def _check_global_isomorphous(self, history_boards, current_board, color, vertex):
repeat = False
next_board = copy.copy(current_board)
next_board[self.game._flatten(vertex)] = color
self._process_board(next_board, color, vertex)
if next_board in history_boards:
repeat = True
return repeat
def _in_board(self, vertex): def _in_board(self, vertex):
x, y = vertex x, y = vertex
if x < 1 or x > self.game.size: return False if x < 1 or x > self.game.size: return False
@ -97,15 +33,57 @@ class Go:
nei.append((_x, _y)) nei.append((_x, _y))
return nei return nei
def _find_group(self, current_board, vertex):
color = current_board[self.game._flatten(vertex)]
# print ("color : ", color)
chain = set()
frontier = [vertex]
has_liberty = False
while frontier:
current = frontier.pop()
# print ("current : ", current)
chain.add(current)
for n in self._neighbor(current):
if current_board[self.game._flatten(n)] == color and not n in chain:
frontier.append(n)
if current_board[self.game._flatten(n)] == utils.EMPTY:
has_liberty = True
return has_liberty, chain
def _is_suicide(self, current_board, color, vertex):
current_board[self.game._flatten(vertex)] = color # assume that we already take this move
suicide = False
has_liberty, group = self._find_group(current_board, vertex)
if not has_liberty:
suicide = True # no liberty, suicide
for n in self._neighbor(vertex):
if current_board[self.game._flatten(n)] == utils.another_color(color):
opponent_liberty, group = self._find_group(current_board, n)
if not opponent_liberty:
suicide = False # this move is able to take opponent's stone, not suicide
current_board[self.game._flatten(vertex)] = utils.EMPTY # undo this move
return suicide
def _process_board(self, current_board, color, vertex): def _process_board(self, current_board, color, vertex):
nei = self._neighbor(vertex) nei = self._neighbor(vertex)
for n in nei: for n in nei:
if current_board[self.game._flatten(n)] == utils.another_color(color): if current_board[self.game._flatten(n)] == utils.another_color(color):
can_kill, block = self._find_block(n) has_liberty, group = self._find_group(current_board, n)
if can_kill: if not has_liberty:
for b in block: for b in group:
current_board[self.game._flatten(b)] = utils.EMPTY current_board[self.game._flatten(b)] = utils.EMPTY
def _check_global_isomorphous(self, history_boards, current_board, color, vertex):
repeat = False
next_board = copy.copy(current_board)
next_board[self.game._flatten(vertex)] = color
self._process_board(next_board, color, vertex)
if next_board in history_boards:
repeat = True
return repeat
def is_valid(self, history_boards, current_board, color, vertex): def is_valid(self, history_boards, current_board, color, vertex):
### in board ### in board
if not self._in_board(vertex): if not self._in_board(vertex):
@ -115,8 +93,8 @@ class Go:
if not current_board[self.game._flatten(vertex)] == utils.EMPTY: if not current_board[self.game._flatten(vertex)] == utils.EMPTY:
return False return False
### check if it is qi ### check if it is suicide
if not self._is_qi(color, vertex): if self._is_suicide(current_board, color, vertex):
return False return False
if self._check_global_isomorphous(history_boards, current_board, color, vertex): if self._check_global_isomorphous(history_boards, current_board, color, vertex):
@ -137,6 +115,15 @@ class Go:
idx = [i for i,x in enumerate(self.game.board) if x == utils.EMPTY ][0] idx = [i for i,x in enumerate(self.game.board) if x == utils.EMPTY ][0]
return self.game._deflatten(idx) return self.game._deflatten(idx)
def _find_boarder(self, vertex):
_, group = self._find_group(self.game.board, vertex)
border = []
for b in group:
for n in self._neighbor(b):
if not (n in group):
border.append(n)
return border
def _add_nearby_stones(self, neighbor_vertex_set, start_vertex_x, start_vertex_y, x_diff, y_diff, num_step): def _add_nearby_stones(self, neighbor_vertex_set, start_vertex_x, start_vertex_y, x_diff, y_diff, num_step):
''' '''
add the nearby stones around the input vertex add the nearby stones around the input vertex

View File

@ -19,6 +19,32 @@ class GoEnv:
self.simulate_board = [utils.EMPTY] * (self.game.size ** 2) self.simulate_board = [utils.EMPTY] * (self.game.size ** 2)
self.simulate_latest_boards = deque(maxlen=8) self.simulate_latest_boards = deque(maxlen=8)
def _in_board(self, vertex):
x, y = vertex
if x < 1 or x > self.game.size: return False
if y < 1 or y > self.game.size: return False
return True
def _neighbor(self, vertex):
x, y = vertex
nei = []
for d in NEIGHBOR_OFFSET:
_x = x + d[0]
_y = y + d[1]
if self._in_board((_x, _y)):
nei.append((_x, _y))
return nei
def _corner(self, vertex):
x, y = vertex
corner = []
for d in CORNER_OFFSET:
_x = x + d[0]
_y = y + d[1]
if self._in_board((_x, _y)):
corner.append((_x, _y))
return corner
def _find_group(self, current_board, vertex): def _find_group(self, current_board, vertex):
color = current_board[self.game._flatten(vertex)] color = current_board[self.game._flatten(vertex)]
# print ("color : ", color) # print ("color : ", color)
@ -52,41 +78,6 @@ class GoEnv:
current_board[self.game._flatten(vertex)] = utils.EMPTY # undo this move current_board[self.game._flatten(vertex)] = utils.EMPTY # undo this move
return suicide return suicide
def _check_global_isomorphous(self, history_boards, current_board, color, vertex):
repeat = False
next_board = copy.copy(current_board)
next_board[self.game._flatten(vertex)] = color
self._process_board(next_board, color, vertex)
if next_board in history_boards:
repeat = True
return repeat
def _in_board(self, vertex):
x, y = vertex
if x < 1 or x > self.game.size: return False
if y < 1 or y > self.game.size: return False
return True
def _neighbor(self, vertex):
x, y = vertex
nei = []
for d in NEIGHBOR_OFFSET:
_x = x + d[0]
_y = y + d[1]
if self._in_board((_x, _y)):
nei.append((_x, _y))
return nei
def _corner(self, vertex):
x, y = vertex
corner = []
for d in CORNER_OFFSET:
_x = x + d[0]
_y = y + d[1]
if self._in_board((_x, _y)):
corner.append((_x, _y))
return corner
def _process_board(self, current_board, color, vertex): def _process_board(self, current_board, color, vertex):
nei = self._neighbor(vertex) nei = self._neighbor(vertex)
for n in nei: for n in nei:
@ -96,6 +87,15 @@ class GoEnv:
for b in group: for b in group:
current_board[self.game._flatten(b)] = utils.EMPTY current_board[self.game._flatten(b)] = utils.EMPTY
def _check_global_isomorphous(self, history_boards, current_board, color, vertex):
repeat = False
next_board = copy.copy(current_board)
next_board[self.game._flatten(vertex)] = color
self._process_board(next_board, color, vertex)
if next_board in history_boards:
repeat = True
return repeat
def _is_eye(self, current_board, color, vertex): def _is_eye(self, current_board, color, vertex):
nei = self._neighbor(vertex) nei = self._neighbor(vertex)
cor = self._corner(vertex) cor = self._corner(vertex)