Example #1
0
    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)])
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
    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)])
Example #5
0
    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)])
Example #6
0
    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)])
Example #7
0
    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