Exemple #1
0
    def _run_play_scenarios(self, scenarios):
        ''' Runs 'play' test scenarios.

        This method verifies whether the engine outputs expected values (move)
        for the specified board arrangements.

        Args:
            scenarios: A list of test scenarios given as dictionaries:

                           {
                               'board': *numpy array of arrays with values
                                         P1, P2 or EMPTY*,
                               'player': *current player: P1 or P2*,
                               'expected_moves': *list of moves given as
                                                  tuples (x, y)*
                           }
        '''

        for scenario in scenarios:
            board = scenario['board']
            player = scenario['player']
            expected_moves = scenario['expected_moves']

            move = self._engine.next_move(board, player)

            self.assertTrue(move in expected_moves,
                             self._MESSAGE_PLAY_TEST.format(expected_moves,
                                                  move,
                                                  util.board_to_str(board)))
Exemple #2
0
    def _run_state_scenarios(self, scenarios):
        ''' Runs 'state' scenarios.

        This method verifies whether the engine correctly analyzes the current
        state of the game (board).

        Args:
            scenarios: A list of test scenarios given as dictionaries:

                           {
                               'board': numpy array of arrays with values
                                         P1, P2 or EMPTY,
                               'expected_state': either P1_WON, P2_WON or DRAW
                           }
        '''

        for scenario in scenarios:
            board = scenario['board']
            expected_state = scenario['expected_state']

            state = self._engine.get_state(board)
            msg = self._MESSAGE_STATE_TEST.format(
                             self._STATE_NAMES[expected_state],
                             self._STATE_NAMES[state],
                             util.board_to_str(board))

            self.assertEqual(state, expected_state, msg)
Exemple #3
0
    def __str__(self) -> str:
        retVal = f"Round: {self.state['round']}\n"
        retVal += f"Active Player: {self.state.activePlayer}\n"

        for p, n in self.state.cellCount().items():
            retVal += f"Living {p}: {n}\n"

        retVal += util.board_to_str(self.last_state.board, self.last_move)
        return retVal
Exemple #4
0
def main():
    ''' Entry method of the Tic-Tac-Toe application. '''
    sys.stdout.write('Cross (X) or nought (0)? [default: O]: ')
    player_choice = sys.stdin.readline().strip().upper()
    human = (player_choice == 'X') and engine.P1 or engine.P2

    game = Game()
    game.start()

    # Print the board only if human player plays the 'X'
    if human == engine.P1:
        print(util.board_to_str(game.board))

    while not game.is_over():
        if game.player == human:
            move = read_move()
        else:
            move = None

        # If the move is None, get move from AI engine
        game.play(move)

        print(util.board_to_str(game.board))

    message = ['The game is over. ']

    if game.is_draw():
        message.append('It\'s a draw!')
    else:
        if game.has_cross_won():
            message.append('Player 1 has won!')
        else:
            message.append('Player 2 has won!')

    print(''.join(message))

    return 0
Exemple #5
0
    def _run_unbeatable(self, board, move_history, player, human):
        ''' Checks every possible game permutation for computer defeat.

        Args:
            board: The game board represented by numpy 3x3 array of arrays.
            move_history: An ordered list of tuples (x, y) representing moves.
            player: Current player.
            human: Human player.
        '''

        state = self._engine.get_state(board)
        if state != IN_PROGRESS:
            computer = self._engine.get_opponent(human)
            self.assertFalse(self._has_computer_lost(state, human),
                             self._MESSAGE_UBEATABLE_TEST
                             .format(self._PLAYER_CHAR[computer],
                                     move_history,
                                     util.board_to_str(board)))
            return

        if player == human:
            for move in self._engine.get_legal_moves(board):
                new_board = board.copy()
                new_move_history = copy.copy(move_history)

                new_move_history.append(move)
                new_board[move[0], move[1]] = player

                self._run_unbeatable(new_board, new_move_history,
                                     self._engine.get_opponent(player), human)
        else:
            move = self._engine.next_move(board, player)
            move_history.append(move)
            board[move[0], move[1]] = player

            self._run_unbeatable(board, move_history,
                                 self._engine.get_opponent(player), human)