Advertisement
max2201111

OK AEC ale moc vystupu

Jul 3rd, 2024 (edited)
711
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 19.19 KB | Science | 0 0
  1. import chess
  2. import time
  3. from functools import lru_cache
  4. import traceback
  5. from typing import Iterator
  6. from chess import Move, BB_ALL, Bitboard, scan_reversed
  7.  
  8. # Definice nových figurek
  9. AMAZON = 7
  10. CYRIL = 8
  11. EVA = 9
  12.  
  13. # Nová funkce attacks_mask
  14. def new_attacks_mask(self, piece_type, square, occupied):
  15.     print("new_attacks_mask")
  16.     bb_square = chess.BB_SQUARES[square]
  17.  
  18.     if piece_type == chess.PAWN:
  19.         color = bool(bb_square & self.occupied_co[chess.WHITE])
  20.         return chess.BB_PAWN_ATTACKS[color][square]
  21.     elif piece_type == chess.KNIGHT:
  22.         return chess.BB_KNIGHT_ATTACKS[square]
  23.     elif piece_type == chess.KING:
  24.         return chess.BB_KING_ATTACKS[square]
  25.     else:
  26.         attacks = 0
  27.         if piece_type == chess.BISHOP or piece_type == chess.QUEEN:
  28.             attacks = chess.BB_DIAG_ATTACKS[square][chess.BB_DIAG_MASKS[square] & occupied]
  29.         if piece_type == chess.ROOK or piece_type == chess.QUEEN:
  30.             attacks |= (chess.BB_RANK_ATTACKS[square][chess.BB_RANK_MASKS[square] & occupied] |
  31.                         chess.BB_FILE_ATTACKS[square][chess.BB_FILE_MASKS[square] & occupied])
  32.         if piece_type == AMAZON:
  33.             attacks = (chess.BB_KNIGHT_ATTACKS[square] |
  34.                        chess.BB_DIAG_ATTACKS[square][chess.BB_DIAG_MASKS[square] & occupied] |
  35.                        chess.BB_RANK_ATTACKS[square][chess.BB_RANK_MASKS[square] & occupied] |
  36.                        chess.BB_FILE_ATTACKS[square][chess.BB_FILE_MASKS[square] & occupied])
  37.         elif piece_type == CYRIL:
  38.             attacks = (chess.BB_KNIGHT_ATTACKS[square] |
  39.                        chess.BB_RANK_ATTACKS[square][chess.BB_RANK_MASKS[square] & occupied] |
  40.                        chess.BB_FILE_ATTACKS[square][chess.BB_FILE_MASKS[square] & occupied])
  41.         elif piece_type == EVA:
  42.             attacks = (chess.BB_KNIGHT_ATTACKS[square] |
  43.                        chess.BB_DIAG_ATTACKS[square][chess.BB_DIAG_MASKS[square] & occupied])
  44.         return attacks
  45.  
  46. # Přiřazení nové funkce
  47. chess.BaseBoard.attacks_mask = new_attacks_mask
  48.  
  49. class CustomBoard(chess.Board):
  50.     def __init__(self, fen=None):
  51.         print("__init__")
  52.         super().__init__(fen)
  53.         self._custom_piece_map = {}
  54.         if fen:
  55.             self._custom_piece_map = self._parse_custom_fen(fen)
  56.         else:
  57.             self._custom_piece_map = self._create_custom_piece_map()
  58.        
  59.         # Inicializace bitboardů pro nové figury
  60.         self.amazons = chess.BB_EMPTY
  61.         self.cyrils = chess.BB_EMPTY
  62.         self.evas = chess.BB_EMPTY
  63.         for square, piece in self._custom_piece_map.items():
  64.             bb = chess.BB_SQUARES[square]
  65.             if piece.piece_type == AMAZON:
  66.                 self.amazons |= bb
  67.             elif piece.piece_type == CYRIL:
  68.                 self.cyrils |= bb
  69.             elif piece.piece_type == EVA:
  70.                 self.evas |= bb
  71.         self.occupied_co[chess.WHITE] |= self.amazons | self.cyrils | self.evas
  72.         self.occupied_co[chess.BLACK] |= self.amazons | self.cyrils | self.evas
  73.         self.occupied |= self.amazons | self.cyrils | self.evas
  74.  
  75.     def _parse_custom_fen(self, fen):
  76.         print("_parse_custom_fen")
  77.         piece_map = {}
  78.         board_part = fen.split()[0]
  79.         square = 0
  80.         for char in board_part:
  81.             if char.isdigit():
  82.                 square += int(char)
  83.             elif char == '/':
  84.                 continue
  85.             else:
  86.                 color = chess.WHITE if char.isupper() else chess.BLACK
  87.                 piece_type = {
  88.                     'A': AMAZON,
  89.                     'C': CYRIL,
  90.                     'E': EVA,
  91.                     'P': chess.PAWN,
  92.                     'N': chess.KNIGHT,
  93.                     'B': chess.BISHOP,
  94.                     'R': chess.ROOK,
  95.                     'Q': chess.QUEEN,
  96.                     'K': chess.KING
  97.                 }.get(char.upper(), None)
  98.                 if piece_type:
  99.                     piece = chess.Piece(piece_type, color)
  100.                     piece_map[square] = piece
  101.                 square += 1
  102.         return piece_map
  103.  
  104.     def piece_symbol(self, piece):
  105.         print("piece_symbol")
  106.         if piece is None:
  107.             return "."
  108.         if piece.piece_type == AMAZON:
  109.             return "A" if piece.color == chess.WHITE else "a"
  110.         if piece.piece_type == CYRIL:
  111.             return "C" if piece.color == chess.WHITE else "c"
  112.         if piece.piece_type == EVA:
  113.             return "E" if piece.color == chess.WHITE else "e"
  114.         return chess.PIECE_SYMBOLS[piece.piece_type].upper() if piece.color == chess.WHITE else chess.PIECE_SYMBOLS[piece.piece_type]
  115.  
  116.     def _create_custom_piece_map(self):
  117.         print("_create_custom_piece_map")
  118.         piece_map = {}
  119.         for square, piece in self.piece_map().items():
  120.             piece_map[square] = piece
  121.         return piece_map
  122.  
  123.     def generate_pseudo_legal_moves(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboard = BB_ALL) -> Iterator[Move]:
  124.         print("generate_pseudo_legal_moves začíná")
  125.         our_pieces = self.occupied_co[self.turn]
  126.         print(f"Na tahu je: {'Bílý' if self.turn == chess.WHITE else 'Černý'}")
  127.         print(f"Počet našich figur: {bin(our_pieces).count('1')}")
  128.  
  129.         # Generate piece moves.
  130.         non_pawns = our_pieces & ~self.pawns & from_mask
  131.         print(f"Počet figur kromě pěšců: {bin(non_pawns).count('1')}")
  132.         for from_square in scan_reversed(non_pawns):
  133.             piece = self.piece_at(from_square)
  134.             if piece is None or piece.color != self.turn:
  135.                 continue
  136.             piece_type = piece.piece_type
  137.             print(f"Generuji tahy pro figuru {piece_type} na poli {chess.SQUARE_NAMES[from_square]}")
  138.             if piece_type == AMAZON:
  139.                 moves = (self.attacks_mask(chess.KNIGHT, from_square, self.occupied) |
  140.                          self.attacks_mask(chess.BISHOP, from_square, self.occupied) |
  141.                          self.attacks_mask(chess.ROOK, from_square, self.occupied)) & ~our_pieces & to_mask
  142.             elif piece_type == CYRIL:
  143.                 moves = (self.attacks_mask(chess.KNIGHT, from_square, self.occupied) |
  144.                          self.attacks_mask(chess.ROOK, from_square, self.occupied)) & ~our_pieces & to_mask
  145.             elif piece_type == EVA:
  146.                 moves = (self.attacks_mask(chess.KNIGHT, from_square, self.occupied) |
  147.                          self.attacks_mask(chess.BISHOP, from_square, self.occupied)) & ~our_pieces & to_mask
  148.             else:
  149.                 moves = self.attacks_mask(piece_type, from_square, self.occupied) & ~our_pieces & to_mask
  150.             move_count = 0
  151.             for to_square in scan_reversed(moves):
  152.                 move_count += 1
  153.                 yield Move(from_square, to_square)
  154.             print(f"Vygenerováno {move_count} tahů pro tuto figuru")
  155.  
  156.         # Generate castling moves.
  157.         if from_mask & self.kings:
  158.             print("Generuji rošády")
  159.             castling_moves = list(self.generate_castling_moves(from_mask, to_mask))
  160.             print(f"Vygenerováno {len(castling_moves)} rošád")
  161.             yield from castling_moves
  162.  
  163.         # The remaining moves are all pawn moves.
  164.         pawns = self.pawns & self.occupied_co[self.turn] & from_mask
  165.         print(f"Počet pěšců: {bin(pawns).count('1')}")
  166.         if not pawns:
  167.             print("Žádní pěšci k tahu")
  168.             return
  169.  
  170.         # Generate pawn moves.
  171.         print("Generuji tahy pěšců")
  172.         pawn_moves = list(self.generate_pseudo_legal_pawn_moves(pawns, to_mask))
  173.         print(f"Vygenerováno {len(pawn_moves)} tahů pěšců")
  174.         yield from pawn_moves
  175.  
  176.         # Generate pawn captures.
  177.         print("Generuji braní pěšců")
  178.         capturers = pawns
  179.         capture_count = 0
  180.         for from_square in scan_reversed(capturers):
  181.             targets = (
  182.                 chess.BB_PAWN_ATTACKS[self.turn][from_square] &
  183.                 self.occupied_co[not self.turn] & to_mask)
  184.  
  185.             for to_square in scan_reversed(targets):
  186.                 capture_count += 1
  187.                 if chess.square_rank(to_square) in [0, 7]:
  188.                     yield Move(from_square, to_square, chess.QUEEN)
  189.                     yield Move(from_square, to_square, chess.ROOK)
  190.                     yield Move(from_square, to_square, chess.BISHOP)
  191.                     yield Move(from_square, to_square, chess.KNIGHT)
  192.                 else:
  193.                     yield Move(from_square, to_square)
  194.         print(f"Vygenerováno {capture_count} braní pěšců")
  195.  
  196.         print("generate_pseudo_legal_moves končí")
  197.  
  198.     def _is_attacked_by_new_piece(self, king: chess.Square, attacker_square: chess.Square, piece_type: chess.PieceType) -> bool:
  199.         print(f"_is_attacked_by_new_piece: cíl (král) {chess.SQUARE_NAMES[king]}, útočník {chess.SQUARE_NAMES[attacker_square]}")
  200.         if piece_type == AMAZON:
  201.             return bool(self.attacks_mask(chess.KNIGHT, attacker_square, self.occupied) & chess.BB_SQUARES[king] or
  202.                         self.attacks_mask(chess.BISHOP, attacker_square, self.occupied) & chess.BB_SQUARES[king] or
  203.                         self.attacks_mask(chess.ROOK, attacker_square, self.occupied) & chess.BB_SQUARES[king])
  204.         elif piece_type == CYRIL:
  205.             return bool(self.attacks_mask(chess.KNIGHT, attacker_square, self.occupied) & chess.BB_SQUARES[king] or
  206.                         self.attacks_mask(chess.ROOK, attacker_square, self.occupied) & chess.BB_SQUARES[king])
  207.         elif piece_type == EVA:
  208.             return bool(self.attacks_mask(chess.KNIGHT, attacker_square, self.occupied) & chess.BB_SQUARES[king] or
  209.                         self.attacks_mask(chess.BISHOP, attacker_square, self.occupied) & chess.BB_SQUARES[king])
  210.         return False
  211.  
  212.     def is_check(self) -> bool:
  213.         print("is_check")
  214.         king = self.king(self.turn)
  215.         if king is None:
  216.             return False
  217.  
  218.         print(f"Kontrola šachu pro krále na {chess.SQUARE_NAMES[king]}")
  219.         opponent_color = not self.turn
  220.         for attacker_square in chess.SQUARES:
  221.             piece = self.piece_at(attacker_square)
  222.             if piece and piece.color == opponent_color:
  223.                 if piece.piece_type in [AMAZON, CYRIL, EVA]:
  224.                     if self._is_attacked_by_new_piece(king, attacker_square, piece.piece_type):
  225.                         print(f"Král je v šachu od {self.piece_symbol(piece)} na poli {chess.SQUARE_NAMES[attacker_square]}")
  226.                         return True
  227.                 elif self.attacks_mask(piece.piece_type, attacker_square, self.occupied) & chess.BB_SQUARES[king]:
  228.                     print(f"Král je v šachu od {self.piece_symbol(piece)} na poli {chess.SQUARE_NAMES[attacker_square]}")
  229.                     return True
  230.  
  231.         print("Král není v šachu")
  232.         return False
  233.  
  234.     def is_legal(self, move: Move) -> bool:
  235.         print(f"Kontrola legality tahu: {move}")
  236.         if not super().is_pseudo_legal(move):
  237.             print("Tah není pseudo-legální")
  238.             return False
  239.        
  240.         self.push(move)
  241.         legal = not self.is_check()
  242.         self.pop()
  243.        
  244.         if legal:
  245.             print("Tah je legální")
  246.         else:
  247.             print("Tah by vystavil vlastního krále šachu")
  248.         return legal
  249.  
  250. @lru_cache(maxsize=None)
  251. def simplify_fen_string(fen):
  252.     print("simplify_fen_string")
  253.     parts = fen.split(' ')
  254.     simplified_fen = ' '.join(parts[:4] + ["0", "1"])
  255.     return simplified_fen
  256.  
  257. def print_board(fen):
  258.     print("print_board")
  259.     board = CustomBoard(fen)
  260.     print(board.unicode(invert_color=True))
  261.     print()  # Add an empty line after the board
  262.  
  263. def format_time(seconds):
  264.     print("format_time")
  265.     hours, remainder = divmod(seconds, 3600)
  266.     minutes, seconds = divmod(remainder, 60)
  267.     return f"{int(hours):02d}h {int(minutes):02d}m {int(seconds):02d}s"
  268.    
  269. def analyze_positions(start_fen, min_depth=5):
  270.     print("analyze_positions začíná")
  271.     print("Initializing analysis...")
  272.     POZ = {1: start_fen}
  273.     AR = {simplify_fen_string(start_fen): {'depth': 0, 'value': None}}
  274.     N = 1
  275.  
  276.     start_time = time.time()
  277.     total_time = 0
  278.  
  279.     print("Generování pozic...")
  280.     while True:
  281.         new_positions = False
  282.         for i in range(1, N + 1):
  283.             current_fen = POZ[i]
  284.             board = CustomBoard(current_fen)
  285.             simplified_fen = simplify_fen_string(current_fen)
  286.            
  287.             if AR[simplified_fen]['depth'] == 0:
  288.                 AR[simplified_fen]['depth'] = 1
  289.                 legal_moves = list(board.legal_moves)
  290.                 print(f"Pozice {i}: {simplified_fen}, Počet legálních tahů: {len(legal_moves)}")
  291.                 for move in legal_moves:
  292.                     board.push(move)
  293.                     new_fen = board.fen()
  294.                     simplified_new_fen = simplify_fen_string(new_fen)
  295.                     if simplified_new_fen not in AR:
  296.                         N += 1
  297.                         POZ[N] = new_fen
  298.                         AR[simplified_new_fen] = {'depth': 0, 'value': None}
  299.                         new_positions = True
  300.                     board.pop()
  301.        
  302.         if not new_positions:
  303.             break
  304.        
  305.     print(f"Celkový počet pozic: {N}")
  306.  
  307.     # Inicializace koncových pozic
  308.     terminal_positions = 0
  309.     for i in range(1, N + 1):
  310.         current_fen = POZ[i]
  311.         board = CustomBoard(current_fen)
  312.         simplified_fen = simplify_fen_string(current_fen)
  313.  
  314.         if board.is_checkmate():
  315.             AR[simplified_fen]['value'] = -1000 if board.turn == chess.WHITE else 1000
  316.             AR[simplified_fen]['depth'] = min_depth
  317.             terminal_positions += 1
  318.         elif board.is_stalemate() or board.is_insufficient_material() or board.is_seventyfive_moves() or board.is_fivefold_repetition():
  319.             AR[simplified_fen]['value'] = 0
  320.             AR[simplified_fen]['depth'] = min_depth
  321.             terminal_positions += 1
  322.  
  323.     print(f"Počet koncových pozic: {terminal_positions}")
  324.  
  325.     max_depth = 0
  326.     while max_depth < min_depth:
  327.         max_depth += 1
  328.         level_start_time = time.time()
  329.         print(f"Výpočet v hloubce {max_depth}")
  330.        
  331.         changes = False
  332.         positions_evaluated = 0
  333.         for i in range(1, N + 1):
  334.             current_fen = POZ[i]
  335.             board = CustomBoard(current_fen)
  336.             simplified_fen = simplify_fen_string(current_fen)
  337.             if AR[simplified_fen]['depth'] < max_depth and AR[simplified_fen]['value'] is None:
  338.                 positions_evaluated += 1
  339.                 best_value = -2000 if board.turn == chess.WHITE else 2000
  340.                 all_moves_evaluated = True
  341.                 legal_moves = list(board.legal_moves)
  342.               ##  print(f"Pozice {i}: {simplified_fen}, Počet legálních tahů: {len(legal_moves)}")
  343.                 for move in legal_moves:
  344.                     board.push(move)
  345.                     next_fen = board.fen()
  346.                     simplified_next_fen = simplify_fen_string(next_fen)
  347.                     if simplified_next_fen not in AR:
  348.                         print(f"Warning: Position not found in AR: {simplified_next_fen}")
  349.                         all_moves_evaluated = False
  350.                         break
  351.                     next_value = AR[simplified_next_fen]['value']
  352.                     if next_value is None:
  353.                         all_moves_evaluated = False
  354.                         break
  355.                     if board.turn == chess.WHITE:
  356.                         best_value = max(best_value, -next_value)
  357.                     else:
  358.                         best_value = min(best_value, -next_value)
  359.                     board.pop()
  360.                
  361.                 if all_moves_evaluated:
  362.                     AR[simplified_fen]['value'] = best_value
  363.                     AR[simplified_fen]['depth'] = max_depth
  364.                     changes = True
  365.  
  366.         level_end_time = time.time()
  367.         level_elapsed_time = level_end_time - level_start_time
  368.         total_time += level_elapsed_time
  369.        
  370.         formatted_total_time = format_time(total_time)
  371.         formatted_level_time = format_time(level_elapsed_time)
  372.        
  373.         print(f"Hloubka {max_depth} dokončena")
  374.         print(f"Pozice vyhodnoceny: {positions_evaluated}")
  375.         print(f"Změny provedeny: {'Ano' if changes else 'Ne'}")
  376.         print(f"Čas: {formatted_total_time} / {formatted_level_time}")
  377.  
  378.     print(f"Analýza dokončena do hloubky {max_depth}")
  379.     print(f"Celkový čas: {format_time(total_time)}")
  380.  
  381.     current_fen = start_fen
  382.     optimal_moves = []
  383.     while True:
  384.         board = CustomBoard(current_fen)
  385.         simplified_fen = simplify_fen_string(current_fen)
  386.         if simplified_fen not in AR:
  387.             print(f"Warning: Position not found in AR: {simplified_fen}")
  388.             break
  389.         current_value = AR[simplified_fen]['value']
  390.        
  391.         if current_value in [-1000, 0, 1000] or current_value is None:
  392.             break
  393.        
  394.         best_move = None
  395.         for move in board.legal_moves:
  396.             board.push(move)
  397.             next_fen = board.fen()
  398.             simplified_next_fen = simplify_fen_string(next_fen)
  399.             if simplified_next_fen not in AR:
  400.                 print(f"Warning: Position not found in AR: {simplified_next_fen}")
  401.                 continue
  402.             next_value = AR[simplified_next_fen]['value']
  403.             if next_value is not None and next_value == -current_value:
  404.                 best_move = move
  405.                 break
  406.             board.pop()
  407.        
  408.         if best_move is None:
  409.             break
  410.        
  411.         optimal_moves.append((current_fen, best_move))
  412.         board.push(best_move)
  413.         current_fen = board.fen()
  414.  
  415.     print("\nOptimální tahy:")
  416.     for fen, move in optimal_moves:
  417.         board = CustomBoard(fen)
  418.         print(f"{board.fullmove_number}. {'Bílý' if board.turn == chess.WHITE else 'Černý'}: {move}")
  419.         print_board(fen)
  420.         print()
  421.  
  422.     print("Konečná pozice:")
  423.     print_board(current_fen)
  424.  
  425.     print("analyze_positions končí")
  426.  
  427. if __name__ == "__main__":
  428.     print("Program začíná")
  429.     start_fen = "1a6/3k4/8/8/8/8/8/6K1 b - - 0 1"
  430.     print("Starting analysis...")
  431.     print("Initial position:")
  432.     print_board(start_fen)
  433.    
  434.     try:
  435.         print("Creating initial board...")
  436.         initial_board = CustomBoard(start_fen)
  437.         print("Initial board created successfully.")
  438.        
  439.         print("Piece map:")
  440.         for square, piece in initial_board._custom_piece_map.items():
  441.             print(f"Square {chess.SQUARE_NAMES[square]}: {initial_board.piece_symbol(piece)}")
  442.        
  443.         print("Generating legal moves for initial position...")
  444.         legal_moves = list(initial_board.legal_moves)
  445.         print(f"Number of legal moves: {len(legal_moves)}")
  446.         for move in legal_moves:
  447.             print(f"Move: {move}")
  448.        
  449.         print("Starting position analysis...")
  450.         analyze_positions(start_fen, min_depth=5)
  451.     except Exception as e:
  452.         print(f"An error occurred: {str(e)}")
  453.         traceback.print_exc()
  454.    
  455.     print("Program končí")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement