diff --git a/chess/chess_64.py b/chess/chess_64.py index 369813c..abd2046 100644 --- a/chess/chess_64.py +++ b/chess/chess_64.py @@ -22,37 +22,20 @@ A3, B3, C3, D3, E3, F3, G3, H3 = range(16, 24) A2, B2, C2, D2, E2, F2, G2, H2 = range(8, 16) A1, B1, C1, D1, E1, F1, G1, H1 = range(8) -# 0 = Normaler Zug (Quiet Move) +# Move Flags QUIET = 0 - -# 1 = Doppelschritt Bauer (wichtig für En Passant im nächsten Zug) DOUBLE_PAWN_PUSH = 1 - -# 2 & 3 = Rochaden KING_CASTLE = 2 QUEEN_CASTLE = 3 - -# 4 = Normaler Schlagzug (Capture) -# Manche Engines codieren Captures extra, manche schauen einfach aufs Brett. -# Für den Anfang reicht es, Captures einfach als Flag 4 zu markieren. CAPTURE = 4 - -# 5 = En Passant Schlag EP_CAPTURE = 5 -# 8-15 = Umwandlungen (Promotion) -# Struktur: 8 + Figur (Springer=0, Läufer=1, Turm=2, Dame=3) +# Falls Capture +4 (z.B. BIS Capture -> 13) PROMO_KNIGHT = 8 PROMO_BISHOP = 9 PROMO_ROOK = 10 PROMO_QUEEN = 11 -# Umwandlung mit Schlagen (optional, spart Zeit beim Checken) -PROMO_N_CAPTURE = 12 -PROMO_B_CAPTURE = 13 -PROMO_R_CAPTURE = 14 -PROMO_Q_CAPTURE = 15 - # Masks NOT_A = 0xfefefefefefefefe NOT_H = 0x7f7f7f7f7f7f7f7f @@ -113,15 +96,22 @@ class Bitboard(): opp = turn ^ 1 turn_offset = turn * 6 opp_offset = opp *6 - # import local Varibles + + # region import self & global Varibles for speed optimization bbs = self.bitboards opponent_pcs = self.all_pieces[opp] friendly_pcs = self.all_pieces[turn] occupancy = opponent_pcs | friendly_pcs + kin, que, bis, nht, roo, paw, no_piece = KIN, QUE, BIS, NHT, ROO, PAW, NO_PIECE + nht_attacks_list, paw_attacks_list = NHT_ATTACKS, PAW_ATTACKS + quiet, dpp, k_castle, q_castle, capture, ep_capture = QUIET, DOUBLE_PAWN_PUSH, KING_CASTLE, QUEEN_CASTLE, CAPTURE, EP_CAPTURE + promo_knight, promo_bishop, promo_rook, promo_queen = PROMO_KNIGHT, PROMO_BISHOP, PROMO_ROOK, PROMO_QUEEN + rays_n, rays_ne, rays_e, rays_se, rays_s, rays_sw, rays_w, rays_nw = RAYS_N, RAYS_NE, RAYS_E, RAYS_SE, RAYS_S, RAYS_SW, RAYS_W, RAYS_NW + # endregion # region --- King Moves --- - kin_sq = bbs[KIN + turn_offset].bit_length() - 1 - kin_attacks = KIN_ATTACKS[kin_sq] + kin_sq = bbs[kin + turn_offset].bit_length() - 1 + kin_attacks = KIN_ATTACKS[kin_sq] kin_attacks &= ~friendly_pcs while kin_attacks: @@ -130,27 +120,27 @@ class Bitboard(): kin_attacks &= (kin_attacks - 1) if to_mask & opponent_pcs: - if to_mask & bbs[PAW + opp_offset]: - capture = PAW + opp_offset - elif to_mask & bbs[NHT + opp_offset]: - capture = NHT + opp_offset - elif to_mask & bbs[BIS + opp_offset]: - capture = BIS + opp_offset - elif to_mask & bbs[ROO + opp_offset]: - capture = ROO + opp_offset + if to_mask & bbs[paw + opp_offset]: + captured = paw + opp_offset + elif to_mask & bbs[nht + opp_offset]: + captured = nht + opp_offset + elif to_mask & bbs[bis + opp_offset]: + captured = bis + opp_offset + elif to_mask & bbs[roo + opp_offset]: + captured = roo + opp_offset else: - capture = QUE + opp_offset - captures.append(to_sq | (kin_sq << 6) | ((KIN + turn_offset) << 12) | (capture << 16) | CAPTURE << 20) + captured = que + opp_offset + captures.append(to_sq | (kin_sq << 6) | ((kin + turn_offset) << 12) | (captured << 16) | capture << 20) else: - moves.append(to_sq | (kin_sq << 6) | ((KIN + turn_offset) << 12) | (NO_PIECE << 16) | QUIET << 20) + moves.append(to_sq | (kin_sq << 6) | ((kin + turn_offset) << 12) | (no_piece << 16) | quiet << 20) # endregion # region --- Knight Moves --- - nht_bb = bbs[NHT + turn_offset] + nht_bb = bbs[nht + turn_offset] while nht_bb: nht_sq = (nht_bb & -nht_bb).bit_length() - 1 nht_bb &= (nht_bb - 1) - nht_attacks = NHT_ATTACKS[nht_sq] + nht_attacks = nht_attacks_list[nht_sq] nht_attacks &= ~friendly_pcs while nht_attacks: @@ -159,83 +149,83 @@ class Bitboard(): nht_attacks &= (nht_attacks - 1) if to_mask & opponent_pcs: - if to_mask & bbs[PAW + opp_offset]: - capture = PAW + opp_offset - elif to_mask & bbs[NHT + opp_offset]: - capture = NHT + opp_offset - elif to_mask & bbs[BIS + opp_offset]: - capture = BIS + opp_offset - elif to_mask & bbs[ROO + opp_offset]: - capture = ROO + opp_offset + if to_mask & bbs[paw + opp_offset]: + captured = paw + opp_offset + elif to_mask & bbs[nht + opp_offset]: + captured = nht + opp_offset + elif to_mask & bbs[bis + opp_offset]: + captured = bis + opp_offset + elif to_mask & bbs[roo + opp_offset]: + captured = roo + opp_offset else: - capture = QUE + opp_offset - captures.append(to_sq | (nht_sq << 6) | ((NHT + turn_offset) << 12) | (capture << 16) | CAPTURE << 20) + captured = que + opp_offset + captures.append(to_sq | (nht_sq << 6) | ((nht + turn_offset) << 12) | (captured << 16) | capture << 20) else: - moves.append(to_sq | (nht_sq << 6) | ((NHT + turn_offset) << 12) | (NO_PIECE << 16) | QUIET << 20) + moves.append(to_sq | (nht_sq << 6) | ((nht + turn_offset) << 12) | (no_piece << 16) | quiet << 20) # endregion # region --- Pawn Moves --- - paw_bb = bbs[PAW + turn_offset] + paw_bb = bbs[paw + turn_offset] while paw_bb: paw_sq = (paw_bb & -paw_bb).bit_length() - 1 paw_bb &= (paw_bb -1) - paw_attacks = PAW_ATTACKS[paw_sq + turn_offset] + paw_attacks = paw_attacks_list[paw_sq + turn_offset] # Irgendwann noch En Passant einfügen paw_attacks &= opponent_pcs while paw_attacks: - flag = CAPTURE + flag = capture to_sq = (paw_attacks & -paw_attacks).bit_length() - 1 to_mask = 1 << to_sq paw_attacks &= (paw_attacks - 1) - if to_mask & bbs[PAW + opp_offset]: - capture = PAW + opp_offset - elif to_mask & bbs[NHT + opp_offset]: - capture = NHT + opp_offset - elif to_mask & bbs[BIS + opp_offset]: - capture = BIS + opp_offset - elif to_mask & bbs[ROO + opp_offset]: - capture = ROO + opp_offset + if to_mask & bbs[paw + opp_offset]: + captured = paw + opp_offset + elif to_mask & bbs[nht + opp_offset]: + captured = nht + opp_offset + elif to_mask & bbs[bis + opp_offset]: + captured = bis + opp_offset + elif to_mask & bbs[roo + opp_offset]: + captured = roo + opp_offset else: - capture = QUE + opp_offset - captures.append(to_sq | (paw_sq << 6) | ((PAW + turn_offset) << 12) | (capture << 16) | flag << 20) + captured = que + opp_offset + captures.append(to_sq | (paw_sq << 6) | ((paw + turn_offset) << 12) | (captured << 16) | flag << 20) if turn == 0: to_sq = paw_sq + 8 to_mask = 1 << to_sq if not to_mask & occupancy: - moves.append(to_sq | (paw_sq << 6) | ((PAW + turn_offset) << 12) | (NO_PIECE << 16) | QUIET << 20) + moves.append(to_sq | (paw_sq << 6) | ((paw + turn_offset) << 12) | (no_piece << 16) | quiet << 20) if 8 <= paw_sq <= 15: to_sq_push = paw_sq + 16 to_mask_push = 1 << to_sq_push if not to_mask_push & occupancy: - moves.append(to_sq_push | (paw_sq << 6) | ((PAW + turn_offset) << 12) | (NO_PIECE << 16) | DOUBLE_PAWN_PUSH << 20) + moves.append(to_sq_push | (paw_sq << 6) | ((paw + turn_offset) << 12) | (no_piece << 16) | dpp << 20) else: to_sq = paw_sq - 8 to_mask = 1 << to_sq if not to_mask & occupancy: - moves.append(to_sq | (paw_sq << 6) | ((PAW + turn_offset) << 12) | (NO_PIECE << 16) | QUIET << 20) + moves.append(to_sq | (paw_sq << 6) | ((paw + turn_offset) << 12) | (no_piece << 16) | quiet << 20) if 48 <= paw_sq <= 55: to_sq_push = paw_sq - 16 to_mask_push = 1 << to_sq_push if not to_mask_push & occupancy: - moves.append(to_sq_push | (paw_sq << 6) | ((PAW + turn_offset) << 12) | (NO_PIECE << 16) | DOUBLE_PAWN_PUSH << 20) + moves.append(to_sq_push | (paw_sq << 6) | ((paw + turn_offset) << 12) | (no_piece << 16) | dpp << 20) # endregion Pawn Moves # region --- Bishop Moves --- - bis_bb = bbs[BIS + turn_offset] + bis_bb = bbs[bis + turn_offset] while bis_bb: bis_sq = (bis_bb & -bis_bb).bit_length() - 1 bis_bb &= (bis_bb - 1) # region North-East - ray = RAYS_NE[bis_sq] + ray = rays_ne[bis_sq] blockers = ray & occupancy if blockers: blocker_sq = (blockers & -blockers).bit_length() - 1 - ray_to_del = RAYS_NE[blocker_sq] + ray_to_del = rays_ne[blocker_sq] bis_attacks = (ray ^ ray_to_del) & ~friendly_pcs else: bis_attacks = ray @@ -246,27 +236,27 @@ class Bitboard(): bis_attacks &= (bis_attacks - 1) if to_mask & opponent_pcs: - if to_mask & bbs[PAW + opp_offset]: - capture = PAW + opp_offset - elif to_mask & bbs[NHT + opp_offset]: - capture = NHT + opp_offset - elif to_mask & bbs[BIS + opp_offset]: - capture = BIS + opp_offset - elif to_mask & bbs[ROO + opp_offset]: - capture = ROO + opp_offset + if to_mask & bbs[paw + opp_offset]: + captured = paw + opp_offset + elif to_mask & bbs[nht + opp_offset]: + captured = nht + opp_offset + elif to_mask & bbs[bis + opp_offset]: + captured = bis + opp_offset + elif to_mask & bbs[roo + opp_offset]: + captured = roo + opp_offset else: - capture = QUE + opp_offset - captures.append(to_sq | (bis_sq << 6) | ((BIS + turn_offset) << 12) | (capture << 16) | CAPTURE << 20) + captured = que + opp_offset + captures.append(to_sq | (bis_sq << 6) | ((bis + turn_offset) << 12) | (captured << 16) | capture << 20) else: - moves.append(to_sq | (bis_sq << 6) | ((BIS + turn_offset) << 12) | (NO_PIECE << 16) | QUIET << 20) + moves.append(to_sq | (bis_sq << 6) | ((bis + turn_offset) << 12) | (no_piece << 16) | quiet << 20) # endregion # region North-West - ray = RAYS_NW[bis_sq] + ray = rays_nw[bis_sq] blockers = ray & occupancy if blockers: blocker_sq = (blockers & -blockers).bit_length() - 1 - ray_to_del = RAYS_NW[blocker_sq] + ray_to_del = rays_nw[blocker_sq] bis_attacks = (ray ^ ray_to_del) & ~friendly_pcs else: bis_attacks = ray @@ -277,27 +267,27 @@ class Bitboard(): bis_attacks &= (bis_attacks - 1) if to_mask & opponent_pcs: - if to_mask & bbs[PAW + opp_offset]: - capture = PAW + opp_offset - elif to_mask & bbs[NHT + opp_offset]: - capture = NHT + opp_offset - elif to_mask & bbs[BIS + opp_offset]: - capture = BIS + opp_offset - elif to_mask & bbs[ROO + opp_offset]: - capture = ROO + opp_offset + if to_mask & bbs[paw + opp_offset]: + captured = paw + opp_offset + elif to_mask & bbs[nht + opp_offset]: + captured = nht + opp_offset + elif to_mask & bbs[bis + opp_offset]: + captured = bis + opp_offset + elif to_mask & bbs[roo + opp_offset]: + captured = roo + opp_offset else: - capture = QUE + opp_offset - captures.append(to_sq | (bis_sq << 6) | ((BIS + turn_offset) << 12) | (capture << 16) | CAPTURE << 20) + captured = que + opp_offset + captures.append(to_sq | (bis_sq << 6) | ((bis + turn_offset) << 12) | (captured << 16) | capture << 20) else: - moves.append(to_sq | (bis_sq << 6) | ((BIS + turn_offset) << 12) | (NO_PIECE << 16) | QUIET << 20) + moves.append(to_sq | (bis_sq << 6) | ((bis + turn_offset) << 12) | (no_piece << 16) | quiet << 20) # endregion # region South-East - ray = RAYS_SE[bis_sq] + ray = rays_se[bis_sq] blockers = ray & occupancy if blockers: blocker_sq = blockers.bit_length() - 1 - ray_to_del = RAYS_SE[blocker_sq] + ray_to_del = rays_se[blocker_sq] bis_attacks = (ray ^ ray_to_del) & ~friendly_pcs else: bis_attacks = ray @@ -308,27 +298,27 @@ class Bitboard(): bis_attacks &= (bis_attacks - 1) if to_mask & opponent_pcs: - if to_mask & bbs[PAW + opp_offset]: - capture = PAW + opp_offset - elif to_mask & bbs[NHT + opp_offset]: - capture = NHT + opp_offset - elif to_mask & bbs[BIS + opp_offset]: - capture = BIS + opp_offset - elif to_mask & bbs[ROO + opp_offset]: - capture = ROO + opp_offset + if to_mask & bbs[paw + opp_offset]: + captured = paw + opp_offset + elif to_mask & bbs[nht + opp_offset]: + captured = nht + opp_offset + elif to_mask & bbs[bis + opp_offset]: + captured = bis + opp_offset + elif to_mask & bbs[roo + opp_offset]: + captured = roo + opp_offset else: - capture = QUE + opp_offset - captures.append(to_sq | (bis_sq << 6) | ((BIS + turn_offset) << 12) | (capture << 16) | CAPTURE << 20) + captured = que + opp_offset + captures.append(to_sq | (bis_sq << 6) | ((bis + turn_offset) << 12) | (captured << 16) | capture << 20) else: - moves.append(to_sq | (bis_sq << 6) | ((BIS + turn_offset) << 12) | (NO_PIECE << 16) | QUIET << 20) + moves.append(to_sq | (bis_sq << 6) | ((bis + turn_offset) << 12) | (no_piece << 16) | quiet << 20) # endregion # region South-West - ray = RAYS_SW[bis_sq] + ray = rays_sw[bis_sq] blockers = ray & occupancy if blockers: blocker_sq = blockers.bit_length() - 1 - ray_to_del = RAYS_SW[blocker_sq] + ray_to_del = rays_sw[blocker_sq] bis_attacks = (ray ^ ray_to_del) & ~friendly_pcs else: bis_attacks = ray @@ -339,26 +329,25 @@ class Bitboard(): bis_attacks &= (bis_attacks - 1) if to_mask & opponent_pcs: - if to_mask & bbs[PAW + opp_offset]: - capture = PAW + opp_offset - elif to_mask & bbs[NHT + opp_offset]: - capture = NHT + opp_offset - elif to_mask & bbs[BIS + opp_offset]: - capture = BIS + opp_offset - elif to_mask & bbs[ROO + opp_offset]: - capture = ROO + opp_offset + if to_mask & bbs[paw + opp_offset]: + captured = paw + opp_offset + elif to_mask & bbs[nht + opp_offset]: + captured = nht + opp_offset + elif to_mask & bbs[bis + opp_offset]: + captured = bis + opp_offset + elif to_mask & bbs[roo + opp_offset]: + captured = roo + opp_offset else: - capture = QUE + opp_offset - captures.append(to_sq | (bis_sq << 6) | ((BIS + turn_offset) << 12) | (capture << 16) | CAPTURE << 20) + captured = que + opp_offset + captures.append(to_sq | (bis_sq << 6) | ((bis + turn_offset) << 12) | (captured << 16) | capture << 20) else: - moves.append(to_sq | (bis_sq << 6) | ((BIS + turn_offset) << 12) | (NO_PIECE << 16) | QUIET << 20) + moves.append(to_sq | (bis_sq << 6) | ((bis + turn_offset) << 12) | (no_piece << 16) | quiet << 20) # endregion # endregion Bishop Moves - def make_move(self, move): # Setup # 6 Bit (0-5): Target (Index: 0-63) @@ -480,6 +469,17 @@ def initialize(): initialize() board = Bitboard() board.print_board() +board.make_move(1835036) #e2-e4 +board.print_board() +board.make_move(1837347) #(d7-d5) +board.print_board() +board.make_move(4590371) #(exd5 - Capture!) +board.print_board() +board.make_move(4245795) #(Qxd5 - Capture!) +board.print_board() +board.make_move(804882) #(Nc3) +board.print_board() +board.make_move(829216) #(Qa5) ''' Board Index: a b c d e f g h