def move(self, board): empty_cells = rules.empty_cells(board) # Check if any of the empty cells represents a winning move for cell in empty_cells: cell = tuple(cell) new_board = board.copy() new_board[cell] = self.side if rules.winning_move(new_board): return cell # Check if any of the empty cells represents a winning move for the # other player, if so block it for cell in empty_cells: cell = tuple(cell) new_board = board.copy() new_board[cell] = -self.side if rules.winning_move(new_board): if self.logger: self.logger.debug("Blocked {0}".format(cell)) return cell else: # Otherwise pick a random cell return tuple(empty_cells[random.randint(0, len(empty_cells) - 1)])
def move_value(self, move, board): """ Checks whether the specified move would result in a win and returns a value accordingly. States that have not been seen before are given a default value. Note that no values are stored here. TODO: remove the win check and just get the state, remove this method? Args: move ((int, int)): tuple with the coordinates of the new move (x, y) board (numpy.ndarray): two dimensional array representing the board Returns: float: the value of the state after the move is applied """ move = tuple(move) board = board.copy() board[move] = self.side # Check if this is a new state with no recorded value if not self.value(board): # Check if this is a winning move for the player if rules.winning_move(board, move): # Return maximum value to the state return self.MAX_VALUE else: return self.DEFAULT_VALUE return self.value(board)
def move_value(self, move, board): """ Checks whether the specified move would result in a win and returns a value accordingly. States that have not been seen before are given a default value. Note that no values are stored here. TODO: remove the win check and just get the state, remove this method? Args: move ((int, int)): tuple with the coordinates of the new move (x, y) board (numpy.ndarray): two dimensional array representing the board Returns: float: the value of the state after the move is applied """ move = tuple(move) board = board.copy() board[move] = self.side # Check if this is a new state with no recorded value if not self.value(board): # Check if this is a winning move for the player if rules.winning_move(board): # Return maximum value to the state return self.MAX_VALUE else: return self.DEFAULT_VALUE return self.value(board)
def move(self, board): empty_cells = rules.empty_cells(board) # Check if any of the empty cells represents a winning move for cell in empty_cells: cell = tuple(cell) new_board = board.copy() new_board[cell] = self.side if rules.winning_move(new_board, cell): return cell else: # Otherwise pick a random cell return tuple(empty_cells[random.randint(0, len(empty_cells) - 1)])
def move(self, board): empty_cells = rules.empty_cells(board) # Check if any of the empty cells represents a winning move for cell in empty_cells: cell = tuple(cell) new_board = board.copy() new_board[cell] = self.side if rules.winning_move(new_board): return cell else: # Otherwise pick a random cell return tuple(empty_cells[random.randint(0, len(empty_cells) - 1)])
def move(self, board): empty_cells = rules.empty_cells(board) # Check if any of the empty cells represents a winning move for cell in empty_cells: cell = tuple(cell) new_board = board.copy() new_board[cell] = self.side if rules.winning_move(new_board, cell): return cell # Check if any of the empty cells represents a winning move for the # other player, if so block it for cell in empty_cells: cell = tuple(cell) new_board = board.copy() new_board[cell] = -self.side if rules.winning_move(new_board, cell): if self.logger: self.logger.debug("Blocked {0}".format(cell)) return cell else: # Otherwise pick a random cell return tuple(empty_cells[random.randint(0, len(empty_cells) - 1)])
def play(self): """ Plays the game, alternating turns between the players. Moves are requested sequentially from each player in turn until there is a winner. The moves are checked for validity. Returns: int: the side of the winning player, or None if there was a draw """ if self.shuffle: random.shuffle(self.players()) player_loop = cycle(self.players()) for player in player_loop: # if self.logger: # self.logger.debug(rules.board_str(self.board)) # Get the coordinates of the player's move move = player.move(self.board) # Make the move if it is valid if rules.valid_move(self.board, move): self.board[move] = player.side else: if self.logger: self.logger.fatal("Invalid move") raise ValueError("Not a valid move: {0}".format(move)) # Check for a win or draw if rules.winning_move(self.board, move): if self.logger: self.logger.info("{2}\nGame over: {0} win ({1})".format( rules.side_name(player.side), type(player).__name__, rules.board_str(self.board))) # Return winning player return player.side elif rules.draw(self.board): if self.logger: self.logger.info("{0}\nGame over: Draw".format( rules.board_str(self.board))) # Return None for draw return None