Advertisement
max2201111

konecne spravne H1, G2 aA HURA

Jul 10th, 2024
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.53 KB | Science | 0 0
  1. import chess
  2. from typing import Iterator, Optional
  3. from chess import Move, BB_ALL, Bitboard, PieceType, Color
  4.  
  5. # Definice nových figur
  6. AMAZON = 7
  7.  
  8. # Rozšíření seznamu PIECE_SYMBOLS
  9. chess.PIECE_SYMBOLS.append('a')
  10.  
  11. class CustomBoard(chess.Board):
  12.     def __init__(self, fen=None):
  13.         self.amazons_white = chess.BB_EMPTY
  14.         self.amazons_black = chess.BB_EMPTY
  15.         super().__init__(None)
  16.         if fen:
  17.             self.set_custom_fen(fen)
  18.         print("Šachovnice inicializována")
  19.         self.debug_amazons()
  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.  
  29.         square = 56
  30.         for c in board_part:
  31.             if c == '/':
  32.                 square -= 16
  33.             elif c.isdigit():
  34.                 square += int(c)
  35.             else:
  36.                 color = chess.WHITE if c.isupper() else chess.BLACK
  37.                 if c.upper() == 'A':
  38.                     if color == chess.WHITE:
  39.                         self.amazons_white |= chess.BB_SQUARES[square]
  40.                     else:
  41.                         self.amazons_black |= chess.BB_SQUARES[square]
  42.                     piece_type = AMAZON
  43.                 else:
  44.                     piece_type = chess.PIECE_SYMBOLS.index(c.lower())
  45.                 self._set_piece_at(square, piece_type, color)
  46.                 square += 1
  47.  
  48.         self.turn = chess.WHITE if parts[1] == 'w' else chess.BLACK
  49.         self.castling_rights = chess.BB_EMPTY
  50.         if '-' not in parts[2]:
  51.             if 'K' in parts[2]: self.castling_rights |= chess.BB_H1
  52.             if 'Q' in parts[2]: self.castling_rights |= chess.BB_A1
  53.             if 'k' in parts[2]: self.castling_rights |= chess.BB_H8
  54.             if 'q' in parts[2]: self.castling_rights |= chess.BB_A8
  55.         self.ep_square = chess.parse_square(parts[3]) if parts[3] != '-' else None
  56.         self.halfmove_clock = int(parts[4])
  57.         self.fullmove_number = int(parts[5])
  58.  
  59.     def _set_piece_at(self, square: chess.Square, piece_type: PieceType, color: Color) -> None:
  60.         super()._set_piece_at(square, piece_type, color)
  61.         if piece_type == AMAZON:
  62.             if color == chess.WHITE:
  63.                 self.amazons_white |= chess.BB_SQUARES[square]
  64.             else:
  65.                 self.amazons_black |= chess.BB_SQUARES[square]
  66.         else:
  67.             self.amazons_white &= ~chess.BB_SQUARES[square]
  68.             self.amazons_black &= ~chess.BB_SQUARES[square]
  69.  
  70.     def piece_at(self, square: chess.Square) -> Optional[chess.Piece]:
  71.         if self.amazons_white & chess.BB_SQUARES[square]:
  72.             return chess.Piece(AMAZON, chess.WHITE)
  73.         elif self.amazons_black & chess.BB_SQUARES[square]:
  74.             return chess.Piece(AMAZON, chess.BLACK)
  75.         return super().piece_at(square)
  76.  
  77.     def generate_pseudo_legal_moves(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboard = BB_ALL) -> Iterator[Move]:
  78.         our_pieces = self.occupied_co[self.turn]
  79.         if self.turn == chess.WHITE:
  80.             our_amazons = self.amazons_white
  81.         else:
  82.             our_amazons = self.amazons_black
  83.  
  84.         for from_square in chess.scan_forward(our_amazons & from_mask):
  85.             attacks = self.amazon_attacks(from_square)
  86.             valid_moves = attacks & ~our_pieces & to_mask
  87.             for to_square in chess.scan_forward(valid_moves):
  88.                 yield Move(from_square, to_square)
  89.  
  90.         for move in super().generate_pseudo_legal_moves(from_mask, to_mask):
  91.             if self.piece_type_at(move.from_square) != AMAZON:
  92.                 yield move
  93.  
  94.     def amazon_attacks(self, square):
  95.         return self.queen_attacks(square) | chess.BB_KNIGHT_ATTACKS[square]
  96.  
  97.     def queen_attacks(self, square):
  98.         return self.bishop_attacks(square) | self.rook_attacks(square)
  99.  
  100.     def bishop_attacks(self, square):
  101.         return chess.BB_DIAG_ATTACKS[square][self.occupied & chess.BB_DIAG_MASKS[square]]
  102.  
  103.     def rook_attacks(self, square):
  104.         return (chess.BB_RANK_ATTACKS[square][self.occupied & chess.BB_RANK_MASKS[square]] |
  105.                 chess.BB_FILE_ATTACKS[square][self.occupied & chess.BB_FILE_MASKS[square]])
  106.  
  107.     def is_pseudo_legal(self, move):
  108.         from_square = move.from_square
  109.         to_square = move.to_square
  110.         piece = self.piece_at(from_square)
  111.        
  112.         if not piece or piece.color != self.turn:
  113.             return False
  114.  
  115.         if self.occupied_co[self.turn] & chess.BB_SQUARES[to_square]:
  116.             return False
  117.  
  118.         if self.is_castling(move):
  119.             return True
  120.  
  121.         if piece.piece_type == AMAZON:
  122.             return bool(self.amazon_attacks(from_square) & chess.BB_SQUARES[to_square])
  123.         else:
  124.             return super().is_pseudo_legal(move)
  125.  
  126.     def is_legal(self, move):
  127.         print(f"Kontrola legality tahu: {move}")
  128.         if not self.is_pseudo_legal(move):
  129.             return False
  130.  
  131.         from_square = move.from_square
  132.         to_square = move.to_square
  133.         piece = self.piece_at(from_square)
  134.         captured_piece = self.piece_at(to_square)
  135.  
  136.         self._remove_piece_at(from_square)
  137.         self._set_piece_at(to_square, piece.piece_type, piece.color)
  138.  
  139.         king_square = to_square if piece.piece_type == chess.KING else self.king(self.turn)
  140.         is_check, attacker_square = self._is_attacked_by(not self.turn, king_square)
  141.  
  142.         self._remove_piece_at(to_square)
  143.         self._set_piece_at(from_square, piece.piece_type, piece.color)
  144.         if captured_piece:
  145.             self._set_piece_at(to_square, captured_piece.piece_type, captured_piece.color)
  146.  
  147.         if is_check:
  148.             attacking_piece = self.piece_at(attacker_square)
  149.             print(f"Tah {move} staví vlastního krále do šachu od figury {self.piece_symbol(attacking_piece)} na {chess.SQUARE_NAMES[attacker_square]}")
  150.         return not is_check
  151.  
  152.     def _is_attacked_by(self, color, square):
  153.         print(f"Kontrola útoku na pole {chess.SQUARE_NAMES[square]} od barvy {'bílé' if color == chess.WHITE else 'černé'}")
  154.         attackers = self.attackers(color, square)
  155.         if attackers:
  156.             for attacker_square in chess.scan_forward(attackers):
  157.                 piece = self.piece_at(attacker_square)
  158.                 attacker_color = "bílá" if piece.color == chess.WHITE else "černá"
  159.                 print(f"Figura {self.piece_symbol(piece)} ({attacker_color}) na {chess.SQUARE_NAMES[attacker_square]} útočí na {chess.SQUARE_NAMES[square]}")
  160.                 return True, attacker_square
  161.         print(f"Žádný útok na pole {chess.SQUARE_NAMES[square]} nebyl nalezen")
  162.         return False, None
  163.  
  164.     def attackers(self, color, square):
  165.         attackers = chess.BB_EMPTY
  166.        
  167.         knights = self.knights & self.occupied_co[color]
  168.         attackers |= knights & chess.BB_KNIGHT_ATTACKS[square]
  169.        
  170.         king = self.kings & self.occupied_co[color]
  171.         attackers |= king & chess.BB_KING_ATTACKS[square]
  172.        
  173.         pawns = self.pawns & self.occupied_co[color]
  174.         if color == chess.WHITE:
  175.             attackers |= pawns & chess.BB_PAWN_ATTACKS[chess.BLACK][square]
  176.         else:
  177.             attackers |= pawns & chess.BB_PAWN_ATTACKS[chess.WHITE][square]
  178.        
  179.         queens = self.queens & self.occupied_co[color]
  180.         bishops = (self.bishops | queens) & self.occupied_co[color]
  181.         rooks = (self.rooks | queens) & self.occupied_co[color]
  182.        
  183.         attackers |= chess.BB_DIAG_ATTACKS[square][self.occupied & chess.BB_DIAG_MASKS[square]] & bishops
  184.         attackers |= (chess.BB_RANK_ATTACKS[square][self.occupied & chess.BB_RANK_MASKS[square]] |
  185.                       chess.BB_FILE_ATTACKS[square][self.occupied & chess.BB_FILE_MASKS[square]]) & rooks
  186.        
  187.         # Kontrola útoků amazonek
  188.         amazons = self.amazons_white if color == chess.WHITE else self.amazons_black
  189.         for amazon_square in chess.scan_forward(amazons):
  190.             if self.amazon_attacks(amazon_square) & chess.BB_SQUARES[square]:
  191.                 attackers |= chess.BB_SQUARES[amazon_square]
  192.        
  193.         return attackers
  194.  
  195.     def push(self, move):
  196.         if not self.is_legal(move):
  197.             raise ValueError(f"Move {move} is not legal in position {self.fen()}")
  198.  
  199.         piece = self.piece_at(move.from_square)
  200.         captured_piece = self.piece_at(move.to_square)
  201.  
  202.         self._remove_piece_at(move.from_square)
  203.         self._set_piece_at(move.to_square, piece.piece_type, piece.color)
  204.  
  205.         if piece.piece_type == AMAZON:
  206.             if piece.color == chess.WHITE:
  207.                 self.amazons_white &= ~chess.BB_SQUARES[move.from_square]
  208.                 self.amazons_white |= chess.BB_SQUARES[move.to_square]
  209.             else:
  210.                 self.amazons_black &= ~chess.BB_SQUARES[move.from_square]
  211.                 self.amazons_black |= chess.BB_SQUARES[move.to_square]
  212.  
  213.         self.turn = not self.turn
  214.         self.fullmove_number += 1 if self.turn == chess.WHITE else 0
  215.         self.halfmove_clock += 1
  216.  
  217.         if captured_piece or piece.piece_type == chess.PAWN:
  218.             self.halfmove_clock = 0
  219.  
  220.         self.move_stack.append(move)
  221.  
  222.     def pop(self):
  223.         if not self.move_stack:
  224.             return None
  225.  
  226.         move = self.move_stack.pop()
  227.  
  228.         piece = self.piece_at(move.to_square)
  229.         self._remove_piece_at(move.to_square)
  230.         self._set_piece_at(move.from_square, piece.piece_type, piece.color)
  231.  
  232.         if piece.piece_type == AMAZON:
  233.             if piece.color == chess.WHITE:
  234.                 self.amazons_white &= ~chess.BB_SQUARES[move.to_square]
  235.                 self.amazons_white |= chess.BB_SQUARES[move.from_square]
  236.             else:
  237.                 self.amazons_black &= ~chess.BB_SQUARES[move.to_square]
  238.                 self.amazons_black |= chess.BB_SQUARES[move.from_square]
  239.  
  240.         captured_piece = self.piece_at(move.to_square)
  241.         if captured_piece:
  242.             self._set_piece_at(move.to_square, captured_piece.piece_type, captured_piece.color)
  243.  
  244.         self.turn = not self.turn
  245.         self.fullmove_number -= 1 if self.turn == chess.BLACK else 0
  246.  
  247.         return move
  248.  
  249.     def is_check(self):
  250.         king_square = self.king(self.turn)
  251.         if king_square is None:
  252.             return False
  253.         return self._is_attacked_by(not self.turn, king_square)[0]
  254.  
  255.     def debug_amazons(self):
  256.         print(f"Bitboard bílých amazonek: {format(self.amazons_white, '064b')}")
  257.         print(f"Bitboard černých amazonek: {format(self.amazons_black, '064b')}")
  258.         for square in chess.SQUARES:
  259.             if self.amazons_white & chess.BB_SQUARES[square]:
  260.                 print(f"Bílá amazonka na {chess.SQUARE_NAMES[square]}")
  261.             if self.amazons_black & chess.BB_SQUARES[square]:
  262.                 print(f"Černá amazonka na {chess.SQUARE_NAMES[square]}")
  263.  
  264.     def piece_symbol(self, piece):
  265.         if piece is None:
  266.             return '.'
  267.         if piece.piece_type == AMAZON:
  268.             return 'A' if piece.color == chess.WHITE else 'a'
  269.         return piece.symbol()
  270.  
  271.     def piece_type_at(self, square):
  272.         if (self.amazons_white | self.amazons_black) & chess.BB_SQUARES[square]:
  273.             return AMAZON
  274.         return super().piece_type_at(square)
  275.  
  276.     def color_at(self, square):
  277.         if self.amazons_white & chess.BB_SQUARES[square]:
  278.             return chess.WHITE
  279.         if self.amazons_black & chess.BB_SQUARES[square]:
  280.             return chess.BLACK
  281.         return super().color_at(square)
  282.  
  283.     @property
  284.     def legal_moves(self):
  285.         return [move for move in self.generate_pseudo_legal_moves() if self.is_legal(move)]
  286.  
  287.     def __str__(self):
  288.         builder = []
  289.         for square in chess.SQUARES_180:
  290.             piece = self.piece_at(square)
  291.             symbol = self.piece_symbol(piece) if piece else '.'
  292.             builder.append(symbol)
  293.             if chess.square_file(square) == 7:
  294.                 if square != chess.H1:
  295.                     builder.append('\n')
  296.         return ''.join(builder)
  297.  
  298. if __name__ == "__main__":
  299.     start_fen = "a7/3k4/8/8/1B6/8/A7/6K1 w - - 0 1"
  300.  
  301.     print(f"Vytváření šachovnice s FEN: {start_fen}")
  302.     board = CustomBoard(start_fen)
  303.  
  304.     print("Současná pozice:")
  305.     print(board)
  306.  
  307.     print("Generování legálních tahů pro počáteční pozici...")
  308.     legal_moves = list(board.legal_moves)
  309.     print(f"Počet legálních tahů: {len(legal_moves)}")
  310.  
  311.     print("Legální tahy:")
  312.     for move in legal_moves:
  313.         from_square = chess.SQUARE_NAMES[move.from_square]
  314.         to_square = chess.SQUARE_NAMES[move.to_square]
  315.         piece = board.piece_at(move.from_square)
  316.         print(f"{board.piece_symbol(piece)}: {from_square}-{to_square}")
  317.  
  318.     # Test tahu bílého krále z G1 na H1
  319.     test_move = chess.Move.from_uci("g1h1")
  320.     is_legal = board.is_legal(test_move)
  321.     print(f"Je tah g1h1 legální? {'Ano' if is_legal else 'Ne'}")
  322.  
  323.     # for square in [chess.H1, chess.G2]:
  324.     #     attackers = board.attackers(chess.BLACK, square)
  325.     #     if attackers:
  326.     #         for attacker_square in chess.scan_forward(attackers):
  327.     #             piece = board.piece_at(attacker_square)
  328.     #             print(f"Pole {chess.SQUARE_NAMES[square]} je napadeno figurou {board.piece_symbol(piece)} ({'bílá' if piece.color == chess.WHITE else 'černá'}) z pole {chess.SQUARE_NAMES[attacker_square]}")
  329.     #     else:
  330.     #         print(f"Pole {chess.SQUARE_NAMES[square]} není napadeno žádnou černou figurou")
  331.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement