Advertisement
max2201111

last bez #

Jul 14th, 2024
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 25.55 KB | Science | 0 0
  1. import chess
  2. from typing import Iterator, Optional, Dict, Tuple
  3. from chess import Move, BB_ALL, Bitboard, PieceType, Color
  4. import time
  5. from collections import deque
  6. import threading
  7.  
  8. # Definice nových figur
  9. AMAZON = 7
  10. CYRIL = 8
  11. EVE = 9
  12.  
  13. # Rozšíření seznamu PIECE_SYMBOLS
  14. chess.PIECE_SYMBOLS.append('a')
  15. chess.PIECE_SYMBOLS.append('c')
  16. chess.PIECE_SYMBOLS.append('e')
  17.  
  18. class CustomBoard(chess.Board):
  19.     def __init__(self, fen=None):
  20.         self.amazons_white = chess.BB_EMPTY
  21.         self.amazons_black = chess.BB_EMPTY
  22.         self.cyrils_white = chess.BB_EMPTY
  23.         self.cyrils_black = chess.BB_EMPTY
  24.         self.eves_white = chess.BB_EMPTY
  25.         self.eves_black = chess.BB_EMPTY
  26.         super().__init__(None)
  27.         if fen:
  28.             self.set_custom_fen(fen)
  29.     #    print("Šachovnice inicializována")
  30.         self.debug_amazons()
  31.         self.debug_cyrils()
  32.         self.debug_eves()
  33.  
  34.     def clear_square(self, square):
  35.         super()._remove_piece_at(square)
  36.         self.amazons_white &= ~chess.BB_SQUARES[square]
  37.         self.amazons_black &= ~chess.BB_SQUARES[square]
  38.         self.cyrils_white &= ~chess.BB_SQUARES[square]
  39.         self.cyrils_black &= ~chess.BB_SQUARES[square]
  40.         self.eves_white &= ~chess.BB_SQUARES[square]
  41.         self.eves_black &= ~chess.BB_SQUARES[square]
  42.  
  43.     def set_custom_fen(self, fen):
  44.         parts = fen.split()
  45.         board_part = parts[0]
  46.  
  47.         self.clear()
  48.         self.amazons_white = chess.BB_EMPTY
  49.         self.amazons_black = chess.BB_EMPTY
  50.         self.cyrils_white = chess.BB_EMPTY
  51.         self.cyrils_black = chess.BB_EMPTY
  52.         self.eves_white = chess.BB_EMPTY
  53.         self.eves_black = chess.BB_EMPTY
  54.  
  55.         square = 56
  56.         for c in board_part:
  57.             if c == '/':
  58.                 square -= 16
  59.             elif c.isdigit():
  60.                 square += int(c)
  61.             else:
  62.                 color = chess.WHITE if c.isupper() else chess.BLACK
  63.                 if c.upper() == 'A':
  64.                     if color == chess.WHITE:
  65.                         self.amazons_white |= chess.BB_SQUARES[square]
  66.                     else:
  67.                         self.amazons_black |= chess.BB_SQUARES[square]
  68.                     piece_type = AMAZON
  69.                 elif c.upper() == 'C':
  70.                     if color == chess.WHITE:
  71.                         self.cyrils_white |= chess.BB_SQUARES[square]
  72.                     else:
  73.                         self.cyrils_black |= chess.BB_SQUARES[square]
  74.                     piece_type = CYRIL
  75.                 elif c.upper() == 'E':
  76.                     if color == chess.WHITE:
  77.                         self.eves_white |= chess.BB_SQUARES[square]
  78.                     else:
  79.                         self.eves_black |= chess.BB_SQUARES[square]
  80.                     piece_type = EVE
  81.                 else:
  82.                     piece_type = chess.PIECE_SYMBOLS.index(c.lower())
  83.                 self._set_piece_at(square, piece_type, color)
  84.                 square += 1
  85.  
  86.         self.turn = chess.WHITE if parts[1] == 'w' else chess.BLACK
  87.         self.castling_rights = chess.BB_EMPTY
  88.         if '-' not in parts[2]:
  89.             if 'K' in parts[2]: self.castling_rights |= chess.BB_H1
  90.             if 'Q' in parts[2]: self.castling_rights |= chess.BB_A1
  91.             if 'k' in parts[2]: self.castling_rights |= chess.BB_H8
  92.             if 'q' in parts[2]: self.castling_rights |= chess.BB_A8
  93.         self.ep_square = chess.parse_square(parts[3]) if parts[3] != '-' else None
  94.  
  95.     def _set_piece_at(self, square: chess.Square, piece_type: PieceType, color: Color) -> None:
  96.         self.clear_square(square)
  97.         super()._set_piece_at(square, piece_type, color)
  98.         if piece_type == AMAZON:
  99.             if color == chess.WHITE:
  100.                 self.amazons_white |= chess.BB_SQUARES[square]
  101.             else:
  102.                 self.amazons_black |= chess.BB_SQUARES[square]
  103.         elif piece_type == CYRIL:
  104.             if color == chess.WHITE:
  105.                 self.cyrils_white |= chess.BB_SQUARES[square]
  106.             else:
  107.                 self.cyrils_black |= chess.BB_SQUARES[square]
  108.         elif piece_type == EVE:
  109.             if color == chess.WHITE:
  110.                 self.eves_white |= chess.BB_SQUARES[square]
  111.             else:
  112.                 self.eves_black |= chess.BB_SQUARES[square]
  113.  
  114.     def piece_at(self, square: chess.Square) -> Optional[chess.Piece]:
  115.         if self.amazons_white & chess.BB_SQUARES[square]:
  116.             return chess.Piece(AMAZON, chess.WHITE)
  117.         elif self.amazons_black & chess.BB_SQUARES[square]:
  118.             return chess.Piece(AMAZON, chess.BLACK)
  119.         elif self.cyrils_white & chess.BB_SQUARES[square]:
  120.             return chess.Piece(CYRIL, chess.WHITE)
  121.         elif self.cyrils_black & chess.BB_SQUARES[square]:
  122.             return chess.Piece(CYRIL, chess.BLACK)
  123.         elif self.eves_white & chess.BB_SQUARES[square]:
  124.             return chess.Piece(EVE, chess.WHITE)
  125.         elif self.eves_black & chess.BB_SQUARES[square]:
  126.             return chess.Piece(EVE, chess.BLACK)
  127.         return super().piece_at(square)
  128.  
  129.     def generate_pseudo_legal_moves(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboard = BB_ALL) -> Iterator[Move]:
  130.         our_pieces = self.occupied_co[self.turn]
  131.         if self.turn == chess.WHITE:
  132.             our_amazons = self.amazons_white
  133.             our_cyrils = self.cyrils_white
  134.             our_eves = self.eves_white
  135.         else:
  136.             our_amazons = self.amazons_black
  137.             our_cyrils = self.cyrils_black
  138.             our_eves = self.eves_black
  139.    
  140.         # Generování tahů pro amazonky
  141.         for from_square in chess.scan_forward(our_amazons & from_mask):
  142.             attacks = self.amazon_attacks(from_square)
  143.             valid_moves = attacks & ~our_pieces & to_mask
  144.             for to_square in chess.scan_forward(valid_moves):
  145.                 yield Move(from_square, to_square)
  146.    
  147.         # Generování tahů pro Cyrily
  148.         for from_square in chess.scan_forward(our_cyrils & from_mask):
  149.             attacks = self.cyril_attacks(from_square)
  150.             valid_moves = attacks & ~our_pieces & to_mask
  151.             for to_square in chess.scan_forward(valid_moves):
  152.                 yield Move(from_square, to_square)
  153.    
  154.         # Generování tahů pro Evy
  155.         for from_square in chess.scan_forward(our_eves & from_mask):
  156.             attacks = self.eve_attacks(from_square)
  157.             valid_moves = attacks & ~our_pieces & to_mask
  158.             for to_square in chess.scan_forward(valid_moves):
  159.                 yield Move(from_square, to_square)
  160.    
  161.         # Generování tahů pro standardní figury
  162.         for move in super().generate_pseudo_legal_moves(from_mask, to_mask):
  163.             piece = self.piece_at(move.from_square)
  164.             if piece and piece.piece_type not in [AMAZON, CYRIL, EVE]:
  165.                 yield move
  166.  
  167.     def queen_attacks(self, square):
  168.         return self.bishop_attacks(square) | self.rook_attacks(square)
  169.  
  170.     def bishop_attacks(self, square):
  171.         return chess.BB_DIAG_ATTACKS[square][self.occupied & chess.BB_DIAG_MASKS[square]]
  172.  
  173.     def rook_attacks(self, square):
  174.         return (chess.BB_RANK_ATTACKS[square][self.occupied & chess.BB_RANK_MASKS[square]] |
  175.                 chess.BB_FILE_ATTACKS[square][self.occupied & chess.BB_FILE_MASKS[square]])
  176.  
  177.     def amazon_attacks(self, square):
  178.         return self.queen_attacks(square) | chess.BB_KNIGHT_ATTACKS[square]
  179.  
  180.     def cyril_attacks(self, square):
  181.         return self.rook_attacks(square) | chess.BB_KNIGHT_ATTACKS(square)
  182.  
  183.     def eve_attacks(self, square):
  184.         return self.bishop_attacks(square) | chess.BB_KNIGHT_ATTACKS(square)
  185.  
  186.     def is_pseudo_legal(self, move):
  187.         from_square = move.from_square
  188.         to_square = move.to_square
  189.         piece = self.piece_at(from_square)
  190.    
  191.         if not piece or piece.color != self.turn:
  192.             return False
  193.    
  194.         if self.occupied_co[self.turn] & chess.BB_SQUARES[to_square]:
  195.             return False
  196.    
  197.         if self.is_castling(move):
  198.             return True
  199.    
  200.         if piece.piece_type == AMAZON:
  201.             return bool(self.amazon_attacks(from_square) & chess.BB_SQUARES[to_square])
  202.         elif piece.piece_type == CYRIL:
  203.             return bool(self.cyril_attacks(from_square) & chess.BB_SQUARES[to_square])
  204.         elif piece.piece_type == EVE:
  205.             return bool(self.eve_attacks(from_square) & chess.BB_SQUARES[to_square])
  206.         else:
  207.             return super().is_pseudo_legal(move)
  208.  
  209.     def is_legal(self, move):
  210.         if not self.is_pseudo_legal(move):
  211.             return False
  212.  
  213.         from_square = move.from_square
  214.         to_square = move.to_square
  215.         piece = self.piece_at(from_square)
  216.         captured_piece = self.piece_at(to_square)
  217.  
  218.         self.clear_square(from_square)
  219.         self.clear_square(to_square)
  220.         self._set_piece_at(to_square, piece.piece_type, piece.color)
  221.  
  222.         king_square = to_square if piece.piece_type == chess.KING else self.king(self.turn)
  223.         is_check = self._is_attacked_by(not self.turn, king_square)
  224.  
  225.         self.clear_square(to_square)
  226.         self._set_piece_at(from_square, piece.piece_type, piece.color)
  227.         if captured_piece:
  228.             self._set_piece_at(to_square, captured_piece.piece_type, captured_piece.color)
  229.  
  230.         if is_check:
  231.             attackers = self.attackers(not self.turn, king_square)
  232.     #        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)]}")
  233.  
  234.         return not is_check
  235.  
  236.     def _is_attacked_by(self, color, square):
  237.         attackers = self.attackers(color, square)
  238.         return bool(attackers)
  239.  
  240.     def attackers(self, color, square):
  241.         attackers = chess.BB_EMPTY
  242.  
  243.         knights = self.knights & self.occupied_co[color]
  244.         attackers |= knights & chess.BB_KNIGHT_ATTACKS[square]
  245.  
  246.         king = self.kings & self.occupied_co[color]
  247.         attackers |= king & chess.BB_KING_ATTACKS[square]
  248.  
  249.         pawns = self.pawns & self.occupied_co[color]
  250.         if color == chess.WHITE:
  251.             attackers |= pawns & chess.BB_PAWN_ATTACKS[chess.BLACK][square]
  252.         else:
  253.             attackers |= pawns & chess.BB_PAWN_ATTACKS[chess.WHITE][square]
  254.  
  255.         queens = self.queens & self.occupied_co[color]
  256.         bishops = (self.bishops | queens) & self.occupied_co[color]
  257.         rooks = (self.rooks | queens) & self.occupied_co[color]
  258.  
  259.         attackers |= chess.BB_DIAG_ATTACKS[square][self.occupied & chess.BB_DIAG_MASKS[square]] & bishops
  260.         attackers |= (chess.BB_RANK_ATTACKS[square][self.occupied & chess.BB_RANK_MASKS[square]] |
  261.                       chess.BB_FILE_ATTACKS[square][self.occupied & chess.BB_FILE_MASKS[square]]) & rooks
  262.  
  263.         amazons = self.amazons_white if color == chess.WHITE else self.amazons_black
  264.         for amazon_square in chess.scan_forward(amazons):
  265.             if self.amazon_attacks(amazon_square) & chess.BB_SQUARES[square]:
  266.                 attackers |= chess.BB_SQUARES[amazon_square]
  267.  
  268.         cyrils = self.cyrils_white if color == chess.WHITE else self.cyrils_black
  269.         for cyril_square in chess.scan_forward(cyrils):
  270.             if self.cyril_attacks(cyril_square) & chess.BB_SQUARES[square]:
  271.                 attackers |= chess.BB_SQUARES[cyril_square]
  272.  
  273.         eves = self.eves_white if color == chess.WHITE else self.eves_black
  274.         for eve_square in chess.scan_forward(eves):
  275.             if self.eve_attacks(eve_square) & chess.BB_SQUARES[square]:
  276.                 attackers |= chess.BB_SQUARES[eve_square]
  277.  
  278.         return attackers
  279.  
  280.     def push(self, move):
  281.         if not self.is_legal(move):
  282.             raise ValueError(f"Move {move} is not legal in position {self.fen()}")
  283.  
  284.         piece = self.piece_at(move.from_square)
  285.         captured_piece = self.piece_at(move.to_square)
  286.  
  287.         self.clear_square(move.from_square)
  288.         self.clear_square(move.to_square)
  289.         self._set_piece_at(move.to_square, piece.piece_type, piece.color)
  290.  
  291.         self.turn = not self.turn
  292.  
  293.         self.move_stack.append((move, captured_piece))
  294.  
  295.     def pop(self):
  296.         if not self.move_stack:
  297.             return None
  298.  
  299.         move, captured_piece = self.move_stack.pop()
  300.  
  301.         piece = self.piece_at(move.to_square)
  302.        
  303.         self.clear_square(move.from_square)
  304.         self.clear_square(move.to_square)
  305.  
  306.         self._set_piece_at(move.from_square, piece.piece_type, piece.color)
  307.  
  308.         if captured_piece:
  309.             self._set_piece_at(move.to_square, captured_piece.piece_type, captured_piece.color)
  310.  
  311.         self.turn = not self.turn
  312.  
  313.         return move
  314.  
  315.     def is_check(self):
  316.         king_square = self.king(self.turn)
  317.         if king_square is None:
  318.             return False
  319.         is_check = self._is_attacked_by(not self.turn, king_square)
  320.   #      print(f"[DEBUG] Checking if position is check: FEN: {self.fen()}, King at {chess.SQUARE_NAMES[king_square]}, is_check: {is_check}")
  321.         return is_check
  322.  
  323.     def is_checkmate(self):
  324.         if not self.is_check():
  325.   #          print(f"[DEBUG] Position is not check, hence not checkmate: FEN: {self.fen()}")
  326.             return False
  327.         legal_moves = list(self.generate_legal_moves())
  328.  #       print(f"[DEBUG] Checking if position is checkmate: FEN: {self.fen()}, Legal moves: {legal_moves}")
  329.         return len(legal_moves) == 0
  330.  
  331.     def is_game_over(self):
  332.         return self.is_checkmate() or self.is_stalemate() or self.is_insufficient_material()
  333.  
  334.     def is_stalemate(self):
  335.         if self.is_check():
  336.             return False
  337.         legal_moves = list(self.generate_legal_moves())
  338.   #      print(f"[DEBUG] Checking if position is stalemate: FEN: {self.fen()}, Legal moves: {legal_moves}")
  339.         return len(legal_moves) == 0
  340.    
  341.     def is_insufficient_material(self):
  342.         return (self.pawns | self.rooks | self.queens | self.amazons_white | self.amazons_black |
  343.                 self.cyrils_white | self.cyrils_black | self.eves_white | self.eves_black) == 0 and (
  344.             chess.popcount(self.occupied) <= 3
  345.         )
  346.  
  347.     def generate_legal_moves(self, from_mask=chess.BB_ALL, to_mask=chess.BB_ALL):
  348.         for move in self.generate_pseudo_legal_moves(from_mask, to_mask):
  349.             if self.is_legal(move):
  350.       #          print(f"[DEBUG] Legal move: {move}")
  351.                 yield move
  352.        #     else:
  353.         #        print(f"[DEBUG] Illegal move: {move}")
  354.  
  355.     def debug_amazons(self):
  356.         pass
  357.       #  print(f"Bitboard bílých amazonek: {format(self.amazons_white, '064b')}")
  358.     #   print(f"Bitboard černých amazonek: {format(self.amazons_black, '064b')}")
  359.         for square in chess.SQUARES:
  360.             pass
  361.        #     if self.amazons_white & chess.BB_SQUARES[square]:
  362.        #         print(f"Bílá amazonka na {chess.SQUARE_NAMES[square]}")
  363.      #       if self.amazons_black & chess.BB_SQUARES[square]:
  364.        #         print(f"Černá amazonka na {chess.SQUARE_NAMES[square]}")
  365.  
  366.     def debug_cyrils(self):
  367.         pass
  368.        # print(f"Bitboard bílých Cyrils: {format(self.cyrils_white, '064b')}")
  369.        # print(f"Bitboard černých Cyrils: {format(self.cyrils_black, '064b')}")
  370.        # for square in chess.SQUARES:
  371.        #     if self.cyrils_white & chess.BB_SQUARES[square]:
  372.       #          print(f"Bílý Cyril na {chess.SQUARE_NAMES[square]}")
  373.      #       if self.cyrils_black & chess.BB_SQUARES[square]:
  374.     #            print(f"Černý Cyril na {chess.SQUARE_NAMES[square]}")
  375.  
  376.     def debug_eves(self):
  377.         pass
  378.     #    print(f"Bitboard bílých Eves: {format(self.eves_white, '064b')}")
  379.      #   print(f"Bitboard černých Eves: {format(self.eves_black, '064b')}")
  380.       #  for square in chess.SQUARES:
  381.       #      if self.eves_white & chess.BB_SQUARES[square]:
  382.           #      print(f"Bílá Eve na {chess.SQUARE_NAMES[square]}")
  383.        #     if self.eves_black & chess.BB_SQUARES[square]:
  384.        #         print(f"Černá Eve na {chess.SQUARE_NAMES[square]}")
  385.  
  386.     def piece_symbol(self, piece):
  387.         if piece is None:
  388.             return '.'
  389.         if piece.piece_type == AMAZON:
  390.             return 'A' if piece.color == chess.WHITE else 'a'
  391.         if piece.piece_type == CYRIL:
  392.             return 'C' if piece.color == chess.WHITE else 'c'
  393.         if piece.piece_type == EVE:
  394.             return 'E' if piece.color == chess.WHITE else 'e'
  395.         return piece.symbol()
  396.  
  397.     def piece_type_at(self, square):
  398.         if (self.amazons_white | self.amazons_black) & chess.BB_SQUARES[square]:
  399.             return AMAZON
  400.         if (self.cyrils_white | self.cyrils_black) & chess.BB_SQUARES[square]:
  401.             return CYRIL
  402.         if (self.eves_white | self.eves_black) & chess.BB_SQUARES[square]:
  403.             return EVE
  404.         return super().piece_type_at(square)
  405.  
  406.     def color_at(self, square):
  407.         if self.amazons_white & chess.BB_SQUARES[square]:
  408.             return chess.WHITE
  409.         if self.amazons_black & chess.BB_SQUARES[square]:
  410.             return chess.BLACK
  411.         if self.cyrils_white & chess.BB_SQUARES[square]:
  412.             return chess.WHITE
  413.         if self.cyrils_black & chess.BB_SQUARES[square]:
  414.             return chess.BLACK
  415.         if self.eves_white & chess.BB_SQUARES[square]:
  416.             return chess.WHITE
  417.         if self.eves_black & chess.BB_SQUARES[square]:
  418.             return chess.BLACK
  419.         return super().color_at(square)
  420.  
  421.     @property
  422.     def legal_moves(self):
  423.         return list(self.generate_legal_moves())
  424.  
  425.     def __str__(self):
  426.         builder = []
  427.         for square in chess.SQUARES_180:
  428.             piece = self.piece_at(square)
  429.             symbol = self.piece_symbol(piece) if piece else '.'
  430.             builder.append(symbol)
  431.             if chess.square_file(square) == 7:
  432.                 if square != chess.H1:
  433.                     builder.append('\n')
  434.         return ''.join(builder)
  435.  
  436.     def print_all_possible_moves(self):
  437.         pass
  438.     #    print(f"[DEBUG] All possible moves for FEN: {self.fen()}")
  439.   #      for move in self.generate_pseudo_legal_moves():
  440.    #         print(f"Move: {move}, Is legal: {self.is_legal(move)}")
  441.  
  442. def simplify_fen_string(fen):
  443.     parts = fen.split(' ')
  444.     return ' '.join(parts[:4])  # Zachováváme pouze informace o pozici, barvě na tahu, rošádách a en passant
  445.  
  446. def format_time(seconds):
  447.     hours, remainder = divmod(seconds, 3600)
  448.     minutes, seconds = divmod(remainder, 60)
  449.     return f"{int(hours):02d}h {int(minutes):02d}m {int(seconds):02d}s"
  450.  
  451. def print_elapsed_time(stop_event, start_time):
  452.     while not stop_event.is_set():
  453.         elapsed_time = time.time() - start_time
  454.         print(f"\rUplynulý čas: {format_time(elapsed_time)}", end="", flush=True)
  455.         time.sleep(1)
  456.  
  457. def format_time(seconds):
  458.     hours, remainder = divmod(seconds, 3600)
  459.     minutes, seconds = divmod(remainder, 60)
  460.     return f"{int(hours):02d}h {int(minutes):02d}m {int(seconds):02d}s"
  461.  
  462. def print_elapsed_time(stop_event, start_time):
  463.     while not stop_event.is_set():
  464.         elapsed_time = time.time() - start_time
  465.         print(f"\rUplynulý čas: {format_time(elapsed_time)}", end="", flush=True)
  466.         time.sleep(1)
  467.  
  468.  
  469. import chess
  470. from typing import Dict
  471. import time
  472.  
  473.  
  474. def format_time(seconds):
  475.     hours, remainder = divmod(seconds, 3600)
  476.     minutes, seconds = divmod(remainder, 60)
  477.     return f"{int(hours):02d}h {int(minutes):02d}m {int(seconds):02d}s"
  478.  
  479. def simplify_fen(fen):
  480.     return ' '.join(fen.split()[:4])
  481.  
  482.  
  483. import threading
  484. import time
  485.  
  486. def print_elapsed_time(stop_event, start_time):
  487.     while not stop_event.is_set():
  488.         elapsed_time = time.time() - start_time
  489.         print(f"\rUplynulý čas: {format_time(elapsed_time)}", end="", flush=True)
  490.         time.sleep(1)
  491.  
  492.  
  493. def calculate_optimal_moves(start_fen: str) -> Dict[str, int]:
  494.     print("Funkce calculate_optimal_moves byla zavolána")
  495.     print(f"Počáteční FEN: {start_fen}")
  496.    
  497.     board = CustomBoard(start_fen)
  498.     POZ = {1: simplify_fen_string(start_fen)}
  499.     AR = {simplify_fen_string(start_fen): {'used': 0, 'to_end': None, 'depth': 0}}
  500.     N = 1
  501.     M = 0
  502.  
  503.     start_time = time.time()
  504.     current_depth = 0
  505.     positions_at_depth = 0
  506.     depth_start_time = start_time
  507.  
  508.     stop_event = threading.Event()
  509.     timer_thread = threading.Thread(target=print_elapsed_time, args=(stop_event, start_time))
  510.     timer_thread.start()
  511.  
  512.     try:
  513.         print("Začínám generovat pozice...")
  514.        
  515.         # Generate all positions
  516.         while M < N:
  517.             M += 1
  518.             current_fen = POZ[M]
  519.             board.set_custom_fen(current_fen)
  520.             simplified_current_fen = simplify_fen_string(current_fen)
  521.  
  522.             if AR[simplified_current_fen]['depth'] > current_depth:
  523.                 depth_time = time.time() - depth_start_time
  524.                 print(f"\nHloubka {current_depth}: {positions_at_depth} pozic, Čas hloubky: {format_time(depth_time)}")
  525.                 current_depth = AR[simplified_current_fen]['depth']
  526.                 positions_at_depth = 0
  527.                 depth_start_time = time.time()
  528.  
  529.             positions_at_depth += 1
  530.  
  531.             if AR[simplified_current_fen]['used'] == 0:
  532.                 AR[simplified_current_fen]['used'] = 1
  533.                 legal_moves = list(board.legal_moves)
  534.                 for move in legal_moves:
  535.                     board.push(move)
  536.                     POZ2 = board.fen()
  537.                     simplified_POZ2 = simplify_fen_string(POZ2)
  538.  
  539.                     if simplified_POZ2 not in AR:
  540.                         N += 1
  541.                         POZ[N] = simplified_POZ2
  542.                         AR[simplified_POZ2] = {'used': 0, 'to_end': None, 'depth': AR[simplified_current_fen]['depth'] + 1}
  543.  
  544.                     board.pop()
  545.  
  546.         depth_time = time.time() - depth_start_time
  547.         print(f"\nHloubka {current_depth}: {positions_at_depth} pozic, Čas hloubky: {format_time(depth_time)}")
  548.         print(f"Generování pozic dokončeno. Celkový počet pozic: {N}")
  549.  
  550.         # Initial evaluation
  551.         print("\nZačínám počáteční ohodnocení...")
  552.         stalemates = 0
  553.         checkmates = 0
  554.         for i in range(1, N + 1):
  555.             current_fen = POZ[i]
  556.             board.set_custom_fen(current_fen)
  557.             simplified_current_fen = simplify_fen_string(current_fen)
  558.  
  559.             if board.is_checkmate():
  560.                 AR[simplified_current_fen]['to_end'] = -1000 if board.turn == chess.WHITE else 1000
  561.                 checkmates += 1
  562.             elif board.is_stalemate() or board.is_insufficient_material():
  563.                 AR[simplified_current_fen]['to_end'] = 0
  564.                 stalemates += 1
  565.  
  566.         print(f"Počáteční ohodnocení: Maty: {checkmates}, Paty: {stalemates}, Normální pozice: {N - checkmates - stalemates}")
  567.  
  568.         # Iterative evaluation
  569.         print("\nZačínám iterativní ohodnocení...")
  570.         iteration = 0
  571.         changed = True
  572.         while changed:
  573.             iteration += 1
  574.             changed = False
  575.             changed_positions = 0
  576.             iteration_start_time = time.time()
  577.  
  578.             for i in range(1, N + 1):
  579.                 current_fen = POZ[i]
  580.                 board.set_custom_fen(current_fen)
  581.                 simplified_current_fen = simplify_fen_string(current_fen)
  582.  
  583.                 if AR[simplified_current_fen]['to_end'] is None:
  584.                     legal_moves = list(board.legal_moves)
  585.                     all_moves_evaluated = True
  586.                     best_value = 1001 if board.turn == chess.BLACK else -1001
  587.  
  588.                     for move in legal_moves:
  589.                         board.push(move)
  590.                         POZ2 = board.fen()
  591.                         simplified_POZ2 = simplify_fen_string(POZ2)
  592.                        
  593.                         if AR[simplified_POZ2]['to_end'] is None:
  594.                             all_moves_evaluated = False
  595.                             break
  596.                        
  597.                         if board.turn == chess.WHITE:
  598.                             best_value = max(best_value, -AR[simplified_POZ2]['to_end'])
  599.                         else:
  600.                             best_value = min(best_value, -AR[simplified_POZ2]['to_end'])
  601.                        
  602.                         board.pop()
  603.  
  604.                     if all_moves_evaluated:
  605.                         AR[simplified_current_fen]['to_end'] = best_value
  606.                         changed = True
  607.                         changed_positions += 1
  608.  
  609.             iteration_time = time.time() - iteration_start_time
  610.             unevaluated = sum(1 for v in AR.values() if v['to_end'] is None)
  611.            
  612.             print(f"\nIterace {iteration}: Změněno {changed_positions} pozic")
  613.             print(f"Čas iterace: {format_time(iteration_time)}")
  614.             print(f"Neohodnocené pozice: {unevaluated}")
  615.  
  616.         print("\nVýpočet dokončen.")
  617.         return {fen: data['to_end'] for fen, data in AR.items() if data['to_end'] is not None}
  618.  
  619.     finally:
  620.         stop_event.set()
  621.         timer_thread.join()
  622.  
  623. # Helper function to format time
  624. def format_time(seconds):
  625.     hours, remainder = divmod(seconds, 3600)
  626.     minutes, seconds = divmod(remainder, 60)
  627.     return f"{int(hours):02d}h {int(minutes):02d}m {int(seconds):02d}s"
  628.  
  629. if __name__ == "__main__":
  630.     start_fen = "8/3k4/8/8/8/8/A7/6K1 w - - 0 1"
  631.     AR = calculate_optimal_moves(start_fen)
  632.    
  633.     # Výpis výsledků
  634.     print("\nVýsledky:")
  635.     for fen, hodnota in AR.items():
  636.         if hodnota != 0:
  637.             print(f"FEN: {fen}")
  638.             print(f"Hodnota: {hodnota}")
  639.             print()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement