def is_legal_pawn_move(self, move, bb): """ Legal Pawn Moves: - Pawn non-attacks that don't intersect with occupied squares - Pawn attacks that intersect with opponent pieces :param move: The proposed move :param bb: An empty bitboard :return: (bool) is a legal pawn move """ moving_to_square = set_bit(bb, move.to_sq) legal_non_attack_moves = { Color.WHITE: self.board.white_pawn_motion_bbs[move.from_sq], Color.BLACK: self.board.black_pawn_motion_bbs[move.from_sq] } legal_non_attack_moves[self.to_move] &= self.board.empty_squares_bb legal_attack_moves = { Color.WHITE: self.board.white_pawn_attack_bbs[move.from_sq], Color.BLACK: self.board.black_pawn_attack_bbs[move.from_sq] } opp_occupied = { Color.WHITE: self.board.black_pieces_bb, Color.BLACK: self.board.white_pieces_bb } legal_attack_moves[self.to_move] &= opp_occupied[self.to_move] legal_moves = legal_non_attack_moves[ self.to_move] | legal_attack_moves[self.to_move] if self.en_passant_target: en_passant_bb = set_bit(bb, self.en_passant_target) en_passant_move = legal_attack_moves[self.to_move] & en_passant_bb legal_moves |= en_passant_move if moving_to_square & legal_attack_moves[self.to_move]: move.is_capture = True promotion_rank = {Color.WHITE: Rank.hex8, Color.BLACK: Rank.hex1} if moving_to_square & promotion_rank[self.to_move]: move.is_promotion = True print("legal moves:", legal_moves) print("moving_to_square:", moving_to_square) print("legal pawn move:", legal_moves & moving_to_square) return legal_moves & moving_to_square
def _set_black(self): self.black_R_bb |= set_bit(self.black_R_bb, 56) self.black_N_bb |= set_bit(self.black_N_bb, 57) self.black_B_bb |= set_bit(self.black_B_bb, 58) self.black_Q_bb |= set_bit(self.black_Q_bb, 59) self.black_K_bb |= set_bit(self.black_K_bb, 60) self.black_B_bb |= set_bit(self.black_B_bb, 61) self.black_N_bb |= set_bit(self.black_N_bb, 62) self.black_R_bb |= set_bit(self.black_R_bb, 63) for i in range (48,56): self.black_P_bb |= set_bit(self.black_P_bb, i)
def _set_white(self): self.white_R_bb |= set_bit(self.white_R_bb, 0) self.white_N_bb |= set_bit(self.white_N_bb, 1) self.white_B_bb |= set_bit(self.white_B_bb, 2) self.white_Q_bb |= set_bit(self.white_Q_bb, 3) self.white_K_bb |= set_bit(self.white_K_bb, 4) self.white_B_bb |= set_bit(self.white_B_bb, 5) self.white_N_bb |= set_bit(self.white_N_bb, 6) self.white_R_bb |= set_bit(self.white_R_bb, 7) for i in range (8,16): self.white_P_bb |= set_bit(self.white_P_bb, i)
def intersects_with_opp_pieces(self, square): bb = np.uint64(0) move_square_bb = set_bit(bb, square) occupy_lookup = { Color.WHITE: self.board.black_pieces_bb, Color.BLACK: self.board.white_pieces_bb, } return occupy_lookup[self.to_move] & move_square_bb
def is_legal_knight_move(self, move, bb): legal_knight_moves = self.board.get_knight_attack_from(move.from_sq) if not legal_knight_moves & set_bit(bb, move.to_sq): return False # if intersects_with_own_pieces return False if self.intersects_with_own_pieces(move.to_sq): return False # if intersects_with_opp_pieces return True, is_capture => True if self.intersects_with_opp_pieces(move.to_sq): move.is_capture = True return True return True
def update_bitboards(self, piece_map): for key, val in piece_map.items(): # White Pieces if key == Piece.wP: self.white_P_bb = np.uint64(0) for bit in val: self.white_P_bb |= set_bit(self.white_P_bb, np.uint64(bit)) elif key == Piece.wR: self.white_R_bb = np.uint64(0) for bit in val: self.white_R_bb |= set_bit(self.white_R_bb, np.uint64(bit)) elif key == Piece.wN: self.white_N_bb = np.uint64(0) for bit in val: self.white_N_bb |= set_bit(self.white_N_bb, np.uint64(bit)) elif key == Piece.wB: self.white_B_bb = np.uint64(0) for bit in val: self.white_B_bb |= set_bit(self.white_B_bb, np.uint64(bit)) elif key == Piece.wQ: self.white_Q_bb = np.uint64(0) for bit in val: self.white_Q_bb |= set_bit(self.white_Q_bb, np.uint64(bit)) elif key == Piece.wK: self.white_K_bb = np.uint64(0) for bit in val: self.white_K_bb |= set_bit(self.white_K_bb, np.uint64(bit)) # Black Pieces if key == Piece.bP: self.black_P_bb = np.uint64(0) for bit in val: self.black_P_bb |= set_bit(self.black_P_bb, np.uint64(bit)) elif key == Piece.bR: self.black_R_bb = np.uint64(0) for bit in val: self.black_R_bb |= set_bit(self.black_R_bb, np.uint64(bit)) elif key == Piece.bN: self.black_N_bb = np.uint64(0) for bit in val: self.black_N_bb |= set_bit(self.black_N_bb, np.uint64(bit)) elif key == Piece.bB: self.black_B_bb = np.uint64(0) for bit in val: self.black_B_bb |= set_bit(self.black_B_bb, np.uint64(bit)) elif key == Piece.bQ: self.black_Q_bb = np.uint64(0) for bit in val: self.black_Q_bb |= set_bit(self.black_Q_bb, np.uint64(bit)) elif key == Piece.bK: self.black_K_bb = np.uint64(0) for bit in val: self.black_K_bb |= set_bit(self.black_K_bb, np.uint64(bit))