Exemplo n.º 1
0
    def move_attacks(
        self,
        move: chess.Move,
        min_value: Optional[int] = None,
        max_value: Optional[int] = None,
        defended: Optional[bool] = None,
    ) -> chess.SquareSet:
        self._board.push(move)
        try:
            squares = chess.SquareSet(
                self._board.attacks_mask(move.to_square)
                & self._board.occupied_co[self.current_color])

            res = chess.SquareSet()
            for square in squares:
                if ((min_value is None
                     or self.piece_value_at(square) >= min_value)
                        and (max_value is None
                             or self.piece_value_at(square) <= max_value)
                        and (defended is None
                             or self.is_square_defended(square) == defended)):
                    res.add(square)
            return res
        finally:
            self._board.pop()
Exemplo n.º 2
0
def svg_dark_board(public_squares: List[chess.Square] = [],
    hidden_squares: List[chess.Square] = [],
    orientation: chess.Color = chess.WHITE,
    flipped: bool = False,
    coordinates: bool = True,
    **kwargs) -> ET.Element:
  svg = chess_svg.board(**kwargs)
  defs = ET.SubElement(svg, "defs")
  defs.append(ET.fromstring(PUBLIC_SQUARE_SVG))
  defs.append(ET.fromstring(HIDDEN_SQUARE_SVG))

  public_set = chess.SquareSet(public_squares)
  hidden_set = chess.SquareSet(hidden_squares)

  orientation ^= flipped
  margin = 15 if coordinates else 0

  for square, bb in enumerate(chess.BB_SQUARES):
    file_index = chess.square_file(square)
    rank_index = chess.square_rank(square)
    x = (
          file_index if orientation else 7 - file_index) * \
        chess_svg.SQUARE_SIZE + margin
    y = (
          7 - rank_index if orientation else rank_index) * \
        chess_svg.SQUARE_SIZE + margin

    if square in public_set:
      ET.SubElement(svg, "use", chess_svg._attrs({
        "xlink:href": "#public", "x": x, "y": y, }))
    if square in hidden_set:
      ET.SubElement(svg, "use", chess_svg._attrs({
        "xlink:href": "#hidden", "x": x, "y": y, }))

  return svg
Exemplo n.º 3
0
    def __init__(self):
        self.StartingPositionsPath = 'PositionsSet.txt'
        self.MlpClassificationWeights = 'Bobbyweights.h5'
        self.MlpDimension = 768
        self.NumberSimulationGames = 2
        self.MlpWins = 0
        self.CnnWins = 0
        self.Draws = 0
        self.width = 8
        self.height = 8
        self.channels = 16
        self.ImportantSquareSet = chess.SquareSet(chess.BB_D4 | chess.BB_D5
                                                  | chess.BB_C4 | chess.BB_C5
                                                  | chess.BB_E4 | chess.BB_E5
                                                  | chess.BB_F2 | chess.BB_F7
                                                  | chess.BB_H2 | chess.BB_H7)

        self.SquareSet = chess.SquareSet(
            chess.BB_A1 | chess.BB_A2 | chess.BB_A3 | chess.BB_A4 | chess.BB_A5
            | chess.BB_A6 | chess.BB_A7 | chess.BB_A8 | chess.BB_B1
            | chess.BB_B2 | chess.BB_B3 | chess.BB_B4 | chess.BB_B5
            | chess.BB_B6 | chess.BB_B7 | chess.BB_B8 | chess.BB_C1
            | chess.BB_C2 | chess.BB_C3 | chess.BB_C4 | chess.BB_C5
            | chess.BB_C6 | chess.BB_C7 | chess.BB_C8 | chess.BB_D1
            | chess.BB_D2 | chess.BB_D3 | chess.BB_D4 | chess.BB_D5
            | chess.BB_D6 | chess.BB_D7 | chess.BB_D8 | chess.BB_A1
            | chess.BB_E2 | chess.BB_E3 | chess.BB_E4 | chess.BB_E5
            | chess.BB_E6 | chess.BB_E7 | chess.BB_E8 | chess.BB_F1
            | chess.BB_F2 | chess.BB_F3 | chess.BB_F4 | chess.BB_F5
            | chess.BB_F6 | chess.BB_F7 | chess.BB_F8 | chess.BB_G1
            | chess.BB_G2 | chess.BB_G3 | chess.BB_G4 | chess.BB_G5
            | chess.BB_G6 | chess.BB_G7 | chess.BB_G8 | chess.BB_H1
            | chess.BB_H2 | chess.BB_H3 | chess.BB_H4 | chess.BB_H5
            | chess.BB_H6 | chess.BB_H7 | chess.BB_H8)
Exemplo n.º 4
0
def fill_piece(iplanes, ix, bb, b, flip_rank, flip_file):
    """ Compute piece placement and attack plane for a given piece type """
    if AUX_INP:
        abb = 0
        squares = chess.SquareSet(bb)
        for sq in squares:
            abb = abb | b.attacks_mask(sq)
            f = chess.square_file(sq)
            r = chess.square_rank(sq)
            if flip_rank: r = RANK_U - r
            if flip_file: f = FILE_U - f
            iplanes[r, f, ix + 12] = 1.0

        squares = chess.SquareSet(abb)
        for sq in squares:
            f = chess.square_file(sq)
            r = chess.square_rank(sq)
            if flip_rank: r = RANK_U - r
            if flip_file: f = FILE_U - f
            iplanes[r, f, ix] = 1.0
    else:
        squares = chess.SquareSet(bb)
        for sq in squares:
            f = chess.square_file(sq)
            r = chess.square_rank(sq)
            if flip_rank: r = RANK_U - r
            if flip_file: f = FILE_U - f
            iplanes[r, f, ix] = 1.0
Exemplo n.º 5
0
 def squareset(pc, f1, r1, x, f2, r2):
     hi1 = ~chess.SquareSet() if pc or f1 or r1 else chess.SquareSet()
     if pc is not None:
         hi1 &= board.pieces(
             chess.Piece.from_symbol(pc).piece_type, board.turn)
     if x and not pc: hi1 &= board.pieces(chess.PAWN, board.turn)
     if f1 is not None: hi1 &= chess.BB_FILES[ord(f1) - ord("a")]
     if r1 is not None: hi1 &= chess.BB_RANKS[ord(r1) - ord("1")]
     hi2 = ~chess.SquareSet() if f2 or r2 else chess.SquareSet()
     if f2 is not None: hi2 &= chess.BB_FILES[ord(f2) - ord("a")]
     if r2 is not None: hi2 &= chess.BB_RANKS[ord(r2) - ord("1")]
     return hi1 | hi2
Exemplo n.º 6
0
def has_pawn_structure(fen, white_files, black_files) -> bool:
    aug = board.AugBoard(fen)
    white_pawns = aug.pieces(chess.PAWN, chess.WHITE)
    black_pawns = aug.pieces(chess.PAWN, chess.BLACK)

    for color_files, color_pawns in zip([white_files, black_files],
                                        [white_pawns, black_pawns]):
        for file_name, ranks in color_files.items():
            file_idx = ord(file_name) - ord("a")
            present = color_pawns & chess.SquareSet(chess.BB_FILES[file_idx])
            expected = chess.SquareSet(
                [8 * (rank - 1) + file_idx for rank in ranks])
            if present != expected:
                return False
    return True
Exemplo n.º 7
0
 def __init__(self, color):
     self.color = color
     self.depth_limit = 3
     self.OUTER_CENTER = chess.SquareSet([
         chess.C3, chess.D3, chess.E3, chess.F3, chess.F4, chess.F5,
         chess.F6, chess.E6, chess.D6, chess.C6, chess.C5, chess.C4
     ])
    def possible(self):
        b = self.board.copy()
        for piece_type in chess.PIECE_TYPES:
            for sq in b.pieces(piece_type, not self.color):
                b.remove_piece_at(sq)

        pawn_capture_moves = []

        no_opponents_board = b.copy()

        for pawn_square in self.board.pieces(chess.PAWN, self.color):
            for attacked_square in self.board.attacks(pawn_square):
                # skip this square if one of our own pieces are on the square
                if no_opponents_board.piece_at(attacked_square):
                    continue

                pawn_capture_moves.append(
                    chess.Move(pawn_square, attacked_square))

                # add in promotion moves
                if attacked_square in chess.SquareSet(chess.BB_BACKRANKS):
                    for piece_type in chess.PIECE_TYPES[1:-1]:
                        pawn_capture_moves.append(
                            chess.Move(pawn_square,
                                       attacked_square,
                                       promotion=piece_type))

        return list(b.generate_pseudo_legal_moves()) + pawn_capture_moves
Exemplo n.º 9
0
    def can_image_correspond_to_chessboard(self, move,
                                           current_chessboard_image):
        self.board.push(move)
        squares = chess.SquareSet(chess.BB_ALL)
        for square in squares:
            row = chess.square_rank(square)
            column = chess.square_file(square)
            piece = self.board.piece_at(square)
            shouldBeEmpty = (piece == None)

            if self.we_play_white == True:
                rowOnImage = 7 - row
                columnOnImage = column
            else:
                rowOnImage = row
                columnOnImage = 7 - column

            squareImage = get_square_image(rowOnImage, columnOnImage,
                                           current_chessboard_image)

            if is_square_empty(squareImage) != shouldBeEmpty:
                self.board.pop()
                #print( "Problem with : ", self.board.uci(move) ," the square ", rowOnImage, columnOnImage, "should ",'be empty' if shouldBeEmpty else 'contain a piece')
                return False
        #print("Accepted move", self.board.uci(move))
        self.board.pop()
        return True
Exemplo n.º 10
0
 def IsLocked(self,
              fen,
              pc=10,
              sqs=gamelib.SquareSet([
                  gamelib.C3, gamelib.C4, gamelib.C5, gamelib.C6,
                  gamelib.D3, gamelib.D4, gamelib.D5, gamelib.D6,
                  gamelib.E3, gamelib.E4, gamelib.E5, gamelib.E6,
                  gamelib.F3, gamelib.F4, gamelib.F5, gamelib.F6,
                  gamelib.B3, gamelib.B4, gamelib.B5, gamelib.B6,
                  gamelib.G3, gamelib.G4, gamelib.G5, gamelib.G6
              ])):
     DetectionRange = sqs
     PieceThreshold = pc
     DetectedPieces = 0
     fenbrd = gamelib.Board()
     fenbrd.set_fen(fen)
     bb = gamelib.BaseBoard()
     bb.set_board_fen(fenbrd.board_fen())
     del (fenbrd)
     pcs = list(bb.piece_map().keys())
     for sqr in DetectionRange:
         if sqr in pcs:
             DetectedPieces += 1
     if DetectedPieces > PieceThreshold:
         return True
     else:
         return False
Exemplo n.º 11
0
    def _is_illegal_castle(self, board, move):
        if not board.is_castling(move):
            return False

        # illegal without kingside rights
        if board.is_kingside_castling(
                move) and not board.has_kingside_castling_rights(board.turn):
            return True

        # illegal without queenside rights
        if board.is_queenside_castling(
                move) and not board.has_queenside_castling_rights(board.turn):
            return True

        # illegal if any pieces are between king & rook
        rook_square = chess.square(
            7 if board.is_kingside_castling(move) else 0,
            chess.square_rank(move.from_square))
        between_squares = chess.SquareSet(
            chess.BB_BETWEEN[move.from_square][rook_square])
        if any(map(lambda s: board.piece_at(s), between_squares)):
            return True

        # its legal
        return False
Exemplo n.º 12
0
    def handle_sensed_pawn(self, new_pawn_square, piece):
        ''' updates self.board if sensed pawn'''
        # only get rid of old pawn in column if this pawn didn't just capture
        # print (chess.SQUARE_NAMES[new_pawn_square])
        # print (new_pawn_square)
        # print (self.my_piece_captured_square)
        if not self.my_piece_captured_square == new_pawn_square:
            # remove furthest pawn in column
            pawn_file = chess.square_file(new_pawn_square)
            pawn_file_list = np.array(
                chess.SquareSet(chess.BB_FILE_MASKS[pawn_file]).tolist())
            pawn_file_locations = np.where(pawn_file_list == True)[0]

            #if playing as black, must search from top down instead of bottom up
            if self.color == chess.BLACK:
                np.flip(pawn_file_locations)

            for square in pawn_file_locations:
                if self.board.piece_at(square) == piece:
                    self.board.remove_piece_at(square)
                    break
            self.set_board_piece(new_pawn_square, piece)

        # else:
        # #print ("JUST GOT PIECE CAPTURED")

        self.set_board_piece(new_pawn_square, piece)
Exemplo n.º 13
0
    def _pawn_on(self, board, turn):
        """
        Generates all pawn captures on `board`, even if there is no piece to capture. All promotion moves are included.
        :param board: chess.Board -- a chess board where you want opponnet's pieces to be removed
        :param turn: bool - True(WHITE's turn) or False(BLACK's turn), the opponnet is the 'not turn'
        
        :return: List(chess.Move)
        """
        pawn_capture_moves = []

        no_opponents_board = self._no_opp_pieces(board, turn)

        for pawn_square in board.pieces(chess.PAWN, turn):
            for attacked_square in board.attacks(pawn_square):
                # skip this square if one of our own pieces are on the square
                if no_opponents_board.piece_at(attacked_square):
                    continue

                pawn_capture_moves.append(
                    chess.Move(pawn_square, attacked_square))

                # add in promotion moves
                if attacked_square in chess.SquareSet(chess.BB_BACKRANKS):
                    for piece_type in chess.PIECE_TYPES[1:-1]:
                        pawn_capture_moves.append(
                            chess.Move(pawn_square,
                                       attacked_square,
                                       promotion=piece_type))

        return pawn_capture_moves
Exemplo n.º 14
0
def highlight_san_move(text, board=None):
    """
    Parse a move in SAN (or UCI) notation, and return a set of
    highlighted squares the move might be affecting.
    """

    # [QKNRB]?[a-h]?[1-8]?x?[a-h][1-8]=?[QNRB]
    def squareset(pc, f1, r1, x, f2, r2):
        hi1 = ~chess.SquareSet() if pc or f1 or r1 else chess.SquareSet()
        if pc is not None:
            hi1 &= board.pieces(
                chess.Piece.from_symbol(pc).piece_type, board.turn)
        if x and not pc: hi1 &= board.pieces(chess.PAWN, board.turn)
        if f1 is not None: hi1 &= chess.BB_FILES[ord(f1) - ord("a")]
        if r1 is not None: hi1 &= chess.BB_RANKS[ord(r1) - ord("1")]
        hi2 = ~chess.SquareSet() if f2 or r2 else chess.SquareSet()
        if f2 is not None: hi2 &= chess.BB_FILES[ord(f2) - ord("a")]
        if r2 is not None: hi2 &= chess.BB_RANKS[ord(r2) - ord("1")]
        return hi1 | hi2

    match = rx_move.match(text)
    if not match: return chess.SquareSet()
    pc, f1, r1, x, f2, r2, pr = match.groups()
    ss = squareset(pc, f1, r1, x, f2, r2)
    if not x and not f2 and not r2:
        ss |= squareset(pc, None, None, None, f1, r1)
    return ss
Exemplo n.º 15
0
def draw_empty_board(font: pygame.font.SysFont, w) -> pygame.Surface:
    surface = pygame.Surface((w, w))
    pygame.draw.rect(surface, LIGHT_COLOR, (0, 0, w, w))
    sw = w / 8

    for dark_square in chess.SquareSet(chess.BB_DARK_SQUARES):
        sx = sw * chess.square_file(dark_square)
        sy = w - sw - sw * chess.square_rank(dark_square)
        pygame.draw.rect(surface, DARK_COLOR, (sx, sy, sw, sw))

    example_label = font.render("a", True, (0, 0, 0))
    rect = example_label.get_rect()
    for i in range(0, 8, 2):
        surface.blit(
            font.render(chess.FILE_NAMES[i], True, LIGHT_COLOR),
            (sw * i, w - rect.height),
        )
        surface.blit(
            font.render(chess.RANK_NAMES[i], True, DARK_COLOR),
            (w - rect.width, w - sw - sw * i),
        )
    for i in range(1, 8, 2):
        surface.blit(
            font.render(chess.FILE_NAMES[i], True, DARK_COLOR),
            (sw * i, w - rect.height),
        )
        surface.blit(
            font.render(chess.RANK_NAMES[i], True, LIGHT_COLOR),
            (w - rect.width, w - sw - sw * i),
        )

    return surface
Exemplo n.º 16
0
def random_positions(max_pieces=64):
    board = chess.Board()

    while True:
        board.clear()
        piece_list = random_piece_list(max_pieces)
        for square, piece in enumerate(piece_list):
            if piece:
                board.set_piece_at(square, piece)

        board.turn = random.choice(chess.COLORS)

        # Skip positions with the opposite side in check.
        if board.was_into_check():
            continue

        # Skip positions with pawns on the promotion rank.
        if board.pawns & board.occupied_co[chess.WHITE] & chess.BB_RANK_8:
            continue
        if board.pawns & board.occupied_co[chess.BLACK] & chess.BB_RANK_1:
            continue

        yield board

        # Generate positions with kinda valid en-passant squares.
        if board.turn == chess.BLACK:
            for potential_ep in chess.SquareSet(chess.BB_RANK_3):
                board.ep_square = potential_ep
                if (board.piece_at(
                        chess.square(chess.file_index(potential_ep), 3))
                        == chess.Piece(chess.PAWN, chess.WHITE)
                        and not board.piece_at(
                            chess.square(chess.file_index(potential_ep), 2))
                        and not board.piece_at(
                            chess.square(chess.file_index(potential_ep), 1))):
                    yield board
        else:
            for potential_ep in chess.SquareSet(chess.BB_RANK_6):
                board.ep_square = potential_ep
                if (board.piece_at(
                        chess.square(chess.file_index(potential_ep), 4))
                        == chess.Piece(chess.PAWN, chess.BLACK)
                        and not board.piece_at(
                            chess.square(chess.file_index(potential_ep), 5))
                        and not board.piece_at(
                            chess.square(chess.file_index(potential_ep), 6))):
                    yield board
Exemplo n.º 17
0
def PsqtEval(pos, color):
    board = pos.board
    if color == chess.WHITE:
        score = 0
        for square in chess.SquareSet(board.occupied_co[chess.WHITE]):
            piece = board.piece_type_at(square)

            score += psqt[piece][transform(square,
                                           chess.WHITE)] + pieces[piece]
        return score
    else:
        score = 0
        for square in chess.SquareSet(board.occupied_co[chess.BLACK]):
            piece = board.piece_type_at(square)
            score += psqt[piece][transform(square,
                                           chess.BLACK)] + pieces[piece]
        return score
Exemplo n.º 18
0
def evaluate_pinned_pieces(board):
    squares = chess.SquareSet(chess.BB_ALL)
    result = 0
    for square in list(squares):
        if board.is_pinned(chess.BLACK, square):
            result = 20

    return result
Exemplo n.º 19
0
def diff2squareset(s1, s2):
    board1 = chess.BaseBoard(s1)
    board2 = chess.BaseBoard(s2)
    diffmap = chess.SquareSet()
    for x in range(chess.A1, chess.H8 + 1):
        if board1.piece_at(x) != board2.piece_at(x):
            diffmap.add(x)
    return diffmap
Exemplo n.º 20
0
def _possible_moves():
    res = set()
    for f in SQUARES:
        for t in chess.SquareSet(chess.BB_RANK_ATTACKS[f][0]):
            res.add((f, t))

        for t in chess.SquareSet(chess.BB_FILE_ATTACKS[f][0]):
            res.add((f, t))

        for t in chess.SquareSet(chess.BB_DIAG_ATTACKS[f][0]):
            res.add((f, t))

        for t in chess.SquareSet(chess.BB_KNIGHT_ATTACKS[f]):
            res.add((f, t))

    assert (10, 26) in res

    return list(sorted(res))
Exemplo n.º 21
0
 def get_moves_from_square(self, square):
     square_moves = chess.SquareSet()
     for move in self.board.legal_moves:
         if move.from_square == square:
             square_moves.add(move.to_square)
     if len(square_moves.tolist()) == 0:
         return None
     else:
         return square_moves
Exemplo n.º 22
0
 def _slide_move(self, board, move):
     psuedo_legal_moves = list(board.generate_pseudo_legal_moves())
     squares = list(chess.SquareSet(chess.BB_BETWEEN[move.from_square][move.to_square])) + [move.to_square]
     squares = sorted(squares, key=lambda s: chess.square_distance(s, move.from_square), reverse=True)
     for slide_square in squares:
         revised = chess.Move(move.from_square, slide_square, move.promotion)
         if revised in psuedo_legal_moves:
             return revised
     return None
Exemplo n.º 23
0
 def square_capturers(self, square: int) -> chess.SquareSet:
     """
     Returns a set of squares that can perform a legal capture on the given square in the current position.
     """
     res = chess.SquareSet()
     for m in self._board.generate_legal_captures(
             to_mask=chess.BB_SQUARES[square]):
         res.add(m.from_square)
     return res
Exemplo n.º 24
0
    def make_svg(self, request):
        try:
            board = chess.Board(request.query["fen"])
        except KeyError:
            raise aiohttp.web.HTTPBadRequest(reason="fen required")
        except ValueError:
            raise aiohttp.web.HTTPBadRequest(reason="invalid fen")

        try:
            size = min(max(int(request.query.get("size", 360)), 16), 1024)
        except ValueError:
            raise aiohttp.web.HTTPBadRequest(reason="size is not a number")

        try:
            uci = request.query.get("lastMove") or request.query["lastmove"]
            lastmove = chess.Move.from_uci(uci)
        except KeyError:
            lastmove = None
        except ValueError:
            raise aiohttp.web.HTTPBadRequest(reason="lastMove is not a valid uci move")

        try:
            check = chess.parse_square(request.query["check"])
        except KeyError:
            check = None
        except ValueError:
            raise aiohttp.web.HTTPBadRequest(reason="check is not a valid square name")

        try:
            arrows = [chess.svg.Arrow.from_pgn(s.strip()) for s in request.query.get("arrows", "").split(",") if s.strip()]
        except ValueError:
            raise aiohttp.web.HTTPBadRequest(reason="invalid arrow")

        try:
            squares = chess.SquareSet(chess.parse_square(s.strip()) for s in request.query.get("squares", "").split(",") if s.strip())
        except ValueError:
            raise aiohttp.web.HTTPBadRequest(reason="invalid squares")

        flipped = request.query.get("orientation", "white") == "black"

        coordinates = request.query.get("coordinates", "0") in ["", "1", "true", "True", "yes"]

        try:
            colors = THEMES[request.query.get("colors", "lichess-brown")]
        except KeyError:
            raise aiohttp.web.HTTPBadRequest(reason="theme colors not found")

        return chess.svg.board(board,
                               coordinates=coordinates,
                               flipped=flipped,
                               lastmove=lastmove,
                               check=check,
                               arrows=arrows,
                               squares=squares,
                               size=size,
                               colors=colors)
Exemplo n.º 25
0
 def render_board(self, hint=False):
     next_moves = chess.SquareSet()
     if hint:
         for move in self.board.legal_moves:
             next_moves.add(move.to_square)
     # Conversion code:
     raw_svg = chess.svg.board(board=self.board,
                               squares=next_moves,
                               style=self.css)
     return svg2png(raw_svg)
Exemplo n.º 26
0
 def __call__(self, pos, color):
     # find the lowest piece that we attack
     score = 0
     my_pawns = pos.board.pawns & pos.board.occupied_co[color]
     for square in chess.SquareSet(my_pawns):
         if color == chess.BLACK:
             score += 7 - chess.square_rank(square)
         else:
             score += chess.square_rank(square)
     return 20 * score
Exemplo n.º 27
0
 def getSquareFromSquareSet(self, bigInt):  #convinence method
     square_set = chess.SquareSet(bigInt)
     hi = []
     for i, boolV in enumerate(square_set.tolist()):
         if boolV:
             hi.append(i)
     if len(hi) <= 1:
         return hi[0]
     else:
         raise error
Exemplo n.º 28
0
 def move_capturers(self, move: chess.Move) -> chess.SquareSet:
     self._board.push(move)
     try:
         res = chess.SquareSet()
         for m in self._board.generate_legal_captures(
                 to_mask=chess.BB_SQUARES[move.to_square]):
             res.add(m.from_square)
         return res
     finally:
         self._board.pop()
Exemplo n.º 29
0
 def material_value(self, board=None):
     if board is None:
         board = self.engine.current_board
     values = [0, 1, 3, 3, 5, 9, 0]
     sum = 0
     for square in chess.SquareSet(chess.BB_ALL):
         piece = board.piece_type_at(square)
         if piece:
             sum += values[piece]
     return sum
Exemplo n.º 30
0
def get_board_square_set(board: chess.Board) -> chess.SquareSet:
    """
    Returns current board represented in list with 64 bits
    :returns chess.SquareSet
    """
    square_set = chess.SquareSet()  # Empty square set
    for key in board.piece_map().keys():
        square_set.add(key)

    return square_set