def test_is_winning_line(self): game = TicTacToe() assert_equal(game._is_winning_line([X, X, X]), True) assert_equal(game._is_winning_line([O, O, O]), True) assert_equal(game._is_winning_line([O, X, O]), False) assert_equal(game._is_winning_line([E, E, E]), False) assert_equal(game._is_winning_line([X, E, X]), False)
def _get_best_move(self, game, depth): """ Min-max algorithm using TicTacToeGame :param game: A TicTacToeGame object. :param depth: The maximum number of actions to look ahead. :return: The score and row/col index of the best move found. """ if game.state != CONTINUE or depth > self.max_depth: # Base case: game is over score = 0 if game.winner() == self.team: score = 10 - depth elif game.winner() == -self.team: score = depth - 10 return score, -1, -1 scores = [] moves = game.available_moves() for row, col in moves: board = copy.deepcopy(game.board) new_game = TicTacToe(board, game.turn) new_game.move(row, col) score, _, _ = self._get_best_move(new_game, depth + 1) scores.append(score) if game.turn == self.team: score = max(scores) else: score = min(scores) # Randomly pick from the moves with the highest/lowest score indices = np.argwhere(np.array(scores) == score).reshape([-1]) index = np.random.choice(indices) row, col = moves[index] return score, row, col
def test_init_end_game_state(self): # Test setting a winning state for X board = [[X, O, E], [X, O, E], [X, E, E]] game = TicTacToe(board=board) assert_equal(game.status, X_WIN) # Test setting a winning state for O board = [[O, X, X], [X, O, X], [E, O, O]] game = TicTacToe(board=board) assert_equal(game.status, O_WIN) # Test setting a cat's game board = [[X, O, X], [O, O, X], [X, X, O]] game = TicTacToe(board=board) assert_equal(game.status, CATS_GAME)
def play_game(player1, player2): """ Plays a game of TicTacToe between player1 and player2. :param player1: Player object :param player2: Player object :return: Integer. The status of the completed game. See taqtoe.constants for possible status codes. """ # Select and announce first player game = TicTacToe(first_move=np.random.choice([X, O])) first = 'X' if game.turn == X else 'O' print('\n{} is up first!'.format(first)) # Game loop while game.status == CONTINUE: player = player1 if game.turn == player1.team else player2 player.move(game) game.print_board() # Game over! Print out info on winner. print_winner(game, player1, player2) return game.status
def test_bad_move(self): game = TicTacToe() # Place X game.move(0, 0) # Check to make sure that O is the current player assert_equal(game.turn, O) # Attempt to place a piece in the same space as X assert_raises(BadMoveException, game.move, 0, 0) # Check that O is still the current player assert_equal(game.turn, O) # Try to place a piece outside of the game dimensions assert_raises(BadMoveException, game.move, 1, 3) # Check that O is still the current player assert_equal(game.turn, O) # Place a good piece game.move(1, 1) # Check that the final game state is as expected assert_equal(game.turn, X) expected_board = [[X, E, E], [E, O, E], [E, E, E]] assert_equal(game.board, expected_board)
def test_move_to_end_game(self): # Test X win board = [[X, E, O], [O, X, X], [O, E, E]] game = TicTacToe(board=board) assert_equal(game.status, CONTINUE) game.move(2, 2) assert_equal(game.status, X_WIN) # Test O win board = [[X, X, O], [O, E, X], [O, E, X]] game = TicTacToe(board=board, first_move=O) assert_equal(game.status, CONTINUE) game.move(1, 1) assert_equal(game.status, O_WIN) # Test cat's game board = [[X, O, O], [O, X, X], [E, X, O]] game = TicTacToe(board=board) assert_equal(game.status, CONTINUE) game.move(2, 0) assert_equal(game.status, CATS_GAME)
def test_move(self): game = TicTacToe() game.move(0, 2) expected_board = [[E, E, X], [E, E, E], [E, E, E]] assert_equal(game.board, expected_board) assert_equal(game.turn, O)
def test_init_move(self): # Test setting first move game = TicTacToe(first_move=O) assert_equal(game.turn, O)
def test_init_board(self): # Test pre-set board state board = [[X, E, E], [E, O, E], [X, X, O]] game = TicTacToe(board=board) assert_equal(game.board, board)
def test_full_game(self): game = TicTacToe() board = [[E, E, E], [E, E, E], [E, E, E]] assert_equal(game.board, board) assert_equal(game.status, CONTINUE) game.move(1, 1) board = [[E, E, E], [E, X, E], [E, E, E]] assert_equal(game.board, board) assert_equal(game.status, CONTINUE) game.move(2, 1) board = [[E, E, E], [E, X, E], [E, O, E]] assert_equal(game.board, board) assert_equal(game.status, CONTINUE) game.move(0, 0) board = [[X, E, E], [E, X, E], [E, O, E]] assert_equal(game.board, board) assert_equal(game.status, CONTINUE) game.move(2, 2) board = [[X, E, E], [E, X, E], [E, O, O]] assert_equal(game.board, board) assert_equal(game.status, CONTINUE) game.move(2, 0) board = [[X, E, E], [E, X, E], [X, O, O]] assert_equal(game.board, board) assert_equal(game.status, CONTINUE) game.move(1, 0) board = [[X, E, E], [O, X, E], [X, O, O]] assert_equal(game.board, board) assert_equal(game.status, CONTINUE) game.move(0, 2) board = [[X, E, X], [O, X, E], [X, O, O]] assert_equal(game.board, board) assert_equal(game.status, X_WIN)
def test_init(self): # Test basic initialization game = TicTacToe() assert_equal(game.board, [[E, E, E], [E, E, E], [E, E, E]]) assert_equal(game.turn, X) assert_equal(game.status, CONTINUE)
def test_find_winner(self): for S, win_state in [(X, X_WIN), (O, O_WIN)]: # Check horizontal win states board = [[S, S, S], [E, E, E], [E, E, E]] game = TicTacToe(board=board) assert_equal(game._find_winner(), S) assert_equal(game.status, win_state) board = [[E, E, E], [S, S, S], [E, E, E]] game = TicTacToe(board=board) assert_equal(game._find_winner(), S) assert_equal(game.status, win_state) board = [[E, E, E], [E, E, E], [S, S, S]] game = TicTacToe(board=board) assert_equal(game._find_winner(), S) assert_equal(game.status, win_state) # Check vertical win states board = [[S, E, E], [S, E, E], [S, E, E]] game = TicTacToe(board=board) assert_equal(game._find_winner(), S) assert_equal(game.status, win_state) board = [[E, S, E], [E, S, E], [E, S, E]] game = TicTacToe(board=board) assert_equal(game._find_winner(), S) assert_equal(game.status, win_state) board = [[E, E, S], [E, E, S], [E, E, S]] game = TicTacToe(board=board) assert_equal(game._find_winner(), S) assert_equal(game.status, win_state) # Check diagonal win states board = [[S, E, E], [E, S, E], [E, E, S]] game = TicTacToe(board=board) assert_equal(game._find_winner(), S) assert_equal(game.status, win_state) board = [[E, E, S], [E, S, E], [S, E, E]] game = TicTacToe(board=board) assert_equal(game._find_winner(), S) assert_equal(game.status, win_state)
def test_available_moves(self): board = [[X, O, X], [E, X, O], [O, X, E]] game = TicTacToe(board=board) expected_available = [(1, 0), (2, 2)] assert_equal(game.available_moves(), expected_available)
def test_is_available(self): game = TicTacToe() assert_equal(game.is_available(1, 1), True) game.move(1, 1) assert_equal(game.is_available(1, 1), False)
score, _, _ = self._get_best_move(new_game, depth + 1) scores.append(score) if game.turn == self.team: score = max(scores) else: score = min(scores) # Randomly pick from the moves with the highest/lowest score indices = np.argwhere(np.array(scores) == score).reshape([-1]) index = np.random.choice(indices) row, col = moves[index] return score, row, col if __name__ == '__main__': # Setup a simple 2-player game from taqtoe.constants import X, O from taqtoe.player import HumanPlayer game = TicTacToe() team1 = np.random.choice([X, O]) team2 = -team1 player1 = HumanPlayer(team1, 'Sam') player2 = MinMaxPlayer(team2, 3, 'Hal') while game.status == CONTINUE: game.print_board() player = player1 if game.turn == team1 else player2 print('{}\'s turn.'.format(player.name)) player.move(game) print('Game over!') game.print_board()