예제 #1
0
def _add_correct_cells_by_ray(position,
                              correct_cells,
                              chess_board,
                              figure_side,
                              dx,
                              dy,
                              step_len=Board.COLUMN_SIZE,
                              can_step_on_figure=True):
    delta = Vector2d(dx, dy)
    cur_step_len = 0

    while cur_step_len < step_len and \
            Board.ROW_SIZE > position.x + delta.x >= 0 and \
            0 <= position.y + delta.y < Board.COLUMN_SIZE and \
            _is_none_or_enemy(chess_board, position + delta, figure_side):

        if _is_enemy(chess_board, position + delta, figure_side):
            if can_step_on_figure:
                correct_cells.append(position + delta)
                break
            else:
                break
        elif _is_enemy(chess_board, position + delta,
                       Side.get_oposite(figure_side)):
            break

        correct_cells.append(position + delta)
        delta.x = delta.x + dx
        delta.y = delta.y + dy
        cur_step_len = cur_step_len + 1
예제 #2
0
    def generate_moves(self, chess_board, its_my_turn=True):
        correct_cells = []

        if its_my_turn is True:
            self.roque_right(chess_board, correct_cells)
            self.roque_left(chess_board, correct_cells)

        _add_correct_cells_by_ray(self.position, correct_cells, chess_board,
                                  self.side, 0, 1, 1)
        _add_correct_cells_by_ray(self.position, correct_cells, chess_board,
                                  self.side, 0, -1, 1)
        _add_correct_cells_by_ray(self.position, correct_cells, chess_board,
                                  self.side, 1, 1, 1)
        _add_correct_cells_by_ray(self.position, correct_cells, chess_board,
                                  self.side, -1, -1, 1)
        _add_correct_cells_by_ray(self.position, correct_cells, chess_board,
                                  self.side, 1, 0, 1)
        _add_correct_cells_by_ray(self.position, correct_cells, chess_board,
                                  self.side, -1, 0, 1)
        _add_correct_cells_by_ray(self.position, correct_cells, chess_board,
                                  self.side, 1, -1, 1)
        _add_correct_cells_by_ray(self.position, correct_cells, chess_board,
                                  self.side, -1, 1, 1)

        if its_my_turn is True:
            summary_attacked_cells = chess_board.summary_attacked_cells(
                Side.get_oposite(self.side))

            for i in range(len(summary_attacked_cells)):
                try:
                    correct_cells.remove(summary_attacked_cells[i])
                except ValueError:
                    pass
        return correct_cells
예제 #3
0
    def roque_right(self, chess_board, correct_cells):

        # self does not move
        if self.was_moved is True:
            return

        # self not on check
        attack_cells = chess_board.summary_attacked_cells(
            Side.get_oposite(self.side))

        if self.position in attack_cells:
            return

        if self.side == Side.WHITE:
            default_rook_right_pos = gb.GameBoard.default_white_rook_right_pos
        else:
            default_rook_right_pos = gb.GameBoard.default_black_rook_right_pos

        right_rook = chess_board.get(default_rook_right_pos)

        # rook does not move
        if not (right_rook is not None and isinstance(right_rook, Rook)
                and right_rook.was_moved is False):
            return

        # not on attack cell
        if self.position + Vector2d(1, 0) in attack_cells:
            return

        ray_to_rook = []
        _add_correct_cells_by_ray(self.position, ray_to_rook, chess_board,
                                  Side.get_oposite(self.side), 1, 0)
        if len(ray_to_rook) == 0:
            return
        if chess_board.get(ray_to_rook[len(ray_to_rook) -
                                       1]).position != default_rook_right_pos:
            return

        correct_cells.append(self.position + Vector2d(2, 0))
예제 #4
0
 def is_that_mate(self, my_side):
     enemy_figures = self.get_figures_list(Side.get_oposite(my_side))
     for i in range(len(enemy_figures)):
         cur_figure = enemy_figures[i]
         available_moves = cur_figure.generate_moves(self)
         for j in range(len(available_moves)):
             new_chess_board = copy.deepcopy(self)
             if new_chess_board.get(cur_figure.position) is None:
                 print(cur_figure.position.x)
                 print(cur_figure.position.y)
             new_chess_board.make_move(Move(cur_figure.position, available_moves[j]))
             if new_chess_board.is_that_check(my_side) is False:
                 return False
     return True
예제 #5
0
    def check_move(self, move, side):
        """
        Check current position state function
        :param side: player current side
        :param move: move figure sructure (Vector2d)
        :param chess_board: chess board class (see ChessBoard.Board)
        :return: MoveResult
        """
        result = MoveResult.INCORRECT

        figure_in_src = self.game_board.get(move.point_from)

        if figure_in_src is None:
            return result

        if figure_in_src.side != side:
            return result

        if figure_in_src is None:
            return result

        my_side = figure_in_src.side
        correct_moves = figure_in_src.generate_moves(self.game_board)
        if len(correct_moves) == 0:
            return result

        if move.point_to in correct_moves:
            result = MoveResult.DEFAULT

        if result == MoveResult.INCORRECT:
            return result

        new_game_board = copy.deepcopy(self.game_board)
        new_game_board.make_move(move)
        if new_game_board.is_that_check(Side.get_oposite(my_side)):
            result = MoveResult.INCORRECT

        if result == MoveResult.INCORRECT:
            return result

        if new_game_board.is_that_check(my_side):
            result = MoveResult.CHECK
            if new_game_board.is_that_mate(my_side):
                result = MoveResult.MATE
        else:
            if new_game_board.is_that_stalemate(my_side):
                result = MoveResult.STALEMATE

        return result
예제 #6
0
    def check_board_res(self, side):
        result = MoveResult.DEFAULT

        new_game_board = copy.deepcopy(self.game_board)
        if new_game_board.is_that_check(Side.get_oposite(side)):
            result = MoveResult.INCORRECT

        if result == MoveResult.INCORRECT:
            return result

        if new_game_board.is_that_check(side):
            result = MoveResult.CHECK
            if new_game_board.is_that_mate(side):
                result = MoveResult.MATE
        else:
            if new_game_board.is_that_stalemate(side):
                result = MoveResult.STALEMATE

        return result
예제 #7
0
    def calc_best_move(self,
                       depth,
                       game,
                       player_color,
                       alpha=-999999999,
                       beta=999999999,
                       is_maximizing_player=True):
        # Base case: evaluate board
        if depth == 0:
            value = game.game_board.evaluate(self.side)
            return value, None

        # Recursive case: search possible moves
        best_swaped_figure = None
        best_move = None  # best move not set yet
        possible_moves = game.game_board.summary_moves(player_color)

        # Set random order for possible moves
        shuffle(possible_moves)

        # Set a default best move value
        if is_maximizing_player:
            best_move_value = -99999999
        else:
            best_move_value = 99999999

        # Search through all possible moves
        for i in range(len(possible_moves)):
            move_res = game.check_move(possible_moves[i], player_color)
            if move_res is not MoveResult.INCORRECT:
                move = possible_moves[i]

                # Make the move, but undo before exiting loop
                new_game = copy.deepcopy(game)
                new_game.update(possible_moves[i], player_color)

                # pawn swaped check
                expected_pawn = new_game.game_board.get(move.point_to)
                if isinstance(expected_pawn, Figures.Pawn):
                    assert (self.pawn_swaped_latters is not None)
                    if expected_pawn.side is Side.WHITE:
                        if move.point_to.y == 0:
                            for figure_lat in self.pawn_swaped_latters:
                                new_game.swap_pawn(move.point_to, figure_lat)
                                value, move_side_effect = self.calc_best_move(
                                    depth - 1, new_game,
                                    Side.get_oposite(player_color), alpha,
                                    beta, not is_maximizing_player)
                                if is_maximizing_player:
                                    # Look for moves that maximize position
                                    if value > best_move_value:
                                        best_move_value = value
                                        best_move = move
                                        best_swaped_figure = figure_lat
                                    alpha = max(alpha, value)
                                else:
                                    # Look for moves that minimize position
                                    if value < best_move_value:
                                        best_move_value = value
                                        best_move = move
                                        best_swaped_figure = figure_lat
                                    beta = min(beta, value)

                                # Check for alpha beta pruning
                                if beta <= alpha:
                                    # print('Prune', alpha, beta)
                                    return best_move_value, best_move
                        else:
                            # Recursively get the value from this move
                            value, move_side_effect = self.calc_best_move(
                                depth - 1, new_game,
                                Side.get_oposite(player_color), alpha, beta,
                                not is_maximizing_player)
                            if is_maximizing_player:
                                # Look for moves that maximize position
                                if value > best_move_value:
                                    best_move_value = value
                                    best_move = move
                                alpha = max(alpha, value)
                            else:
                                # Look for moves that minimize position
                                if value < best_move_value:
                                    best_move_value = value
                                    best_move = move
                                beta = min(beta, value)

                            # Check for alpha beta pruning
                            if beta <= alpha:
                                # print('Prune', alpha, beta)
                                return best_move_value, best_move

                    if expected_pawn.side is Side.BLACK:
                        if move.point_to.y == 7:
                            for figure_lat in self.pawn_swaped_latters:
                                new_game.swap_pawn(move.point_to, figure_lat)
                                value, move_side_effect = self.calc_best_move(
                                    depth - 1, new_game,
                                    Side.get_oposite(player_color), alpha,
                                    beta, not is_maximizing_player)
                                if is_maximizing_player:
                                    # Look for moves that maximize position
                                    if value > best_move_value:
                                        best_move_value = value
                                        best_move = move
                                        best_swaped_figure = figure_lat
                                    alpha = max(alpha, value)
                                else:
                                    # Look for moves that minimize position
                                    if value < best_move_value:
                                        best_move_value = value
                                        best_move = move
                                        best_swaped_figure = figure_lat
                                    beta = min(beta, value)

                                # Check for alpha beta pruning
                                if beta <= alpha:
                                    # print('Prune', alpha, beta)
                                    return best_move_value, best_move
                        else:
                            # Recursively get the value from this move
                            value, move_side_effect = self.calc_best_move(
                                depth - 1, new_game,
                                Side.get_oposite(player_color), alpha, beta,
                                not is_maximizing_player)
                            if is_maximizing_player:
                                # Look for moves that maximize position
                                if value > best_move_value:
                                    best_move_value = value
                                    best_move = move
                                alpha = max(alpha, value)
                            else:
                                # Look for moves that minimize position
                                if value < best_move_value:
                                    best_move_value = value
                                    best_move = move
                                beta = min(beta, value)

                            # Check for alpha beta pruning
                            if beta <= alpha:
                                # print('Prune', alpha, beta)
                                return best_move_value, best_move
                else:
                    # Recursively get the value from this move
                    value, move_side_effect = self.calc_best_move(
                        depth - 1, new_game, Side.get_oposite(player_color),
                        alpha, beta, not is_maximizing_player)

                    if is_maximizing_player:
                        # Look for moves that maximize position
                        if value > best_move_value:
                            best_move_value = value
                            best_move = move
                        alpha = max(alpha, value)
                    else:
                        # Look for moves that minimize position
                        if value < best_move_value:
                            best_move_value = value
                            best_move = move
                        beta = min(beta, value)

                    # Check for alpha beta pruning
                    if beta <= alpha:
                        # print('Prune', alpha, beta)
                        return best_move_value, best_move

        if depth == self.depth:
            self.move = best_move
            self.value = best_move_value
            self.pawn_swaped_figure = best_swaped_figure

        return best_move_value, best_move
예제 #8
0
 def update(self, move, side):
     figure = self.game_board.get(move.point_from)
     assert figure is not None
     self.game_board.make_move(move)
     self.game_board.delete_double_move(Side.get_oposite(side))
예제 #9
0
 def is_that_check(self, my_side):
     attacked_cells = self.summary_attacked_cells(my_side)
     enemy_king_cell = self.get_king_cell(Side.get_oposite(my_side))
     return enemy_king_cell in attacked_cells