def is_point_an_eye(board, point, color): #if stone is at point, then point cant be an eye if board.get(point) is not None: return False #all adjacent stones must contain friendly stones for neighbor in point.neighbors(): if board.is_on_grid(neighbor): neighbor_color = board.get(neighbor) if neighbor != color: return False #must control 3 out of 4 corners if the point is in middle of board, #while on the edge of the board must control 4 corners friendly_corners = 0 off_board_corners = 0 corners = [ Point(point.row - 1, point.col - 1), Point(point.row - 1, point.col + 1), Point(point.row + 1, point.col - 1), Point(point.row + 1, point.col + 1), ] for corner in corners: if board.is_on_grid(corner): corner_color = board.get(corner) if corner_color == color: friendly_corners += 1 else: off_board_corners += 1 if off_board_corners > 0: #point is on edge or corner return off_board_corners + friendly_cornes == 4 #point is in middle return friendly_corners >= 3
def select_move(self, game_state): """Choose a random valid move that preserves our own eyes.""" candidates = [] for r in range(1, game_state.board.num_rows + 1): for c in range(1, game_state.board.num_cols + 1): candidate = Point(row=r, col=c) if game_state.is_valid_move(Move.play(candidate)) and \ not is_point_an_eye(game_state.board, candidate, game_state.next_player): candidates.append(candidate) if not candidates: return Move.pass_turn() print(Move.play(random.choice(candidates))) # end::random_bot[]
def legal_moves(self): "using this bypasses the need of is_valid_move" moves = [] for row in range(1, self.board.num_rows + 1): for col in range(1, self.board.num_cols + 1): move = Move.play(Point(row, col)) if self.is_valid_move(move): moves.append(move) moves.append(Move.pass_turn()) moves.append(Move.resign()) return moves
def select_move(self, game_state): """Selects random value that preserves eyes""" candidates = [] for r in range(1, game_state.board.num_rows + 1): for c in range(1, game_state.board.num_cols + 1): candidate = Point( row=r, col=c) #added first parameter to Move.play below to be "1" if game_state.is_valid_move(Move.play(candidate)) and \ not is_point_an_eye(game_state.board, \ candidate, \ game_state.next_player): candidates.append(candidate) if not candidates: return Move.pass_turn() return Move.play(random.choice(candidates))
def evaluate_territory(board): status = {} for r in range(1, board.num_cols + 1): for c in range(1, board.num_cols+ 1): p = Point(row=r, col=c) if p in status: continue stone = board.get(p) if stone is not None: status[p] = board.get(p) else: group, neighbors = _collect_region(p, board) if len(neighbors) == 1: neighbor_stone = neighbors.pop() stone_str = 'b' if neighbor_stone == Player.black else 'w' fill_with = 'territory_' + stone_str else: fill_with = 'dame' for pos in group: status[pos] = fill_with return Territory(status)
def _collect_region(start_pos, board, visited=None): if visited is None: visited = {} if start_pos in visited: return [], set() all_points = [start_pos] all_borders = set() visited[start_pos] = True here = board.get(start_pos) deltas = [(-1,0), (1,0), (0,-1), (0,1)] for delta_r, delta_c in deltas: next_p = Point(row=start_pos.row + delta_r, col=start_pos.col + delta_c) if not board.is_on_grid(next_p): continue neighbor = board.get(next_p) if neighbor == here: points, borders = _collect_region(next_p, board, visited) all_points += points all_borders |= borders else: all_borders.add(neighbor) return all_points, all_borders
def is_point_an_eye(board, point, color): if board.get(point) is not None: # <1> return False for neighbor in point.neighbors(): # <2> if board.is_on_grid(neighbor): neighbor_color = board.get(neighbor) if neighbor_color != color: return False friendly_corners = 0 # <3> off_board_corners = 0 corners = [ Point(point.row - 1, point.col - 1), Point(point.row - 1, point.col + 1), Point(point.row + 1, point.col - 1), Point(point.row + 1, point.col + 1), ] for corner in corners: if board.is_on_grid(corner): corner_color = board.get(corner) if corner_color == color: friendly_corners += 1 else: off_board_corners += 1 if off_board_corners > 0: return off_board_corners + friendly_corners == 4 # <4> return friendly_corners >= 3 # <5> # <1> An eye is an empty point. # <2> All adjacent points must contain friendly stones. # <3> We must control 3 out of 4 corners if the point is in the middle of the board; on the edge we must control all corners. # <4> Point is on the edge or corner. # <5> Point is in the middle. # end::eye[]