Advertisement
max2201111

KONECNE H1 JE NAPADENO OD A8!!

Jul 10th, 2024
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.41 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.  
  6. # Definice nových figur
  7. AMAZON = 7
  8.  
  9. # Rozšíření seznamu PIECE_SYMBOLS
  10. chess.PIECE_SYMBOLS.append('a')
  11.  
  12. class CustomBoard(chess.Board):
  13.     def __init__(self, fen=None):
  14.         self.amazons_white = chess.BB_EMPTY
  15.         self.amazons_black = chess.BB_EMPTY
  16.         super().__init__(None)
  17.         if fen:
  18.             self.set_custom_fen(fen)
  19.         print("Šachovnice inicializována")
  20.         self.debug_amazons()
  21.  
  22.     def set_custom_fen(self, fen):
  23.         parts = fen.split()
  24.         board_part = parts[0]
  25.  
  26.         self.clear()
  27.         self.amazons_white = chess.BB_EMPTY
  28.         self.amazons_black = chess.BB_EMPTY
  29.  
  30.         square = 56
  31.         for c in board_part:
  32.             if c == '/':
  33.                 square -= 16
  34.             elif c.isdigit():
  35.                 square += int(c)
  36.             else:
  37.                 color = chess.WHITE if c.isupper() else chess.BLACK
  38.                 if c.upper() == 'A':
  39.                     if color == chess.WHITE:
  40.                         self.amazons_white |= chess.BB_SQUARES[square]
  41.                     else:
  42.                         self.amazons_black |= chess.BB_SQUARES[square]
  43.                     piece_type = AMAZON
  44.                 else:
  45.                     piece_type = chess.PIECE_SYMBOLS.index(c.lower())
  46.                 self._set_piece_at(square, piece_type, color)
  47.                 square += 1
  48.  
  49.         self.turn = chess.WHITE if parts[1] == 'w' else chess.BLACK
  50.         self.castling_rights = chess.BB_EMPTY
  51.         if '-' not in parts[2]:
  52.             if 'K' in parts[2]: self.castling_rights |= chess.BB_H1
  53.             if 'Q' in parts[2]: self.castling_rights |= chess.BB_A1
  54.             if 'k' in parts[2]: self.castling_rights |= chess.BB_H8
  55.             if 'q' in parts[2]: self.castling_rights |= chess.BB_A8
  56.         self.ep_square = chess.parse_square(parts[3]) if parts[3] != '-' else None
  57.         self.halfmove_clock = int(parts[4])
  58.         self.fullmove_number = int(parts[5])
  59.  
  60.     def _set_piece_at(self, square: chess.Square, piece_type: PieceType, color: Color) -> None:
  61.         super()._set_piece_at(square, piece_type, color)
  62.         if piece_type == AMAZON:
  63.             if color == chess.WHITE:
  64.                 self.amazons_white |= chess.BB_SQUARES[square]
  65.             else:
  66.                 self.amazons_black |= chess.BB_SQUARES[square]
  67.         else:
  68.             self.amazons_white &= ~chess.BB_SQUARES[square]
  69.             self.amazons_black &= ~chess.BB_SQUARES[square]
  70.  
  71.     def piece_at(self, square: chess.Square) -> Optional[chess.Piece]:
  72.         if self.amazons_white & chess.BB_SQUARES[square]:
  73.             return chess.Piece(AMAZON, chess.WHITE)
  74.         elif self.amazons_black & chess.BB_SQUARES[square]:
  75.             return chess.Piece(AMAZON, chess.BLACK)
  76.         return super().piece_at(square)
  77.  
  78.     def generate_pseudo_legal_moves(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboard = BB_ALL) -> Iterator[Move]:
  79.         our_pieces = self.occupied_co[self.turn]
  80.         if self.turn == chess.WHITE:
  81.             our_amazons = self.amazons_white
  82.         else:
  83.             our_amazons = self.amazons_black
  84.  
  85.         for from_square in chess.scan_forward(our_amazons & from_mask):
  86.             attacks = self.amazon_attacks(from_square)
  87.             valid_moves = attacks & ~our_pieces & to_mask
  88.             for to_square in chess.scan_forward(valid_moves):
  89.                 yield Move(from_square, to_square)
  90.  
  91.         for move in super().generate_pseudo_legal_moves(from_mask, to_mask):
  92.             if self.piece_type_at(move.from_square) != AMAZON:
  93.                 yield move
  94.  
  95.     def amazon_attacks(self, square):
  96.         return self.queen_attacks(square) | chess.BB_KNIGHT_ATTACKS[square]
  97.  
  98.     def queen_attacks(self, square):
  99.         return self.bishop_attacks(square) | self.rook_attacks(square)
  100.  
  101.     def bishop_attacks(self, square):
  102.         return chess.BB_DIAG_ATTACKS[square][self.occupied & chess.BB_DIAG_MASKS[square]]
  103.  
  104.     def rook_attacks(self, square):
  105.         return (chess.BB_RANK_ATTACKS[square][self.occupied & chess.BB_RANK_MASKS[square]] |
  106.                 chess.BB_FILE_ATTACKS[square][self.occupied & chess.BB_FILE_MASKS[square]])
  107.  
  108.     def is_pseudo_legal(self, move):
  109.         from_square = move.from_square
  110.         to_square = move.to_square
  111.         piece = self.piece_at(from_square)
  112.        
  113.         if not piece or piece.color != self.turn:
  114.             return False
  115.  
  116.         if self.occupied_co[self.turn] & chess.BB_SQUARES[to_square]:
  117.             return False
  118.  
  119.         if self.is_castling(move):
  120.             return True
  121.  
  122.         if piece.piece_type == AMAZON:
  123.             return bool(self.amazon_attacks(from_square) & chess.BB_SQUARES[to_square])
  124.         else:
  125.             return super().is_pseudo_legal(move)
  126.  
  127.     def is_legal(self, move):
  128.         print(f"Kontrola legality tahu: {move}")
  129.         if not self.is_pseudo_legal(move):
  130.             return False
  131.  
  132.         from_square = move.from_square
  133.         to_square = move.to_square
  134.         piece = self.piece_at(from_square)
  135.         captured_piece = self.piece_at(to_square)
  136.  
  137.         self._remove_piece_at(from_square)
  138.         self._set_piece_at(to_square, piece.piece_type, piece.color)
  139.  
  140.         king_square = to_square if piece.piece_type == chess.KING else self.king(self.turn)
  141.         is_check, attacker_square = self._is_attacked_by(not self.turn, king_square)
  142.  
  143.         self._remove_piece_at(to_square)
  144.         self._set_piece_at(from_square, piece.piece_type, piece.color)
  145.         if captured_piece:
  146.             self._set_piece_at(to_square, captured_piece.piece_type, captured_piece.color)
  147.  
  148.         if is_check:
  149.             attacking_piece = self.piece_at(attacker_square)
  150.             print(f"Tah {move} staví vlastního krále do šachu od figury {self.piece_symbol(attacking_piece)} na {chess.SQUARE_NAMES[attacker_square]}")
  151.         return not is_check
  152.  
  153.     def _is_attacked_by(self, color, square):
  154.         print(f"Kontrola útoku na pole {chess.SQUARE_NAMES[square]} od barvy {'bílé' if color == chess.WHITE else 'černé'}")
  155.         attackers = self.attackers(color, square)
  156.         if attackers:
  157.             for attacker_square in chess.scan_forward(attackers):
  158.                 piece = self.piece_at(attacker_square)
  159.                 print(f"Figura {self.piece_symbol(piece)} 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