Advertisement
max2201111

tak toto je dost dobre A zmeneno pozic 4

Jul 14th, 2024
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 53.98 KB | Science | 0 0
  1. # Import knihovny chess a dalších potřebných modulů
  2. import chess
  3. from typing import Iterator, Optional, Dict, Tuple
  4. from chess import Move, BB_ALL, Bitboard, PieceType, Color
  5. import time
  6. from collections import deque
  7. import threading
  8.  
  9. # Definice nových figur
  10. AMAZON = 7
  11. CYRIL = 8
  12. EVE = 9
  13.  
  14. # Rozšíření seznamu PIECE_SYMBOLS
  15. chess.PIECE_SYMBOLS.append('a')
  16. chess.PIECE_SYMBOLS.append('c')
  17. chess.PIECE_SYMBOLS.append('e')
  18.  
  19. class CustomBoard(chess.Board):
  20.     def __init__(self, fen=None):
  21.         self.amazons_white = chess.BB_EMPTY
  22.         self.amazons_black = chess.BB_EMPTY
  23.         self.cyrils_white = chess.BB_EMPTY
  24.         self.cyrils_black = chess.BB_EMPTY
  25.         self.eves_white = chess.BB_EMPTY
  26.         self.eves_black = chess.BB_EMPTY
  27.         super().__init__(None)
  28.         if fen:
  29.             self.set_custom_fen(fen)
  30.     #    print("Šachovnice inicializována")
  31.         self.debug_amazons()
  32.         self.debug_cyrils()
  33.         self.debug_eves()
  34.  
  35.     def clear_square(self, square):
  36.         super()._remove_piece_at(square)
  37.         self.amazons_white &= ~chess.BB_SQUARES[square]
  38.         self.amazons_black &= ~chess.BB_SQUARES[square]
  39.         self.cyrils_white &= ~chess.BB_SQUARES[square]
  40.         self.cyrils_black &= ~chess.BB_SQUARES[square]
  41.         self.eves_white &= ~chess.BB_SQUARES[square]
  42.         self.eves_black &= ~chess.BB_SQUARES[square]
  43.  
  44.     def set_custom_fen(self, fen):
  45.         parts = fen.split()
  46.         board_part = parts[0]
  47.  
  48.         self.clear()
  49.         self.amazons_white = chess.BB_EMPTY
  50.         self.amazons_black = chess.BB_EMPTY
  51.         self.cyrils_white = chess.BB_EMPTY
  52.         self.cyrils_black = chess.BB_EMPTY
  53.         self.eves_white = chess.BB_EMPTY
  54.         self.eves_black = chess.BB_EMPTY
  55.  
  56.         square = 56
  57.         for c in board_part:
  58.             if c == '/':
  59.                 square -= 16
  60.             elif c.isdigit():
  61.                 square += int(c)
  62.             else:
  63.                 color = chess.WHITE if c.isupper() else chess.BLACK
  64.                 if c.upper() == 'A':
  65.                     if color == chess.WHITE:
  66.                         self.amazons_white |= chess.BB_SQUARES[square]
  67.                     else:
  68.                         self.amazons_black |= chess.BB_SQUARES[square]
  69.                     piece_type = AMAZON
  70.                 elif c.upper() == 'C':
  71.                     if color == chess.WHITE:
  72.                         self.cyrils_white |= chess.BB_SQUARES[square]
  73.                     else:
  74.                         self.cyrils_black |= chess.BB_SQUARES[square]
  75.                     piece_type = CYRIL
  76.                 elif c.upper() == 'E':
  77.                     if color == chess.WHITE:
  78.                         self.eves_white |= chess.BB_SQUARES[square]
  79.                     else:
  80.                         self.eves_black |= chess.BB_SQUARES[square]
  81.                     piece_type = EVE
  82.                 else:
  83.                     piece_type = chess.PIECE_SYMBOLS.index(c.lower())
  84.                 self._set_piece_at(square, piece_type, color)
  85.                 square += 1
  86.  
  87.         self.turn = chess.WHITE if parts[1] == 'w' else chess.BLACK
  88.         self.castling_rights = chess.BB_EMPTY
  89.         if '-' not in parts[2]:
  90.             if 'K' in parts[2]: self.castling_rights |= chess.BB_H1
  91.             if 'Q' in parts[2]: self.castling_rights |= chess.BB_A1
  92.             if 'k' in parts[2]: self.castling_rights |= chess.BB_H8
  93.             if 'q' in parts[2]: self.castling_rights |= chess.BB_A8
  94.         self.ep_square = chess.parse_square(parts[3]) if parts[3] != '-' else None
  95.  
  96.     def _set_piece_at(self, square: chess.Square, piece_type: PieceType, color: Color) -> None:
  97.         self.clear_square(square)
  98.         super()._set_piece_at(square, piece_type, color)
  99.         if piece_type == AMAZON:
  100.             if color == chess.WHITE:
  101.                 self.amazons_white |= chess.BB_SQUARES[square]
  102.             else:
  103.                 self.amazons_black |= chess.BB_SQUARES[square]
  104.         elif piece_type == CYRIL:
  105.             if color == chess.WHITE:
  106.                 self.cyrils_white |= chess.BB_SQUARES[square]
  107.             else:
  108.                 self.cyrils_black |= chess.BB_SQUARES[square]
  109.         elif piece_type == EVE:
  110.             if color == chess.WHITE:
  111.                 self.eves_white |= chess.BB_SQUARES[square]
  112.             else:
  113.                 self.eves_black |= chess.BB_SQUARES[square]
  114.  
  115.     def piece_at(self, square: chess.Square) -> Optional[chess.Piece]:
  116.         if self.amazons_white & chess.BB_SQUARES[square]:
  117.             return chess.Piece(AMAZON, chess.WHITE)
  118.         elif self.amazons_black & chess.BB_SQUARES[square]:
  119.             return chess.Piece(AMAZON, chess.BLACK)
  120.         elif self.cyrils_white & chess.BB_SQUARES[square]:
  121.             return chess.Piece(CYRIL, chess.WHITE)
  122.         elif self.cyrils_black & chess.BB_SQUARES[square]:
  123.             return chess.Piece(CYRIL, chess.BLACK)
  124.         elif self.eves_white & chess.BB_SQUARES[square]:
  125.             return chess.Piece(EVE, chess.WHITE)
  126.         elif self.eves_black & chess.BB_SQUARES[square]:
  127.             return chess.Piece(EVE, chess.BLACK)
  128.         return super().piece_at(square)
  129.  
  130.     def generate_pseudo_legal_moves(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboard = BB_ALL) -> Iterator[Move]:
  131.         our_pieces = self.occupied_co[self.turn]
  132.         if self.turn == chess.WHITE:
  133.             our_amazons = self.amazons_white
  134.             our_cyrils = self.cyrils_white
  135.             our_eves = self.eves_white
  136.         else:
  137.             our_amazons = self.amazons_black
  138.             our_cyrils = self.cyrils_black
  139.             our_eves = self.eves_black
  140.    
  141.         # Generování tahů pro amazonky
  142.         for from_square in chess.scan_forward(our_amazons & from_mask):
  143.             attacks = self.amazon_attacks(from_square)
  144.             valid_moves = attacks & ~our_pieces & to_mask
  145.             for to_square in chess.scan_forward(valid_moves):
  146.                 yield Move(from_square, to_square)
  147.    
  148.         # Generování tahů pro Cyrily
  149.         for from_square in chess.scan_forward(our_cyrils & from_mask):
  150.             attacks = self.cyril_attacks(from_square)
  151.             valid_moves = attacks & ~our_pieces & to_mask
  152.             for to_square in chess.scan_forward(valid_moves):
  153.                 yield Move(from_square, to_square)
  154.    
  155.         # Generování tahů pro Evy
  156.         for from_square in chess.scan_forward(our_eves & from_mask):
  157.             attacks = self.eve_attacks(from_square)
  158.             valid_moves = attacks & ~our_pieces & to_mask
  159.             for to_square in chess.scan_forward(valid_moves):
  160.                 yield Move(from_square, to_square)
  161.    
  162.         # Generování tahů pro standardní figury
  163.         for move in super().generate_pseudo_legal_moves(from_mask, to_mask):
  164.             piece = self.piece_at(move.from_square)
  165.             if piece and piece.piece_type not in [AMAZON, CYRIL, EVE]:
  166.                 yield move
  167.  
  168.     def queen_attacks(self, square):
  169.         return self.bishop_attacks(square) | self.rook_attacks(square)
  170.  
  171.     def bishop_attacks(self, square):
  172.         return chess.BB_DIAG_ATTACKS[square][self.occupied & chess.BB_DIAG_MASKS[square]]
  173.  
  174.     def rook_attacks(self, square):
  175.         return (chess.BB_RANK_ATTACKS[square][self.occupied & chess.BB_RANK_MASKS[square]] |
  176.                 chess.BB_FILE_ATTACKS[square][self.occupied & chess.BB_FILE_MASKS[square]])
  177.  
  178.     def amazon_attacks(self, square):
  179.         return self.queen_attacks(square) | chess.BB_KNIGHT_ATTACKS[square]
  180.  
  181.     def cyril_attacks(self, square):
  182.         return self.rook_attacks(square) | chess.BB_KNIGHT_ATTACKS(square)
  183.  
  184.     def eve_attacks(self, square):
  185.         return self.bishop_attacks(square) | chess.BB_KNIGHT_ATTACKS(square)
  186.  
  187.     def is_pseudo_legal(self, move):
  188.         from_square = move.from_square
  189.         to_square = move.to_square
  190.         piece = self.piece_at(from_square)
  191.    
  192.         if not piece or piece.color != self.turn:
  193.             return False
  194.    
  195.         if self.occupied_co[self.turn] & chess.BB_SQUARES[to_square]:
  196.             return False
  197.    
  198.         if self.is_castling(move):
  199.             return True
  200.    
  201.         if piece.piece_type == AMAZON:
  202.             return bool(self.amazon_attacks(from_square) & chess.BB_SQUARES[to_square])
  203.         elif piece.piece_type == CYRIL:
  204.             return bool(self.cyril_attacks(from_square) & chess.BB_SQUARES[to_square])
  205.         elif piece.piece_type == EVE:
  206.             return bool(self.eve_attacks(from_square) & chess.BB_SQUARES[to_square])
  207.         else:
  208.             return super().is_pseudo_legal(move)
  209.  
  210.     def is_legal(self, move):
  211.         if not self.is_pseudo_legal(move):
  212.             return False
  213.  
  214.         from_square = move.from_square
  215.         to_square = move.to_square
  216.         piece = self.piece_at(from_square)
  217.         captured_piece = self.piece_at(to_square)
  218.  
  219.         self.clear_square(from_square)
  220.         self.clear_square(to_square)
  221.         self._set_piece_at(to_square, piece.piece_type, piece.color)
  222.  
  223.         king_square = to_square if piece.piece_type == chess.KING else self.king(self.turn)
  224.         is_check = self._is_attacked_by(not self.turn, king_square)
  225.  
  226.         self.clear_square(to_square)
  227.         self._set_piece_at(from_square, piece.piece_type, piece.color)
  228.         if captured_piece:
  229.             self._set_piece_at(to_square, captured_piece.piece_type, captured_piece.color)
  230.  
  231.         if is_check:
  232.             attackers = self.attackers(not self.turn, king_square)
  233.     #        print(f"[DEBUG] King at {chess.SQUARE_NAMES[king_square]} is attacked by pieces at: {[chess.SQUARE_NAMES[sq] for sq in chess.scan_forward(attackers)]}")
  234.  
  235.         return not is_check
  236.  
  237.     def _is_attacked_by(self, color, square):
  238.         attackers = self.attackers(color, square)
  239.         return bool(attackers)
  240.  
  241.     def attackers(self, color, square):
  242.         attackers = chess.BB_EMPTY
  243.  
  244.         knights = self.knights & self.occupied_co[color]
  245.         attackers |= knights & chess.BB_KNIGHT_ATTACKS[square]
  246.  
  247.         king = self.kings & self.occupied_co[color]
  248.         attackers |= king & chess.BB_KING_ATTACKS[square]
  249.  
  250.         pawns = self.pawns & self.occupied_co[color]
  251.         if color == chess.WHITE:
  252.             attackers |= pawns & chess.BB_PAWN_ATTACKS[chess.BLACK][square]
  253.         else:
  254.             attackers |= pawns & chess.BB_PAWN_ATTACKS[chess.WHITE][square]
  255.  
  256.         queens = self.queens & self.occupied_co[color]
  257.         bishops = (self.bishops | queens) & self.occupied_co[color]
  258.         rooks = (self.rooks | queens) & self.occupied_co[color]
  259.  
  260.         attackers |= chess.BB_DIAG_ATTACKS[square][self.occupied & chess.BB_DIAG_MASKS[square]] & bishops
  261.         attackers |= (chess.BB_RANK_ATTACKS[square][self.occupied & chess.BB_RANK_MASKS[square]] |
  262.                       chess.BB_FILE_ATTACKS[square][self.occupied & chess.BB_FILE_MASKS[square]]) & rooks
  263.  
  264.         amazons = self.amazons_white if color == chess.WHITE else self.amazons_black
  265.         for amazon_square in chess.scan_forward(amazons):
  266.             if self.amazon_attacks(amazon_square) & chess.BB_SQUARES[square]:
  267.                 attackers |= chess.BB_SQUARES[amazon_square]
  268.  
  269.         cyrils = self.cyrils_white if color == chess.WHITE else self.cyrils_black
  270.         for cyril_square in chess.scan_forward(cyrils):
  271.             if self.cyril_attacks(cyril_square) & chess.BB_SQUARES[square]:
  272.                 attackers |= chess.BB_SQUARES[cyril_square]
  273.  
  274.         eves = self.eves_white if color == chess.WHITE else self.eves_black
  275.         for eve_square in chess.scan_forward(eves):
  276.             if self.eve_attacks(eve_square) & chess.BB_SQUARES[square]:
  277.                 attackers |= chess.BB_SQUARES[eve_square]
  278.  
  279.         return attackers
  280.  
  281.     def push(self, move):
  282.         if not self.is_legal(move):
  283.             raise ValueError(f"Move {move} is not legal in position {self.fen()}")
  284.  
  285.         piece = self.piece_at(move.from_square)
  286.         captured_piece = self.piece_at(move.to_square)
  287.  
  288.         self.clear_square(move.from_square)
  289.         self.clear_square(move.to_square)
  290.         self._set_piece_at(move.to_square, piece.piece_type, piece.color)
  291.  
  292.         self.turn = not self.turn
  293.  
  294.         self.move_stack.append((move, captured_piece))
  295.  
  296.     def pop(self):
  297.         if not self.move_stack:
  298.             return None
  299.  
  300.         move, captured_piece = self.move_stack.pop()
  301.  
  302.         piece = self.piece_at(move.to_square)
  303.        
  304.         self.clear_square(move.from_square)
  305.         self.clear_square(move.to_square)
  306.  
  307.         self._set_piece_at(move.from_square, piece.piece_type, piece.color)
  308.  
  309.         if captured_piece:
  310.             self._set_piece_at(move.to_square, captured_piece.piece_type, captured_piece.color)
  311.  
  312.         self.turn = not self.turn
  313.  
  314.         return move
  315.  
  316.     def is_check(self):
  317.         king_square = self.king(self.turn)
  318.         if king_square is None:
  319.             return False
  320.         is_check = self._is_attacked_by(not self.turn, king_square)
  321.   #      print(f"[DEBUG] Checking if position is check: FEN: {self.fen()}, King at {chess.SQUARE_NAMES[king_square]}, is_check: {is_check}")
  322.         return is_check
  323.  
  324.     def is_checkmate(self):
  325.         if not self.is_check():
  326.   #          print(f"[DEBUG] Position is not check, hence not checkmate: FEN: {self.fen()}")
  327.             return False
  328.         legal_moves = list(self.generate_legal_moves())
  329.  #       print(f"[DEBUG] Checking if position is checkmate: FEN: {self.fen()}, Legal moves: {legal_moves}")
  330.         return len(legal_moves) == 0
  331.  
  332.     def is_game_over(self):
  333.         return self.is_checkmate() or self.is_stalemate() or self.is_insufficient_material()
  334.  
  335.     def is_stalemate(self):
  336.         if self.is_check():
  337.             return False
  338.         legal_moves = list(self.generate_legal_moves())
  339.   #      print(f"[DEBUG] Checking if position is stalemate: FEN: {self.fen()}, Legal moves: {legal_moves}")
  340.         return len(legal_moves) == 0
  341.    
  342.     def is_insufficient_material(self):
  343.         return (self.pawns | self.rooks | self.queens | self.amazons_white | self.amazons_black |
  344.                 self.cyrils_white | self.cyrils_black | self.eves_white | self.eves_black) == 0 and (
  345.             chess.popcount(self.occupied) <= 3
  346.         )
  347.  
  348.     def generate_legal_moves(self, from_mask=chess.BB_ALL, to_mask=chess.BB_ALL):
  349.         for move in self.generate_pseudo_legal_moves(from_mask, to_mask):
  350.             if self.is_legal(move):
  351.       #          print(f"[DEBUG] Legal move: {move}")
  352.                 yield move
  353.        #     else:
  354.         #        print(f"[DEBUG] Illegal move: {move}")
  355.  
  356.     def debug_amazons(self):
  357.         pass
  358.       #  print(f"Bitboard bílých amazonek: {format(self.amazons_white, '064b')}")
  359.     #   print(f"Bitboard černých amazonek: {format(self.amazons_black, '064b')}")
  360.         for square in chess.SQUARES:
  361.             pass
  362.        #     if self.amazons_white & chess.BB_SQUARES[square]:
  363.        #         print(f"Bílá amazonka na {chess.SQUARE_NAMES[square]}")
  364.      #       if self.amazons_black & chess.BB_SQUARES[square]:
  365.        #         print(f"Černá amazonka na {chess.SQUARE_NAMES[square]}")
  366.  
  367.     def debug_cyrils(self):
  368.         pass
  369.        # print(f"Bitboard bílých Cyrils: {format(self.cyrils_white, '064b')}")
  370.        # print(f"Bitboard černých Cyrils: {format(self.cyrils_black, '064b')}")
  371.        # for square in chess.SQUARES:
  372.        #     if self.cyrils_white & chess.BB_SQUARES[square]:
  373.       #          print(f"Bílý Cyril na {chess.SQUARE_NAMES[square]}")
  374.      #       if self.cyrils_black & chess.BB_SQUARES[square]:
  375.     #            print(f"Černý Cyril na {chess.SQUARE_NAMES[square]}")
  376.  
  377.     def debug_eves(self):
  378.         pass
  379.     #    print(f"Bitboard bílých Eves: {format(self.eves_white, '064b')}")
  380.      #   print(f"Bitboard černých Eves: {format(self.eves_black, '064b')}")
  381.       #  for square in chess.SQUARES:
  382.       #      if self.eves_white & chess.BB_SQUARES[square]:
  383.           #      print(f"Bílá Eve na {chess.SQUARE_NAMES[square]}")
  384.        #     if self.eves_black & chess.BB_SQUARES[square]:
  385.        #         print(f"Černá Eve na {chess.SQUARE_NAMES[square]}")
  386.  
  387.     def piece_symbol(self, piece):
  388.         if piece is None:
  389.             return '.'
  390.         if piece.piece_type == AMAZON:
  391.             return 'A' if piece.color == chess.WHITE else 'a'
  392.         if piece.piece_type == CYRIL:
  393.             return 'C' if piece.color == chess.WHITE else 'c'
  394.         if piece.piece_type == EVE:
  395.             return 'E' if piece.color == chess.WHITE else 'e'
  396.         return piece.symbol()
  397.  
  398.     def piece_type_at(self, square):
  399.         if (self.amazons_white | self.amazons_black) & chess.BB_SQUARES[square]:
  400.             return AMAZON
  401.         if (self.cyrils_white | self.cyrils_black) & chess.BB_SQUARES[square]:
  402.             return CYRIL
  403.         if (self.eves_white | self.eves_black) & chess.BB_SQUARES[square]:
  404.             return EVE
  405.         return super().piece_type_at(square)
  406.  
  407.     def color_at(self, square):
  408.         if self.amazons_white & chess.BB_SQUARES[square]:
  409.             return chess.WHITE
  410.         if self.amazons_black & chess.BB_SQUARES[square]:
  411.             return chess.BLACK
  412.         if self.cyrils_white & chess.BB_SQUARES[square]:
  413.             return chess.WHITE
  414.         if self.cyrils_black & chess.BB_SQUARES[square]:
  415.             return chess.BLACK
  416.         if self.eves_white & chess.BB_SQUARES[square]:
  417.             return chess.WHITE
  418.         if self.eves_black & chess.BB_SQUARES[square]:
  419.             return chess.BLACK
  420.         return super().color_at(square)
  421.  
  422.     @property
  423.     def legal_moves(self):
  424.         return list(self.generate_legal_moves())
  425.  
  426.     def __str__(self):
  427.         builder = []
  428.         for square in chess.SQUARES_180:
  429.             piece = self.piece_at(square)
  430.             symbol = self.piece_symbol(piece) if piece else '.'
  431.             builder.append(symbol)
  432.             if chess.square_file(square) == 7:
  433.                 if square != chess.H1:
  434.                     builder.append('\n')
  435.         return ''.join(builder)
  436.  
  437.     def print_all_possible_moves(self):
  438.         pass
  439.     #    print(f"[DEBUG] All possible moves for FEN: {self.fen()}")
  440.   #      for move in self.generate_pseudo_legal_moves():
  441.    #         print(f"Move: {move}, Is legal: {self.is_legal(move)}")
  442.  
  443. def simplify_fen_string(fen):
  444.     parts = fen.split(' ')
  445.     return ' '.join(parts[:4])  # Zachováváme pouze informace o pozici, barvě na tahu, rošádách a en passant
  446.  
  447. def format_time(seconds):
  448.     hours, remainder = divmod(seconds, 3600)
  449.     minutes, seconds = divmod(remainder, 60)
  450.     return f"{int(hours):02d}h {int(minutes):02d}m {int(seconds):02d}s"
  451.  
  452. def print_elapsed_time(stop_event, start_time):
  453.     while not stop_event.is_set():
  454.         elapsed_time = time.time() - start_time
  455.         print(f"\rUplynulý čas: {format_time(elapsed_time)}", end="", flush=True)
  456.         time.sleep(1)
  457.  
  458. # def calculate_optimal_moves(start_fen: str) -> Dict[str, int]:
  459. #     board = CustomBoard(start_fen)
  460. #     AR = {simplify_fen_string(start_fen): 0}
  461. #     queue = deque([(simplify_fen_string(start_fen), 0)])
  462. #     visited = set()
  463.  
  464. #     start_time = time.time()
  465. #     current_level = 0
  466. #     pozice_na_urovni = 0
  467. #     level_start_time = start_time
  468.  
  469. #     stop_event = threading.Event()
  470. #     timer_thread = threading.Thread(target=print_elapsed_time, args=(stop_event, start_time))
  471. #     timer_thread.start()
  472.  
  473. #     try:
  474. #         # Fáze 1: Generování všech pozic
  475. #         while queue:
  476. #             fen, hloubka = queue.popleft()
  477.  
  478. #             if hloubka > current_level:
  479. #                 level_time = time.time() - level_start_time
  480. #                 print(f"\nHloubka {current_level + 1}: {pozice_na_urovni} pozic, Čas: {format_time(level_time)}")
  481. #                 current_level = hloubka
  482. #                 pozice_na_urovni = 0
  483. #                 level_start_time = time.time()
  484.  
  485. #             if fen in visited:
  486. #                 continue
  487.  
  488. #             visited.add(fen)
  489. #             pozice_na_urovni += 1
  490. #             board.set_custom_fen(fen)
  491.  
  492. #             if board.is_checkmate():
  493. #                 AR[fen] = -1000 if board.turn == chess.WHITE else 1000
  494. #             elif board.is_stalemate() or board.is_insufficient_material():
  495. #                 AR[fen] = 0
  496. #             else:
  497. #                 legal_moves = list(board.legal_moves)
  498. #                 for move in legal_moves:
  499. #                     board.push(move)
  500. #                     new_fen = simplify_fen_string(board.fen())
  501. #                     if new_fen not in AR:
  502. #                         AR[new_fen] = 0
  503. #                         queue.append((new_fen, hloubka + 1))
  504. #                     board.pop()
  505.  
  506. #         print(f"\nCelkový počet pozic: {len(AR)}")
  507.  
  508. #         # Fáze 2: Aktualizace hodnot
  509. #         print("\nZačíná aktualizace hodnot...")
  510. #         POZ = {1: simplify_fen_string(start_fen)}
  511. #         AR = {simplify_fen_string(start_fen): {'used': 0, 'to_end': None}}
  512. #         N = 1
  513. #         M = 0
  514.  
  515. #         while M < N:
  516. #             M += 1
  517. #             current_fen = POZ[M]
  518. #             board = CustomBoard(current_fen)
  519. #             simplified_current_fen = simplify_fen_string(current_fen)
  520.  
  521. #             if AR[simplified_current_fen]['used'] == 0:
  522. #                 AR[simplified_current_fen]['used'] = 1
  523. #                 for move in board.legal_moves:
  524. #                     if board.is_pseudo_legal(move) and move.promotion:
  525. #                         move.promotion = chess.QUEEN
  526.  
  527. #                     board.push(move)
  528. #                     POZ2 = board.fen()
  529. #                     simplified_POZ2 = simplify_fen_string(POZ2)
  530.  
  531. #                     if simplified_POZ2 not in AR:
  532. #                         AR[simplified_POZ2] = {'used': None, 'to_end': None}
  533.  
  534. #                     if AR[simplified_POZ2]['used'] is None:
  535. #                         N += 1
  536. #                         POZ[N] = simplified_POZ2
  537. #                         AR[simplified_POZ2] = {'used': 0, 'to_end': None}
  538.  
  539. #                     board.pop()
  540.  
  541. #         print(f"Počet pozic je {N}")
  542.  
  543. #         F = 0
  544. #         for i in range(1, N + 1):
  545. #             current_fen = POZ[i]
  546. #             board = CustomBoard(current_fen)
  547. #             simplified_current_fen = simplify_fen_string(current_fen)
  548.  
  549. #             if board.is_checkmate():
  550. #                 AR[simplified_current_fen]['to_end'] = -1000 if board.turn == chess.WHITE else 1000
  551. #                 F += 1
  552. #             elif board.is_stalemate() or board.is_insufficient_material():
  553. #                 AR[simplified_current_fen]['to_end'] = 0
  554. #             else:
  555. #                 AR[simplified_current_fen]['to_end'] = 0
  556.  
  557. #         print(f"Počet pozic v matu je {F}")
  558.  
  559. #         uroven = 0
  560. #         while F > 0:
  561. #             uroven += 1
  562. #             level_start_time = time.time()
  563. #             print(f"Výpočet v úrovni {uroven}")
  564.  
  565. #             F = 0
  566. #             current_level_positions = 0
  567. #             for i in range(1, N + 1):
  568. #                 current_fen = POZ[i]
  569. #                 board = CustomBoard(current_fen)
  570. #                 simplified_current_fen = simplify_fen_string(current_fen)
  571. #                 if AR[simplified_current_fen]['to_end'] == 0:
  572. #                     hod = -2000
  573. #                     for move in board.legal_moves:
  574. #                         if board.is_pseudo_legal(move) and move.promotion:
  575. #                             move.promotion = chess.QUEEN
  576.  
  577. #                         board.push(move)
  578. #                         POZ2 = board.fen()
  579. #                         simplified_POZ2 = simplify_fen_string(POZ2)
  580. #                         hod2 = -AR[simplified_POZ2]['to_end']
  581. #                         if hod2 > hod:
  582. #                             hod = hod2
  583. #                         board.pop()
  584. #                     if hod == 1001 - uroven:
  585. #                         AR[simplified_current_fen]['to_end'] = 1000 - uroven
  586. #                         F += 1
  587. #                         current_level_positions += 1
  588. #                     if hod == -1001 + uroven:
  589. #                         AR[simplified_current_fen]['to_end'] = -1000 + uroven
  590. #                         F += 1
  591. #                         current_level_positions += 1
  592. #             level_end_time = time.time()
  593. #             total_elapsed_time = level_end_time - start_time
  594. #             level_elapsed_time = level_end_time - level_start_time
  595. #             print(f"Nalezeno {current_level_positions} pozic v úrovni {uroven}")
  596. #             print(f"Čas úrovně: {format_time(level_elapsed_time)}, Celkový čas: {format_time(total_elapsed_time)}")
  597.  
  598. #         print(f"Nalezeno {F} pozic celkem")
  599.  
  600. #     finally:
  601. #         stop_event.set()
  602. #         timer_thread.join()
  603.  
  604. #     total_time = time.time() - start_time
  605. #     print(f"\nCelkový čas výpočtu: {format_time(total_time)}")
  606.  
  607. #     return {fen: data['to_end'] for fen, data in AR.items()}
  608.  
  609. # def calculate_optimal_moves(start_fen: str) -> Dict[str, int]:
  610. #     board = CustomBoard(start_fen)
  611. #     POZ = {1: simplify_fen_string(start_fen)}
  612. #     AR = {simplify_fen_string(start_fen): {'used': 0, 'to_end': None}}
  613. #     N = 1
  614. #     M = 0
  615.  
  616. #     start_time = time.time()
  617.  
  618. #     stop_event = threading.Event()
  619. #     timer_thread = threading.Thread(target=print_elapsed_time, args=(stop_event, start_time))
  620. #     timer_thread.start()
  621.  
  622. #     try:
  623. #         while M < N:
  624. #             M += 1
  625. #             current_fen = POZ[M]
  626. #             board.set_custom_fen(current_fen)
  627. #             simplified_current_fen = simplify_fen_string(current_fen)
  628.  
  629. #             if AR[simplified_current_fen]['used'] == 0:
  630. #                 AR[simplified_current_fen]['used'] = 1
  631. #                 legal_moves = list(board.legal_moves)
  632. #                 for move in legal_moves:
  633. #                     if board.is_pseudo_legal(move) and move.promotion:
  634. #                         move.promotion = chess.QUEEN
  635.  
  636. #                     board.push(move)
  637. #                     POZ2 = board.fen()
  638. #                     simplified_POZ2 = simplify_fen_string(POZ2)
  639.  
  640. #                     if simplified_POZ2 not in AR:
  641. #                         AR[simplified_POZ2] = {'used': None, 'to_end': None}
  642.  
  643. #                     if AR[simplified_POZ2]['used'] is None:
  644. #                         N += 1
  645. #                         POZ[N] = simplified_POZ2
  646. #                         AR[simplified_POZ2] = {'used': 0, 'to_end': None}
  647.  
  648. #                     board.pop()
  649.  
  650. #         print(f"Počet pozic je {N}")
  651.  
  652. #         # Inicializace hodnot
  653. #         for i in range(1, N + 1):
  654. #             current_fen = POZ[i]
  655. #             board.set_custom_fen(current_fen)
  656. #             simplified_current_fen = simplify_fen_string(current_fen)
  657.  
  658. #             if board.is_checkmate():
  659. #                 AR[simplified_current_fen]['to_end'] = -1000 if board.turn == chess.WHITE else 1000
  660. #             elif board.is_stalemate() or board.is_insufficient_material():
  661. #                 AR[simplified_current_fen]['to_end'] = 0
  662. #             else:
  663. #                 AR[simplified_current_fen]['to_end'] = None  # Změna zde
  664.  
  665. #         changed = True
  666. #         uroven = 0
  667. #         while changed:
  668. #             uroven += 1
  669. #             level_start_time = time.time()
  670. #             print(f"Výpočet v úrovni {uroven}")
  671.  
  672. #             changed = False
  673. #             current_level_positions = 0
  674. #             for i in range(1, N + 1):
  675. #                 current_fen = POZ[i]
  676. #                 board.set_custom_fen(current_fen)
  677. #                 simplified_current_fen = simplify_fen_string(current_fen)
  678. #                 if AR[simplified_current_fen]['to_end'] is None:
  679. #                     legal_moves = list(board.legal_moves)
  680. #                     if board.turn == chess.WHITE:
  681. #                         best_value = -2000
  682. #                         for move in legal_moves:
  683. #                             board.push(move)
  684. #                             POZ2 = board.fen()
  685. #                             simplified_POZ2 = simplify_fen_string(POZ2)
  686. #                             if AR[simplified_POZ2]['to_end'] is not None:
  687. #                                 best_value = max(best_value, -AR[simplified_POZ2]['to_end'])
  688. #                             board.pop()
  689. #                         if best_value > -2000:
  690. #                             AR[simplified_current_fen]['to_end'] = best_value
  691. #                             changed = True
  692. #                             current_level_positions += 1
  693. #                     else:  # Black's turn
  694. #                         best_value = 2000
  695. #                         for move in legal_moves:
  696. #                             board.push(move)
  697. #                             POZ2 = board.fen()
  698. #                             simplified_POZ2 = simplify_fen_string(POZ2)
  699. #                             if AR[simplified_POZ2]['to_end'] is not None:
  700. #                                 best_value = min(best_value, -AR[simplified_POZ2]['to_end'])
  701. #                             board.pop()
  702. #                         if best_value < 2000:
  703. #                             AR[simplified_current_fen]['to_end'] = best_value
  704. #                             changed = True
  705. #                             current_level_positions += 1
  706.  
  707. #             level_end_time = time.time()
  708. #             total_elapsed_time = level_end_time - start_time
  709. #             level_elapsed_time = level_end_time - level_start_time
  710. #             print(f"Nalezeno {current_level_positions} pozic v úrovni {uroven}")
  711. #             print(f"Čas úrovně: {format_time(level_elapsed_time)}, Celkový čas: {format_time(total_elapsed_time)}")
  712.  
  713. #         print(f"Nalezeno {sum(1 for v in AR.values() if v['to_end'] is not None)} vyhodnocených pozic celkem")
  714.  
  715. #     finally:
  716. #         stop_event.set()
  717. #         timer_thread.join()
  718.  
  719. #     total_time = time.time() - start_time
  720. #     print(f"\nCelkový čas výpočtu: {format_time(total_time)}")
  721.  
  722.   #  return {fen: data['to_end'] for fen, data in AR.items() if data['to_end'] is not None}
  723.  
  724. # def calculate_optimal_moves(start_fen: str) -> Dict[str, int]:
  725. #     board = CustomBoard(start_fen)
  726. #     POZ = {1: simplify_fen_string(start_fen)}
  727. #     AR = {simplify_fen_string(start_fen): {'used': 0, 'to_end': None}}
  728. #     N = 1
  729. #     M = 0
  730.  
  731. #     start_time = time.time()
  732.  
  733. #     stop_event = threading.Event()
  734. #     timer_thread = threading.Thread(target=print_elapsed_time, args=(stop_event, start_time))
  735. #     timer_thread.start()
  736.  
  737. #     try:
  738. #         while M < N:
  739. #             M += 1
  740. #             current_fen = POZ[M]
  741. #             board.set_custom_fen(current_fen)
  742. #             simplified_current_fen = simplify_fen_string(current_fen)
  743.  
  744. #             if AR[simplified_current_fen]['used'] == 0:
  745. #                 AR[simplified_current_fen]['used'] = 1
  746. #                 legal_moves = list(board.legal_moves)
  747. #                 for move in legal_moves:
  748. #                     if board.is_pseudo_legal(move) and move.promotion:
  749. #                         move.promotion = chess.QUEEN
  750.  
  751. #                     board.push(move)
  752. #                     POZ2 = board.fen()
  753. #                     simplified_POZ2 = simplify_fen_string(POZ2)
  754.  
  755. #                     if simplified_POZ2 not in AR:
  756. #                         AR[simplified_POZ2] = {'used': None, 'to_end': None}
  757.  
  758. #                     if AR[simplified_POZ2]['used'] is None:
  759. #                         N += 1
  760. #                         POZ[N] = simplified_POZ2
  761. #                         AR[simplified_POZ2] = {'used': 0, 'to_end': None}
  762.  
  763. #                     board.pop()
  764.  
  765. #         print(f"Počet pozic je {N}")
  766.  
  767. #         # Inicializace hodnot
  768. #         initial_positions = 0
  769. #         for i in range(1, N + 1):
  770. #             current_fen = POZ[i]
  771. #             board.set_custom_fen(current_fen)
  772. #             simplified_current_fen = simplify_fen_string(current_fen)
  773.  
  774. #             if board.is_checkmate():
  775. #                 AR[simplified_current_fen]['to_end'] = -1000 if board.turn == chess.WHITE else 1000
  776. #                 initial_positions += 1
  777. #             elif board.is_stalemate() or board.is_insufficient_material():
  778. #                 AR[simplified_current_fen]['to_end'] = 0
  779. #                 initial_positions += 1
  780. #             else:
  781. #                 AR[simplified_current_fen]['to_end'] = None
  782.  
  783. #         print(f"Počet počátečních ohodnocených pozic: {initial_positions}")
  784.  
  785. #         changed = True
  786. #         uroven = 0
  787. #         while changed:
  788. #             uroven += 1
  789. #             level_start_time = time.time()
  790. #             print(f"Výpočet v úrovni {uroven}")
  791.  
  792. #             changed = False
  793. #             current_level_positions = 0
  794. #             for i in range(1, N + 1):
  795. #                 current_fen = POZ[i]
  796. #                 board.set_custom_fen(current_fen)
  797. #                 simplified_current_fen = simplify_fen_string(current_fen)
  798. #                 if AR[simplified_current_fen]['to_end'] is None:
  799. #                     legal_moves = list(board.legal_moves)
  800. #                     if board.turn == chess.WHITE:
  801. #                         best_value = -2000
  802. #                         for move in legal_moves:
  803. #                             board.push(move)
  804. #                             POZ2 = board.fen()
  805. #                             simplified_POZ2 = simplify_fen_string(POZ2)
  806. #                             if AR[simplified_POZ2]['to_end'] is not None:
  807. #                                 best_value = max(best_value, -AR[simplified_POZ2]['to_end'])
  808. #                             board.pop()
  809. #                         if best_value > -2000:
  810. #                             AR[simplified_current_fen]['to_end'] = best_value
  811. #                             changed = True
  812. #                             current_level_positions += 1
  813. #                     else:  # Black's turn
  814. #                         best_value = 2000
  815. #                         for move in legal_moves:
  816. #                             board.push(move)
  817. #                             POZ2 = board.fen()
  818. #                             simplified_POZ2 = simplify_fen_string(POZ2)
  819. #                             if AR[simplified_POZ2]['to_end'] is not None:
  820. #                                 best_value = min(best_value, -AR[simplified_POZ2]['to_end'])
  821. #                             board.pop()
  822. #                         if best_value < 2000:
  823. #                             AR[simplified_current_fen]['to_end'] = best_value
  824. #                             changed = True
  825. #                             current_level_positions += 1
  826.  
  827. #             level_end_time = time.time()
  828. #             total_elapsed_time = level_end_time - start_time
  829. #             level_elapsed_time = level_end_time - level_start_time
  830. #             print(f"Změněno {current_level_positions} pozic v úrovni {uroven}")
  831. #             print(f"Čas úrovně: {format_time(level_elapsed_time)}, Celkový čas: {format_time(total_elapsed_time)}")
  832.  
  833. #         total_evaluated = sum(1 for v in AR.values() if v['to_end'] is not None)
  834. #         print(f"Celkem vyhodnoceno {total_evaluated} pozic")
  835. #         print(f"Pozice bez hodnocení: {N - total_evaluated}")
  836.  
  837. #     finally:
  838. #         stop_event.set()
  839. #         timer_thread.join()
  840.  
  841. #     total_time = time.time() - start_time
  842. #     print(f"\nCelkový čas výpočtu: {format_time(total_time)}")
  843.  
  844. #     return {fen: data['to_end'] for fen, data in AR.items() if data['to_end'] is not None}
  845.  
  846. # def calculate_optimal_moves(start_fen: str) -> Dict[str, int]:
  847. #     board = CustomBoard(start_fen)
  848. #     POZ = {1: simplify_fen_string(start_fen)}
  849. #     AR = {simplify_fen_string(start_fen): {'used': 0, 'to_end': None}}
  850. #     N = 1
  851. #     M = 0
  852.  
  853. #     start_time = time.time()
  854.  
  855. #     stop_event = threading.Event()
  856. #     timer_thread = threading.Thread(target=print_elapsed_time, args=(stop_event, start_time))
  857. #     timer_thread.start()
  858.  
  859. #     try:
  860. #         while M < N:
  861. #             M += 1
  862. #             current_fen = POZ[M]
  863. #             board.set_custom_fen(current_fen)
  864. #             simplified_current_fen = simplify_fen_string(current_fen)
  865.  
  866. #             if AR[simplified_current_fen]['used'] == 0:
  867. #                 AR[simplified_current_fen]['used'] = 1
  868. #                 legal_moves = list(board.legal_moves)
  869. #                 for move in legal_moves:
  870. #                     if board.is_pseudo_legal(move) and move.promotion:
  871. #                         move.promotion = chess.QUEEN
  872.  
  873. #                     board.push(move)
  874. #                     POZ2 = board.fen()
  875. #                     simplified_POZ2 = simplify_fen_string(POZ2)
  876.  
  877. #                     if simplified_POZ2 not in AR:
  878. #                         AR[simplified_POZ2] = {'used': None, 'to_end': None}
  879.  
  880. #                     if AR[simplified_POZ2]['used'] is None:
  881. #                         N += 1
  882. #                         POZ[N] = simplified_POZ2
  883. #                         AR[simplified_POZ2] = {'used': 0, 'to_end': None}
  884.  
  885. #                     board.pop()
  886.  
  887. #         print(f"Počet pozic je {N}")
  888.  
  889. #         # Inicializace hodnot
  890. #         initial_positions = 0
  891. #         for i in range(1, N + 1):
  892. #             current_fen = POZ[i]
  893. #             board.set_custom_fen(current_fen)
  894. #             simplified_current_fen = simplify_fen_string(current_fen)
  895.  
  896. #             if board.is_checkmate():
  897. #                 AR[simplified_current_fen]['to_end'] = -1000 if board.turn == chess.WHITE else 1000
  898. #                 initial_positions += 1
  899. #             elif board.is_stalemate() or board.is_insufficient_material():
  900. #                 AR[simplified_current_fen]['to_end'] = 0
  901. #                 initial_positions += 1
  902. #             else:
  903. #                 AR[simplified_current_fen]['to_end'] = None
  904.  
  905. #         print(f"Počet počátečních ohodnocených pozic: {initial_positions}")
  906.  
  907. #         changed = True
  908. #         uroven = 0
  909. #         while changed:
  910. #             uroven += 1
  911. #             level_start_time = time.time()
  912. #             print(f"Výpočet v úrovni {uroven}")
  913.  
  914. #             changed = False
  915. #             current_level_positions = 0
  916. #             for i in range(1, N + 1):
  917. #                 current_fen = POZ[i]
  918. #                 board.set_custom_fen(current_fen)
  919. #                 simplified_current_fen = simplify_fen_string(current_fen)
  920. #                 if AR[simplified_current_fen]['to_end'] is None:
  921. #                     legal_moves = list(board.legal_moves)
  922. #                     if board.turn == chess.WHITE:
  923. #                         best_value = -2000
  924. #                         for move in legal_moves:
  925. #                             board.push(move)
  926. #                             POZ2 = board.fen()
  927. #                             simplified_POZ2 = simplify_fen_string(POZ2)
  928. #                             if AR[simplified_POZ2]['to_end'] is not None:
  929. #                                 best_value = max(best_value, -AR[simplified_POZ2]['to_end'])
  930. #                             board.pop()
  931. #                         if best_value > -2000:
  932. #                             AR[simplified_current_fen]['to_end'] = best_value
  933. #                             changed = True
  934. #                             current_level_positions += 1
  935. #                     else:  # Black's turn
  936. #                         best_value = 2000
  937. #                         for move in legal_moves:
  938. #                             board.push(move)
  939. #                             POZ2 = board.fen()
  940. #                             simplified_POZ2 = simplify_fen_string(POZ2)
  941. #                             if AR[simplified_POZ2]['to_end'] is not None:
  942. #                                 best_value = min(best_value, -AR[simplified_POZ2]['to_end'])
  943. #                             board.pop()
  944. #                         if best_value < 2000:
  945. #                             AR[simplified_current_fen]['to_end'] = best_value
  946. #                             changed = True
  947. #                             current_level_positions += 1
  948.  
  949. #             level_end_time = time.time()
  950. #             total_elapsed_time = level_end_time - start_time
  951. #             level_elapsed_time = level_end_time - level_start_time
  952. #             print(f"Změněno {current_level_positions} pozic v úrovni {uroven}")
  953. #             print(f"Čas úrovně: {format_time(level_elapsed_time)}, Celkový čas: {format_time(total_elapsed_time)}")
  954.  
  955. #             if not changed:
  956. #                 break
  957.  
  958. #         total_evaluated = sum(1 for v in AR.values() if v['to_end'] is not None)
  959. #         print(f"Celkem vyhodnoceno {total_evaluated} pozic")
  960. #         print(f"Pozice bez hodnocení: {N - total_evaluated}")
  961.  
  962. #     finally:
  963. #         stop_event.set()
  964. #         timer_thread.join()
  965.  
  966. #     total_time = time.time() - start_time
  967. #     print(f"\nCelkový čas výpočtu: {format_time(total_time)}")
  968.  
  969. #     return {fen: data['to_end'] for fen, data in AR.items() if data['to_end'] is not None}
  970.  
  971. # def calculate_optimal_moves(start_fen: str) -> Dict[str, int]:
  972. #     board = CustomBoard(start_fen)
  973. #     POZ = {1: simplify_fen_string(start_fen)}
  974. #     AR = {simplify_fen_string(start_fen): {'used': 0, 'to_end': None, 'depth': 0}}
  975. #     N = 1
  976. #     M = 0
  977.  
  978. #     start_time = time.time()
  979. #     current_depth = 0
  980. #     positions_at_depth = 0
  981. #     depth_start_time = start_time
  982.  
  983. #     stop_event = threading.Event()
  984. #     timer_thread = threading.Thread(target=print_elapsed_time, args=(stop_event, start_time))
  985. #     timer_thread.start()
  986.  
  987. #     try:
  988. #         while M < N:
  989. #             M += 1
  990. #             current_fen = POZ[M]
  991. #             board.set_custom_fen(current_fen)
  992. #             simplified_current_fen = simplify_fen_string(current_fen)
  993. #             current_depth = AR[simplified_current_fen]['depth']
  994.  
  995. #             if current_depth > positions_at_depth:
  996. #                 depth_time = time.time() - depth_start_time
  997. #                 print(f"\nHloubka {current_depth}: {positions_at_depth} pozic, Čas: {format_time(depth_time)}")
  998. #                 positions_at_depth = 0
  999. #                 depth_start_time = time.time()
  1000.  
  1001. #             positions_at_depth += 1
  1002.  
  1003. #             if AR[simplified_current_fen]['used'] == 0:
  1004. #                 AR[simplified_current_fen]['used'] = 1
  1005. #                 legal_moves = list(board.legal_moves)
  1006. #                 for move in legal_moves:
  1007. #                     if board.is_pseudo_legal(move) and move.promotion:
  1008. #                         move.promotion = chess.QUEEN
  1009.  
  1010. #                     board.push(move)
  1011. #                     POZ2 = board.fen()
  1012. #                     simplified_POZ2 = simplify_fen_string(POZ2)
  1013.  
  1014. #                     if simplified_POZ2 not in AR:
  1015. #                         AR[simplified_POZ2] = {'used': None, 'to_end': None, 'depth': current_depth + 1}
  1016.  
  1017. #                     if AR[simplified_POZ2]['used'] is None:
  1018. #                         N += 1
  1019. #                         POZ[N] = simplified_POZ2
  1020. #                         AR[simplified_POZ2] = {'used': 0, 'to_end': None, 'depth': current_depth + 1}
  1021.  
  1022. #                     board.pop()
  1023.  
  1024. #         print(f"\nHloubka {current_depth}: {positions_at_depth} pozic, Čas: {format_time(time.time() - depth_start_time)}")
  1025. #         print(f"Celkový počet pozic: {N}")
  1026.  
  1027. #         # Inicializace hodnot
  1028. #         initial_positions = 0
  1029. #         for i in range(1, N + 1):
  1030. #             current_fen = POZ[i]
  1031. #             board.set_custom_fen(current_fen)
  1032. #             simplified_current_fen = simplify_fen_string(current_fen)
  1033.  
  1034. #             if board.is_checkmate():
  1035. #                 AR[simplified_current_fen]['to_end'] = -1000 if board.turn == chess.WHITE else 1000
  1036. #                 initial_positions += 1
  1037. #             elif board.is_stalemate() or board.is_insufficient_material():
  1038. #                 AR[simplified_current_fen]['to_end'] = 0
  1039. #                 initial_positions += 1
  1040. #             else:
  1041. #                 AR[simplified_current_fen]['to_end'] = None
  1042.  
  1043. #         print(f"Počet počátečních ohodnocených pozic: {initial_positions}")
  1044.  
  1045. #         changed = True
  1046. #         uroven = 0
  1047. #         while changed:
  1048. #             uroven += 1
  1049. #             level_start_time = time.time()
  1050. #             print(f"Výpočet v úrovni {uroven}")
  1051.  
  1052. #             changed = False
  1053. #             current_level_positions = 0
  1054. #             for i in range(1, N + 1):
  1055. #                 current_fen = POZ[i]
  1056. #                 board.set_custom_fen(current_fen)
  1057. #                 simplified_current_fen = simplify_fen_string(current_fen)
  1058. #                 if AR[simplified_current_fen]['to_end'] is None:
  1059. #                     legal_moves = list(board.legal_moves)
  1060. #                     if board.turn == chess.WHITE:
  1061. #                         best_value = -2000
  1062. #                         for move in legal_moves:
  1063. #                             board.push(move)
  1064. #                             POZ2 = board.fen()
  1065. #                             simplified_POZ2 = simplify_fen_string(POZ2)
  1066. #                             if AR[simplified_POZ2]['to_end'] is not None:
  1067. #                                 best_value = max(best_value, -AR[simplified_POZ2]['to_end'])
  1068. #                             board.pop()
  1069. #                         if best_value > -2000:
  1070. #                             AR[simplified_current_fen]['to_end'] = best_value
  1071. #                             changed = True
  1072. #                             current_level_positions += 1
  1073. #                     else:  # Black's turn
  1074. #                         best_value = 2000
  1075. #                         for move in legal_moves:
  1076. #                             board.push(move)
  1077. #                             POZ2 = board.fen()
  1078. #                             simplified_POZ2 = simplify_fen_string(POZ2)
  1079. #                             if AR[simplified_POZ2]['to_end'] is not None:
  1080. #                                 best_value = min(best_value, -AR[simplified_POZ2]['to_end'])
  1081. #                             board.pop()
  1082. #                         if best_value < 2000:
  1083. #                             AR[simplified_current_fen]['to_end'] = best_value
  1084. #                             changed = True
  1085. #                             current_level_positions += 1
  1086.  
  1087. #             level_end_time = time.time()
  1088. #             total_elapsed_time = level_end_time - start_time
  1089. #             level_elapsed_time = level_end_time - level_start_time
  1090. #             print(f"Změněno {current_level_positions} pozic v úrovni {uroven}")
  1091. #             print(f"Čas úrovně: {format_time(level_elapsed_time)}, Celkový čas: {format_time(total_elapsed_time)}")
  1092.  
  1093. #             if not changed:
  1094. #                 break
  1095.  
  1096. #         total_evaluated = sum(1 for v in AR.values() if v['to_end'] is not None)
  1097. #         print(f"Celkem vyhodnoceno {total_evaluated} pozic")
  1098. #         print(f"Pozice bez hodnocení: {N - total_evaluated}")
  1099.  
  1100. #     finally:
  1101. #         stop_event.set()
  1102. #         timer_thread.join()
  1103.  
  1104. #     total_time = time.time() - start_time
  1105. #     print(f"\nCelkový čas výpočtu: {format_time(total_time)}")
  1106.  
  1107. #     return {fen: data['to_end'] for fen, data in AR.items() if data['to_end'] is not None}
  1108.  
  1109. # if __name__ == "__main__":
  1110. #     start_fen = "8/3k4/8/8/8/8/A7/6K1 w - - 0 1"
  1111. #     AR = calculate_optimal_moves(start_fen)
  1112. #     F = 0
  1113.  
  1114. #     # Výpis výsledků
  1115. #     for fen, hodnota in AR.items():
  1116. #         F = F + 1
  1117. #         if F < 50 or hodnota != 0:
  1118. #             print(f"FEN: {fen}")
  1119. #             print(f"Hodnota: {hodnota}")
  1120. #             print()
  1121.  
  1122.  
  1123.  
  1124. import chess
  1125. from typing import Iterator, Optional, Dict, Tuple
  1126. from chess import Move, BB_ALL, Bitboard, PieceType, Color
  1127. import time
  1128. from collections import deque
  1129. import threading
  1130.  
  1131. # ... (předchozí definice zůstávají stejné)
  1132.  
  1133. def format_time(seconds):
  1134.     hours, remainder = divmod(seconds, 3600)
  1135.     minutes, seconds = divmod(remainder, 60)
  1136.     return f"{int(hours):02d}h {int(minutes):02d}m {int(seconds):02d}s"
  1137.  
  1138. def print_elapsed_time(stop_event, start_time):
  1139.     while not stop_event.is_set():
  1140.         elapsed_time = time.time() - start_time
  1141.         print(f"\rUplynulý čas: {format_time(elapsed_time)}", end="", flush=True)
  1142.         time.sleep(1)
  1143.  
  1144. def calculate_optimal_moves(start_fen: str) -> Dict[str, int]:
  1145.     board = CustomBoard(start_fen)
  1146.     POZ = {1: simplify_fen_string(start_fen)}
  1147.     AR = {simplify_fen_string(start_fen): {'used': 0, 'to_end': None, 'depth': 0}}
  1148.     N = 1
  1149.     M = 0
  1150.  
  1151.     start_time = time.time()
  1152.     current_depth = 0
  1153.     positions_at_depth = 0
  1154.     depth_start_time = start_time
  1155.  
  1156.     stop_event = threading.Event()
  1157.     timer_thread = threading.Thread(target=print_elapsed_time, args=(stop_event, start_time))
  1158.     timer_thread.start()
  1159.  
  1160.     try:
  1161.         while M < N:
  1162.             M += 1
  1163.             current_fen = POZ[M]
  1164.             board.set_custom_fen(current_fen)
  1165.             simplified_current_fen = simplify_fen_string(current_fen)
  1166.             current_depth = AR[simplified_current_fen]['depth']
  1167.  
  1168.             if current_depth > positions_at_depth:
  1169.                 depth_time = time.time() - depth_start_time
  1170.                 print(f"\nHloubka {positions_at_depth}: {positions_at_depth} pozic, Čas: {format_time(depth_time)}")
  1171.                 positions_at_depth = current_depth
  1172.                 depth_start_time = time.time()
  1173.  
  1174.             if AR[simplified_current_fen]['used'] == 0:
  1175.                 AR[simplified_current_fen]['used'] = 1
  1176.                 legal_moves = list(board.legal_moves)
  1177.                 for move in legal_moves:
  1178.                     if board.is_pseudo_legal(move) and move.promotion:
  1179.                         move.promotion = chess.QUEEN
  1180.  
  1181.                     board.push(move)
  1182.                     POZ2 = board.fen()
  1183.                     simplified_POZ2 = simplify_fen_string(POZ2)
  1184.  
  1185.                     if simplified_POZ2 not in AR:
  1186.                         AR[simplified_POZ2] = {'used': None, 'to_end': None, 'depth': current_depth + 1}
  1187.  
  1188.                     if AR[simplified_POZ2]['used'] is None:
  1189.                         N += 1
  1190.                         POZ[N] = simplified_POZ2
  1191.                         AR[simplified_POZ2] = {'used': 0, 'to_end': None, 'depth': current_depth + 1}
  1192.  
  1193.                     board.pop()
  1194.  
  1195.         print(f"\nHloubka {current_depth}: {N - sum(1 for v in AR.values() if v['depth'] < current_depth)} pozic, Čas: {format_time(time.time() - depth_start_time)}")
  1196.         print(f"Celkový počet pozic: {N}")
  1197.  
  1198.         # Inicializace hodnot
  1199.         initial_positions = 0
  1200.         for i in range(1, N + 1):
  1201.             current_fen = POZ[i]
  1202.             board.set_custom_fen(current_fen)
  1203.             simplified_current_fen = simplify_fen_string(current_fen)
  1204.  
  1205.             if board.is_checkmate():
  1206.                 AR[simplified_current_fen]['to_end'] = -1000 if board.turn == chess.WHITE else 1000
  1207.                 initial_positions += 1
  1208.             elif board.is_stalemate() or board.is_insufficient_material():
  1209.                 AR[simplified_current_fen]['to_end'] = 0
  1210.                 initial_positions += 1
  1211.             else:
  1212.                 AR[simplified_current_fen]['to_end'] = None
  1213.  
  1214.         print(f"Počet počátečních ohodnocených pozic: {initial_positions}")
  1215.  
  1216.         changed = True
  1217.         uroven = 0
  1218.         while changed:
  1219.             uroven += 1
  1220.             level_start_time = time.time()
  1221.             print(f"\nVýpočet v úrovni {uroven}")
  1222.  
  1223.             changed = False
  1224.             current_level_positions = 0
  1225.             for i in range(1, N + 1):
  1226.                 current_fen = POZ[i]
  1227.                 board.set_custom_fen(current_fen)
  1228.                 simplified_current_fen = simplify_fen_string(current_fen)
  1229.                 if AR[simplified_current_fen]['to_end'] is None:
  1230.                     legal_moves = list(board.legal_moves)
  1231.                     if board.turn == chess.WHITE:
  1232.                         best_value = -2000
  1233.                         for move in legal_moves:
  1234.                             board.push(move)
  1235.                             POZ2 = board.fen()
  1236.                             simplified_POZ2 = simplify_fen_string(POZ2)
  1237.                             if AR[simplified_POZ2]['to_end'] is not None:
  1238.                                 best_value = max(best_value, -AR[simplified_POZ2]['to_end'])
  1239.                             board.pop()
  1240.                         if best_value > -2000:
  1241.                             AR[simplified_current_fen]['to_end'] = best_value
  1242.                             changed = True
  1243.                             current_level_positions += 1
  1244.                     else:  # Black's turn
  1245.                         best_value = 2000
  1246.                         for move in legal_moves:
  1247.                             board.push(move)
  1248.                             POZ2 = board.fen()
  1249.                             simplified_POZ2 = simplify_fen_string(POZ2)
  1250.                             if AR[simplified_POZ2]['to_end'] is not None:
  1251.                                 best_value = min(best_value, -AR[simplified_POZ2]['to_end'])
  1252.                             board.pop()
  1253.                         if best_value < 2000:
  1254.                             AR[simplified_current_fen]['to_end'] = best_value
  1255.                             changed = True
  1256.                             current_level_positions += 1
  1257.  
  1258.             level_end_time = time.time()
  1259.             total_elapsed_time = level_end_time - start_time
  1260.             level_elapsed_time = level_end_time - level_start_time
  1261.             print(f"Změněno {current_level_positions} pozic v úrovni {uroven}")
  1262.             print(f"Čas úrovně: {format_time(level_elapsed_time)}, Celkový čas: {format_time(total_elapsed_time)}")
  1263.  
  1264.             if not changed:
  1265.                 break
  1266.  
  1267.         total_evaluated = sum(1 for v in AR.values() if v['to_end'] is not None)
  1268.         print(f"\nCelkem vyhodnoceno {total_evaluated} pozic")
  1269.         print(f"Pozice bez hodnocení: {N - total_evaluated}")
  1270.  
  1271.     finally:
  1272.         stop_event.set()
  1273.         timer_thread.join()
  1274.  
  1275.     total_time = time.time() - start_time
  1276.     print(f"\nCelkový čas výpočtu: {format_time(total_time)}")
  1277.  
  1278.     return {fen: data['to_end'] for fen, data in AR.items() if data['to_end'] is not None}
  1279.  
  1280. if __name__ == "__main__":
  1281.     start_fen = "8/3k4/8/8/8/8/A7/6K1 w - - 0 1"
  1282.     AR = calculate_optimal_moves(start_fen)
  1283.    
  1284.     # Výpis výsledků
  1285.     print("\nVýsledky:")
  1286.     for fen, hodnota in AR.items():
  1287.         if hodnota != 0:
  1288.             print(f"FEN: {fen}")
  1289.             print(f"Hodnota: {hodnota}")
  1290.             print()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement