예제 #1
0
 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)
예제 #2
0
    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
예제 #3
0
 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)
예제 #4
0
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
예제 #5
0
 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)
예제 #6
0
    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)
예제 #7
0
 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)
예제 #8
0
 def test_init_move(self):
     # Test setting first move
     game = TicTacToe(first_move=O)
     assert_equal(game.turn, O)
예제 #9
0
 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)
예제 #10
0
    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)
예제 #11
0
 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)
예제 #12
0
    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)
예제 #13
0
 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)
예제 #14
0
 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)
예제 #15
0
            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()