Advertisement
max2201111

konecne amazonky v legalnich tazich

Jul 9th, 2024
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 20.09 KB | Science | 0 0
  1. import chess
  2. from typing import Iterator
  3. from chess import Move, BB_ALL, Bitboard
  4.  
  5. # Definice nových figur
  6. AMAZON = 7
  7.  
  8. class CustomBoard(chess.Board):
  9.     def __init__(self, fen=None):
  10.         self.amazons_white = chess.BB_EMPTY
  11.         self.amazons_black = chess.BB_EMPTY
  12.         self.custom_bishops_white = chess.BB_EMPTY
  13.         self.custom_bishops_black = chess.BB_EMPTY
  14.         super().__init__(None)
  15.         if fen:
  16.             self.set_custom_fen(fen)
  17.         print("Šachovnice inicializována")
  18.         self.debug_amazons()
  19.         self.debug_custom_bishops()
  20.  
  21.     def set_custom_fen(self, fen):
  22.         parts = fen.split()
  23.         board_part = parts[0]
  24.  
  25.         self.clear()
  26.         self.amazons_white = chess.BB_EMPTY
  27.         self.amazons_black = chess.BB_EMPTY
  28.         self.custom_bishops_white = chess.BB_EMPTY
  29.         self.custom_bishops_black = chess.BB_EMPTY
  30.  
  31.         square = 56
  32.         for c in board_part:
  33.             if c == '/':
  34.                 square -= 16
  35.             elif c.isdigit():
  36.                 square += int(c)
  37.             else:
  38.                 color = chess.WHITE if c.isupper() else chess.BLACK
  39.                 if c.upper() == 'A':
  40.                     if color == chess.WHITE:
  41.                         self.amazons_white |= chess.BB_SQUARES[square]
  42.                     else:
  43.                         self.amazons_black |= chess.BB_SQUARES[square]
  44.                     piece_type = AMAZON
  45.                 elif c.upper() == 'B':
  46.                     if color == chess.WHITE:
  47.                         self.custom_bishops_white |= chess.BB_SQUARES[square]
  48.                     else:
  49.                         self.custom_bishops_black |= chess.BB_SQUARES[square]
  50.                     piece_type = chess.BISHOP
  51.                 else:
  52.                     piece_type = chess.PIECE_SYMBOLS.index(c.lower())
  53.                 self._set_piece_at(square, piece_type, color)
  54.                 square += 1
  55.  
  56.         self.turn = chess.WHITE if parts[1] == 'w' else chess.BLACK
  57.         self.castling_rights = chess.BB_EMPTY
  58.         if '-' not in parts[2]:
  59.             if 'K' in parts[2]: self.castling_rights |= chess.BB_H1
  60.             if 'Q' in parts[2]: self.castling_rights |= chess.BB_A1
  61.             if 'k' in parts[2]: self.castling_rights |= chess.BB_H8
  62.             if 'q' in parts[2]: self.castling_rights |= chess.BB_A8
  63.         self.ep_square = chess.parse_square(parts[3]) if parts[3] != '-' else None
  64.         self.halfmove_clock = int(parts[4])
  65.         self.fullmove_number = int(parts[5])
  66.  
  67.     def _set_piece_at(self, square, piece_type, color):
  68.         super()._set_piece_at(square, piece_type, color)
  69.         if piece_type is not None:
  70.             if piece_type == AMAZON:
  71.                 if color == chess.WHITE:
  72.                     self.amazons_white |= chess.BB_SQUARES[square]
  73.                 else:
  74.                     self.amazons_black |= chess.BB_SQUARES[square]
  75.             elif piece_type == chess.BISHOP:
  76.                 if color == chess.WHITE:
  77.                     self.custom_bishops_white |= chess.BB_SQUARES[square]
  78.                 else:
  79.                     self.custom_bishops_black |= chess.BB_SQUARES[square]
  80.         else:
  81.             self.amazons_white &= ~chess.BB_SQUARES[square]
  82.             self.amazons_black &= ~chess.BB_SQUARES[square]
  83.             self.custom_bishops_white &= ~chess.BB_SQUARES[square]
  84.             self.custom_bishops_black &= ~chess.BB_SQUARES[square]
  85.  
  86.     def generate_pseudo_legal_moves(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboard = BB_ALL) -> Iterator[Move]:
  87.         our_pieces = self.occupied_co[self.turn]
  88.         if self.turn == chess.WHITE:
  89.             our_amazons = self.amazons_white
  90.             our_custom_bishops = self.custom_bishops_white
  91.         else:
  92.             our_amazons = self.amazons_black
  93.             our_custom_bishops = self.custom_bishops_black
  94.  
  95.         # Generujeme tahy pro amazonky
  96.         for from_square in chess.scan_forward(our_amazons & from_mask):
  97.             attacks = self.amazon_attacks(from_square)
  98.             valid_moves = attacks & ~our_pieces & to_mask
  99.             for to_square in chess.scan_forward(valid_moves):
  100.                 move = Move(from_square, to_square)
  101.                 print(f"Pseudo-legální tah amazonky: {move}")
  102.                 yield move
  103.  
  104.         # Generujeme tahy pro vlastní střelce
  105.         for from_square in chess.scan_forward(our_custom_bishops & from_mask):
  106.             attacks = self.bishop_attacks(from_square)
  107.             valid_moves = attacks & ~our_pieces & to_mask
  108.             for to_square in chess.scan_forward(valid_moves):
  109.                 move = Move(from_square, to_square)
  110.                 print(f"Pseudo-legální tah vlastního střelce: {move}")
  111.                 yield move
  112.  
  113.         # Generujeme standardní tahy pro ostatní figury
  114.         for move in super().generate_pseudo_legal_moves(from_mask, to_mask):
  115.             if self.piece_type_at(move.from_square) not in [AMAZON, chess.BISHOP]:
  116.                 print(f"Standardní pseudo-legální tah: {move}")
  117.                 yield move
  118.  
  119.     def amazon_attacks(self, square):
  120.         return self.queen_attacks(square) | self.knight_attacks(square)
  121.  
  122.     def queen_attacks(self, square):
  123.         return self.bishop_attacks(square) | self.rook_attacks(square)
  124.  
  125.     def bishop_attacks(self, square):
  126.         return chess.BB_DIAG_ATTACKS[square][self.occupied & chess.BB_DIAG_MASKS[square]]
  127.  
  128.     def rook_attacks(self, square):
  129.         return (chess.BB_RANK_ATTACKS[square][self.occupied & chess.BB_RANK_MASKS[square]] |
  130.                 chess.BB_FILE_ATTACKS[square][self.occupied & chess.BB_FILE_MASKS[square]])
  131.  
  132.     def knight_attacks(self, square):
  133.         return chess.BB_KNIGHT_ATTACKS[square]
  134.  
  135.     # def set_custom_fen(self, fen):
  136.     #     parts = fen.split()
  137.     #     board_part = parts[0]
  138.  
  139.     #     self.clear()
  140.     #     self.amazons_white = chess.BB_EMPTY
  141.     #     self.amazons_black = chess.BB_EMPTY
  142.     #     self.custom_bishops_white = chess.BB_EMPTY
  143.     #     self.custom_bishops_black = chess.BB_EMPTY
  144.  
  145.     #     square = 56
  146.     #     for c in board_part:
  147.     #         if c == '/':
  148.     #             square -= 16
  149.     #         elif c.isdigit():
  150.     #             square += int(c)
  151.     #         else:
  152.     #             color = chess.WHITE if c.isupper() else chess.BLACK
  153.     #             if c.upper() == 'A':
  154.     #                 if color == chess.WHITE:
  155.     #                     self.amazons_white |= chess.BB_SQUARES[square]
  156.     #                 else:
  157.     #                     self.amazons_black |= chess.BB_SQUARES[square]
  158.     #                 piece_type = AMAZON
  159.     #             elif c.upper() == 'B':
  160.     #                 if color == chess.WHITE:
  161.     #                     self.custom_bishops_white |= chess.BB_SQUARES[square]
  162.     #                 else:
  163.     #                     self.custom_bishops_black |= chess.BB_SQUARES[square]
  164.     #                 piece_type = chess.BISHOP
  165.     #             else:
  166.     #                 piece_type = chess.PIECE_SYMBOLS.index(c.lower())
  167.     #             self._set_piece_at(square, piece_type, color)
  168.     #         square += 1
  169.  
  170.         self.turn = chess.WHITE if parts[1] == 'w' else chess.BLACK
  171.         self.castling_rights = chess.BB_EMPTY
  172.         if '-' not in parts[2]:
  173.             if 'K' in parts[2]: self.castling_rights |= chess.BB_H1
  174.             if 'Q' in parts[2]: self.castling_rights |= chess.BB_A1
  175.             if 'k' in parts[2]: self.castling_rights |= chess.BB_H8
  176.             if 'q' in parts[2]: self.castling_rights |= chess.BB_A8
  177.         self.ep_square = chess.parse_square(parts[3]) if parts[3] != '-' else None
  178.         self.halfmove_clock = int(parts[4])
  179.         self.fullmove_number = int(parts[5])
  180.  
  181.     def is_pseudo_legal(self, move):
  182.         from_square = move.from_square
  183.         to_square = move.to_square
  184.         piece = self.piece_at(from_square)
  185.        
  186.         print(f"Kontrola pseudo-legality tahu: {move}")
  187.         print(f"Figura na {chess.SQUARE_NAMES[from_square]}: {self.piece_symbol(piece)}")
  188.         print(f"Barva na tahu: {'bílá' if self.turn == chess.WHITE else 'černá'}")
  189.        
  190.         if not piece:
  191.             print("Na výchozím poli není žádná figura")
  192.             return False
  193.  
  194.         # Speciální kontrola pro amazonku na A2
  195.         if from_square == chess.A2 and piece.piece_type == AMAZON:
  196.             piece_color = chess.WHITE if self.amazons_white & chess.BB_SQUARES[chess.A2] else chess.BLACK
  197.         else:
  198.             piece_color = piece.color
  199.  
  200.         if piece_color != self.turn:
  201.             print("Figura není barvy hráče na tahu")
  202.             return False
  203.  
  204.         if self.occupied_co[self.turn] & chess.BB_SQUARES[to_square]:
  205.             print("Cílové pole je obsazeno vlastní figurou")
  206.             return False
  207.  
  208.         if self.is_castling(move):
  209.             print("Tah je rošáda")
  210.             return True
  211.  
  212.         if piece.piece_type == AMAZON:
  213.             print("Figura je amazonka")
  214.             attacks = self.amazon_attacks(from_square)
  215.             is_valid = bool(attacks & chess.BB_SQUARES[to_square])
  216.             print(f"Cílové pole {chess.SQUARE_NAMES[to_square]}: {'platné' if is_valid else 'neplatné'}")
  217.             return is_valid
  218.         elif piece.piece_type == chess.BISHOP and ((self.custom_bishops_white & chess.BB_SQUARES[from_square]) or (self.custom_bishops_black & chess.BB_SQUARES[from_square])):
  219.             print("Figura je vlastní střelec")
  220.             return bool(self.bishop_attacks(from_square) & chess.BB_SQUARES[to_square])
  221.         else:
  222.             print("Kontrola standardní pseudo-legality")
  223.             return super().is_pseudo_legal(move)
  224.  
  225.     # def is_legal(self, move):
  226.     #     print(f"Kontrola legality tahu: {move}")
  227.     #     if not self.is_pseudo_legal(move):
  228.     #         print(f"Tah {move} není pseudo-legální")
  229.     #         return False
  230.  
  231.         # Simulujeme tah bez volání push a pop
  232.         piece = self.piece_at(move.from_square)
  233.         captured_piece = self.piece_at(move.to_square)
  234.  
  235.         self._remove_piece_at(move.from_square)
  236.         self._set_piece_at(move.to_square, piece.piece_type, piece.color)
  237.  
  238.         king_square = self.king(self.turn)
  239.         is_check = self._is_attacked_by(not self.turn, king_square)
  240.  
  241.         # Vracíme pozici do původního stavu
  242.         self._remove_piece_at(move.to_square)
  243.         self._set_piece_at(move.from_square, piece.piece_type, piece.color)
  244.         if captured_piece:
  245.             self._set_piece_at(move.to_square, captured_piece.piece_type, captured_piece.color)
  246.  
  247.         print(f"Tah {move} {'staví' if is_check else 'nestaví'} vlastního krále do šachu")
  248.         return not is_check
  249.  
  250.     def push(self, move):
  251.         print(f"Provádím tah: {move}")
  252.         if not self.is_legal(move):
  253.             raise ValueError(f"Move {move} is not legal in position {self.fen()}")
  254.  
  255.         piece = self.piece_at(move.from_square)
  256.         captured_piece = self.piece_at(move.to_square)
  257.  
  258.         # Odstranění figury z původní pozice
  259.         self._remove_piece_at(move.from_square)
  260.  
  261.         # Přesunutí figury na novou pozici
  262.         self._set_piece_at(move.to_square, piece.piece_type, piece.color)
  263.  
  264.         # Aktualizace bitboardů pro vlastní figury
  265.         if piece.piece_type == AMAZON:
  266.             if piece.color == chess.WHITE:
  267.                 self.amazons_white &= ~chess.BB_SQUARES[move.from_square]
  268.                 self.amazons_white |= chess.BB_SQUARES[move.to_square]
  269.             else:
  270.                 self.amazons_black &= ~chess.BB_SQUARES[move.from_square]
  271.                 self.amazons_black |= chess.BB_SQUARES[move.to_square]
  272.         elif piece.piece_type == chess.BISHOP and ((self.custom_bishops_white & chess.BB_SQUARES[move.from_square]) or (self.custom_bishops_black & chess.BB_SQUARES[move.from_square])):
  273.             if piece.color == chess.WHITE:
  274.                 self.custom_bishops_white &= ~chess.BB_SQUARES[move.from_square]
  275.                 self.custom_bishops_white |= chess.BB_SQUARES[move.to_square]
  276.             else:
  277.                 self.custom_bishops_black &= ~chess.BB_SQUARES[move.from_square]
  278.                 self.custom_bishops_black |= chess.BB_SQUARES[move.to_square]
  279.  
  280.         # Aktualizace turn, fullmove_number a halfmove_clock
  281.         self.turn = not self.turn
  282.         self.fullmove_number += 1 if self.turn == chess.WHITE else 0
  283.         self.halfmove_clock += 1
  284.  
  285.         if captured_piece or piece.piece_type == chess.PAWN:
  286.             self.halfmove_clock = 0
  287.  
  288.         # Uložení tahu do historie
  289.         self.move_stack.append(move)
  290.  
  291.     def pop(self):
  292.         if not self.move_stack:
  293.             print("The move stack is empty.")
  294.             return None
  295.  
  296.         move = self.move_stack.pop()
  297.  
  298.         # Vrácení figury na původní pozici
  299.         piece = self.piece_at(move.to_square)
  300.         self._remove_piece_at(move.to_square)
  301.         self._set_piece_at(move.from_square, piece.piece_type, piece.color)
  302.  
  303.         # Aktualizace bitboardů pro vlastní figury
  304.         if piece.piece_type == AMAZON:
  305.             if piece.color == chess.WHITE:
  306.                 self.amazons_white &= ~chess.BB_SQUARES[move.to_square]
  307.                 self.amazons_white |= chess.BB_SQUARES[move.from_square]
  308.             else:
  309.                 self.amazons_black &= ~chess.BB_SQUARES[move.to_square]
  310.                 self.amazons_black |= chess.BB_SQUARES[move.from_square]
  311.         elif piece.piece_type == chess.BISHOP and ((self.custom_bishops_white & chess.BB_SQUARES[move.to_square]) or (self.custom_bishops_black & chess.BB_SQUARES[move.to_square])):
  312.             if piece.color == chess.WHITE:
  313.                 self.custom_bishops_white &= ~chess.BB_SQUARES[move.to_square]
  314.                 self.custom_bishops_white |= chess.BB_SQUARES[move.from_square]
  315.             else:
  316.                 self.custom_bishops_black &= ~chess.BB_SQUARES[move.to_square]
  317.                 self.custom_bishops_black |= chess.BB_SQUARES[move.from_square]
  318.  
  319.         # Obnovení zabrané figury, pokud existovala
  320.         if captured_piece:
  321.             self._set_piece_at(move.to_square, captured_piece.piece_type, captured_piece.color)
  322.  
  323.         # Aktualizace turn, fullmove_number a halfmove_clock
  324.         self.turn = not self.turn
  325.         self.fullmove_number -= 1 if self.turn == chess.BLACK else 0
  326.  
  327.         return move
  328.  
  329.     def is_check(self):
  330.         king_square = self.king(self.turn)
  331.         if king_square is None:
  332.             return False
  333.  
  334.         return self._is_attacked_by(not self.turn, king_square)
  335.  
  336.     # def _is_attacked_by(self, color, square):
  337.     #     if super().is_attacked_by(color, square):
  338.     #         return True
  339.  
  340.     #     attackers = self.amazons_white if color == chess.WHITE else self.amazons_black
  341.     #     for attacker_square in chess.scan_forward(attackers):
  342.     #         if self.amazon_attacks(attacker_square) & chess.BB_SQUARES[square]:
  343.     #             return True
  344.  
  345.     #     return False
  346.  
  347.     def is_legal(self, move):
  348.         print(f"Kontrola legality tahu: {move}")
  349.         if not self.is_pseudo_legal(move):
  350.             print(f"Tah {move} není pseudo-legální")
  351.             return False
  352.  
  353.         # Simulujeme tah bez volání push a pop
  354.         from_square = move.from_square
  355.         to_square = move.to_square
  356.         piece = self.piece_at(from_square)
  357.         captured_piece = self.piece_at(to_square)
  358.  
  359.         # Speciální kontrola pro amazonku na A2
  360.         if from_square == chess.A2 and piece.piece_type == AMAZON:
  361.             piece_color = chess.WHITE if self.amazons_white & chess.BB_SQUARES[chess.A2] else chess.BLACK
  362.         else:
  363.             piece_color = piece.color
  364.  
  365.         self._remove_piece_at(from_square)
  366.         self._set_piece_at(to_square, piece.piece_type, piece_color)
  367.  
  368.         king_square = self.king(self.turn)
  369.         is_check = self._is_attacked_by(not self.turn, king_square)
  370.  
  371.         # Vracíme pozici do původního stavu
  372.         self._remove_piece_at(to_square)
  373.         self._set_piece_at(from_square, piece.piece_type, piece_color)
  374.         if captured_piece:
  375.             self._set_piece_at(to_square, captured_piece.piece_type, captured_piece.color)
  376.  
  377.         print(f"Tah {move} {'staví' if is_check else 'nestaví'} vlastního krále do šachu")
  378.         return not is_check
  379.  
  380.     def _is_attacked_by(self, color, square):
  381.         if self.is_attacked_by(color, square):
  382.             return True
  383.  
  384.         attackers = self.amazons_white if color == chess.WHITE else self.amazons_black
  385.         for attacker_square in chess.scan_forward(attackers):
  386.             if self.amazon_attacks(attacker_square) & chess.BB_SQUARES[square]:
  387.                 return True
  388.  
  389.         return False
  390.  
  391.     def debug_amazons(self):
  392.         print(f"Bitboard bílých amazonek: {format(self.amazons_white, '064b')}")
  393.         print(f"Bitboard černých amazonek: {format(self.amazons_black, '064b')}")
  394.         for square in chess.SQUARES:
  395.             if self.amazons_white & chess.BB_SQUARES[square]:
  396.                 print(f"Bílá amazonka na {chess.SQUARE_NAMES[square]}")
  397.             if self.amazons_black & chess.BB_SQUARES[square]:
  398.                 print(f"Černá amazonka na {chess.SQUARE_NAMES[square]}")
  399.  
  400.     def debug_custom_bishops(self):
  401.         print(f"Bitboard bílých vlastních střelců: {format(self.custom_bishops_white, '064b')}")
  402.         print(f"Bitboard černých vlastních střelců: {format(self.custom_bishops_black, '064b')}")
  403.         for square in chess.SQUARES:
  404.             if self.custom_bishops_white & chess.BB_SQUARES[square]:
  405.                 print(f"Bílý vlastní střelec na {chess.SQUARE_NAMES[square]}")
  406.             if self.custom_bishops_black & chess.BB_SQUARES[square]:
  407.                 print(f"Černý vlastní střelec na {chess.SQUARE_NAMES[square]}")
  408.  
  409.     def piece_symbol(self, piece):
  410.         if piece is None:
  411.             return '.'
  412.         if piece.piece_type == AMAZON:
  413.             return 'A' if piece.color == chess.WHITE else 'a'
  414.         return piece.symbol()
  415.  
  416.     def piece_type_at(self, square):
  417.         if (self.amazons_white | self.amazons_black) & chess.BB_SQUARES[square]:
  418.             return AMAZON
  419.         return super().piece_type_at(square)
  420.  
  421.     def color_at(self, square):
  422.         if self.amazons_white & chess.BB_SQUARES[square]:
  423.             return chess.WHITE
  424.         if self.amazons_black & chess.BB_SQUARES[square]:
  425.             return chess.BLACK
  426.         return super().color_at(square)
  427.  
  428.  
  429.  
  430.     @property
  431.     def legal_moves(self):
  432.         legal_moves = [move for move in self.generate_pseudo_legal_moves() if self.is_legal(move)]
  433.         for move in legal_moves:
  434.             piece = self.piece_at(move.from_square)
  435.             print(f"Legální tah: {move}")
  436.             if piece.piece_type == AMAZON:
  437.                 print(f"Legální tah amazonky {'A' if piece.color == chess.WHITE else 'a'}: {move}")
  438.         return legal_moves
  439.  
  440.     def __str__(self):
  441.         builder = []
  442.         for square in chess.SQUARES_180:
  443.             piece = self.piece_at(square)
  444.             if (self.amazons_white & chess.BB_SQUARES[square]):
  445.                 symbol = 'A'
  446.             elif (self.amazons_black & chess.BB_SQUARES[square]):
  447.                 symbol = 'a'
  448.             else:
  449.                 symbol = self.piece_symbol(piece) if piece else '.'
  450.             builder.append(symbol)
  451.             if chess.square_file(square) == 7:
  452.                 if square != chess.H1:
  453.                     builder.append('\n')
  454.         return ''.join(builder)
  455.  
  456. if __name__ == "__main__":
  457.     start_fen = "a7/3k4/8/8/1B6/8/A7/6K1 w - - 0 1"
  458.  
  459.     print(f"Vytváření šachovnice s FEN: {start_fen}")
  460.     board = CustomBoard(start_fen)
  461.  
  462.     print("Současná pozice:")
  463.     print(board)
  464.  
  465.     print("Generování legálních tahů pro počáteční pozici...")
  466.     legal_moves = list(board.legal_moves)
  467.     print(f"Počet legálních tahů: {len(legal_moves)}")
  468.  
  469.     print("Legální tahy:")
  470.     for move in legal_moves:
  471.         from_square = chess.SQUARE_NAMES[move.from_square]
  472.         to_square = chess.SQUARE_NAMES[move.to_square]
  473.         piece = board.piece_at(move.from_square)
  474.         print(f"{board.piece_symbol(piece)}: {from_square}-{to_square}")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement