Ejemplo n.º 1
0
    def _get_input(self, board: Board) -> np.array:
        """Generate the input to the neural network from a board.

        Parameters
        ----------
        board : Board

        Returns
        -------
        np.array
            shape is (32, 1).

        """
        inp = np.zeros((32, 1))
        id = 0
        for i in range(8):
            for j in range(i & 1, 8, 2):
                disk = board.get_disk_at((i, j))
                if disk is None:
                    inp[id] = 0
                else:
                    val = 1
                    if disk.is_king():
                        val += 1
                    if disk.get_colour() == 'black':
                        val = -val
                    inp[id] = val
                id += 1
        return inp
Ejemplo n.º 2
0
    def _terminal_state(self, board: Board, turn: int,
                        draw_counter: int) -> str:
        """Get the status of a terminal state, or None if it's not terminal.

        Parameters
        ----------
        board : Board
            board state.
        turn : int
            turn's number.
        draw_counter : int
            counter of non-attack moves.

        Returns
        -------
        str
            'win', 'lose', 'draw', or None if it's not a terminal state.

        """
        if turn % 2 == 1:
            colour = 'white'
        else:
            colour = 'black'
        status = board.get_status(colour, draw_counter)
        return status
Ejemplo n.º 3
0
    def _max(self, board: Board, depth: int, turn: int, draw_counter: int,
             alpha: float, beta: float) -> float:
        self._tot_num += 1  # increase the number of explored nodes.

        # apply dynamic path feature if it's set to true.
        # please note that this feature is under tests.
        if self._dynamic_depth is True:
            if self._tot_num > MiniMaxAlphaBetaSystem.maximum_nodes_number:
                return np.sum(
                    self._pred_system.predict([board], turn, draw_counter))

        # get the status if current node.
        status = self._terminal_state(board, turn, draw_counter)
        if status is not None:
            # lose for black is win for white and vice versa.
            sign = 1 if turn % 2 == 1 else -1
            if status == 'win':
                return 100 * sign
            elif status == 'lose':
                return -100 * sign
            else:
                return 0

        # if we reach the maximum depth then stop and return
        # a prediction of the current board state.
        if depth >= self._depth:
            return np.sum(
                self._pred_system.predict([board], turn, draw_counter))

        # generate the next boards by applying the valid moves.
        boards = []
        Moves.get_all_next_boards(board, 'white', boards)

        current_max = -1e7
        size_before = board.get_number_of_disks(None)
        for b in boards:
            next_draw_counter = draw_counter
            size_after = b.get_number_of_disks(None)
            next_draw_counter = update_draw_counter(next_draw_counter,
                                                    size_before, size_after)
            current_max = max(
                current_max,
                self._min(b, depth + 1, turn + 1, next_draw_counter, alpha,
                          beta))
            if current_max >= beta:
                return current_max
            alpha = max(alpha, current_max)
        return current_max
Ejemplo n.º 4
0
def initial_board_generator() -> Board:
    """Generate an initial board.

    Returns
    -------
    Board

    """
    black_disks = [(0, 0), (0, 2), (0, 4), (0, 6),
                   (1, 1), (1, 3), (1, 5), (1, 7),
                   (2, 0), (2, 2), (2, 4), (2, 6)]
    white_disks = []
    for location in black_disks:
        new_location = (7-location[0], 7-location[1])
        white_disks.append(new_location)
    for i, loc in enumerate(white_disks.copy()):
        white_disks[i] = Disk(location=loc, colour='white')
    for i, loc in enumerate(black_disks.copy()):
        black_disks[i] = Disk(location=loc, colour='black')
    b = Board(set(white_disks), set(black_disks))
    return b
Ejemplo n.º 5
0
    def show(self, board: Board) -> None:
        """Show the given board.

        Parameters
        ----------
        board : Board

        Returns
        -------
        None

        """
        for i in reversed(range(8)):
            print(f'{i} ', end='')
            for j in range(8):
                disk = board.get_disk_at((i, j))
                if disk is None:
                    print(' . ', end='')
                else:
                    out = ''
                    if disk.is_king() is True:
                        out += 'k'
                    if disk.get_colour() == 'white':
                        out += 'w'
                    else:
                        out += 'b'
                    if len(out) < 3:
                        out += ' '
                    if len(out) < 3:
                        out = ' ' + out
                    print(out, end='')
            print()
        print('  ', end='')
        for i in range(8):
            print(f' {i} ', end='')
        print()
        print()
Ejemplo n.º 6
0
 def _min(self, board: Board, depth: int, turn: int, draw_counter: int,
          alpha: float, beta: float) -> float:
     self._tot_num += 1
     if self._dynamic_depth is True:
         if self._tot_num > MiniMaxAlphaBetaSystem.maximum_nodes_number:
             return np.sum(
                 self._pred_system.predict([board], turn, draw_counter))
     status = self._terminal_state(board, turn, draw_counter)
     if status is not None:
         sign = 1 if turn % 2 == 1 else -1
         if status == 'win':
             return 100 * sign
         elif status == 'lose':
             return -100 * sign
         else:
             return 0
     if depth >= self._depth:
         return np.sum(
             self._pred_system.predict([board], turn, draw_counter))
     boards = []
     Moves.get_all_next_boards(board, 'black', boards)
     current_min = 1e7
     size_before = board.get_number_of_disks(None)
     for b in boards:
         next_draw_counter = draw_counter
         size_after = b.get_number_of_disks(None)
         next_draw_counter = update_draw_counter(next_draw_counter,
                                                 size_before, size_after)
         current_min = min(
             current_min,
             self._max(b, depth + 1, turn + 1, next_draw_counter, alpha,
                       beta))
         if current_min <= alpha:
             return current_min
         beta = min(beta, current_min)
     return current_min
Ejemplo n.º 7
0
 def _f4_number_of_white_kings(self, board: Board) -> float:
     return board.get_number_of_kings('white')
Ejemplo n.º 8
0
 def _f3_number_of_black_kings(self, board: Board) -> float:
     return board.get_number_of_kings('black')
Ejemplo n.º 9
0
 def _f2_number_of_white_pieces(self, board: Board) -> float:
     return board.get_number_of_disks('white')
Ejemplo n.º 10
0
 def _f1_number_of_black_pieces(self, board: Board) -> float:
     return board.get_number_of_disks('black')
Ejemplo n.º 11
0
        boards = []
        Moves.get_all_next_boards(board, 'black', boards)
        current_min = 1e7
        size_before = board.get_number_of_disks(None)
        for b in boards:
            next_draw_counter = draw_counter
            size_after = b.get_number_of_disks(None)
            next_draw_counter = update_draw_counter(next_draw_counter,
                                                    size_before, size_after)
            current_min = min(
                current_min,
                self._max(b, depth + 1, turn + 1, next_draw_counter, alpha,
                          beta))
            if current_min <= alpha:
                return current_min
            beta = min(beta, current_min)
        return current_min


if __name__ == '__main__':
    f_system = FeaturesBasedSystem('test', 0.01, True)
    white_disks = [(0, 4), (0, 6), (1, 5), (1, 7), (2, 0), (2, 4), (3, 5)]
    black_disks = [(3, 1), (4, 4), (5, 5), (6, 0), (6, 2), (6, 4), (6, 6)]
    for i, loc in enumerate(white_disks.copy()):
        white_disks[i] = Disk(location=loc, colour='white')
    for i, loc in enumerate(black_disks.copy()):
        black_disks[i] = Disk(location=loc, colour='black')
    b = Board(set(white_disks), set(black_disks))
    print(f_system.predict([b], 0, 0))
    print('Everything work.')