Advertisement
max2201111

joo!! 987 1,6

Sep 4th, 2024
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 33.14 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.         self.debug_amazons()
  30.         self.debug_cyrils()
  31.         self.debug_eves()
  32.  
  33.     def clear_square(self, square):
  34.         super()._remove_piece_at(square)
  35.         self.amazons_white &= ~chess.BB_SQUARES[square]
  36.         self.amazons_black &= ~chess.BB_SQUARES[square]
  37.         self.cyrils_white &= ~chess.BB_SQUARES[square]
  38.         self.cyrils_black &= ~chess.BB_SQUARES[square]
  39.         self.eves_white &= ~chess.BB_SQUARES[square]
  40.         self.eves_black &= ~chess.BB_SQUARES[square]
  41.  
  42.     def set_custom_fen(self, fen):
  43.         parts = fen.split()
  44.         board_part = parts[0]
  45.    
  46.         self.clear()
  47.         self.amazons_white = chess.BB_EMPTY
  48.         self.amazons_black = chess.BB_EMPTY
  49.         self.cyrils_white = chess.BB_EMPTY
  50.         self.cyrils_black = chess.BB_EMPTY
  51.         self.eves_white = chess.BB_EMPTY
  52.         self.eves_black = chess.BB_EMPTY
  53.    
  54.         square = 56
  55.         for c in board_part:
  56.             if c == '/':
  57.                 square -= 16
  58.             elif c.isdigit():
  59.                 square += int(c)
  60.             else:
  61.                 color = chess.WHITE if c.isupper() else chess.BLACK
  62.                 if c.upper() == 'A':
  63.                     if color == chess.WHITE:
  64.                         self.amazons_white |= chess.BB_SQUARES[square]
  65.                     else:
  66.                         self.amazons_black |= chess.BB_SQUARES[square]
  67.                     piece_type = AMAZON
  68.                 elif c.upper() == 'C':
  69.                     if color == chess.WHITE:
  70.                         self.cyrils_white |= chess.BB_SQUARES[square]
  71.                     else:
  72.                         self.cyrils_black |= chess.BB_SQUARES[square]
  73.                     piece_type = CYRIL
  74.                 elif c.upper() == 'E':
  75.                     if color == chess.WHITE:
  76.                         self.eves_white |= chess.BB_SQUARES[square]
  77.                     else:
  78.                         self.eves_black |= chess.BB_SQUARES[square]
  79.                     piece_type = EVE
  80.                 elif c == 'P' and chess.square_rank(square) == 7:
  81.                     piece_type = AMAZON
  82.                     color = chess.WHITE
  83.                 elif c == 'p' and chess.square_rank(square) == 0:
  84.                     piece_type = AMAZON
  85.                     color = chess.BLACK
  86.                 else:
  87.                     piece_type = chess.PIECE_SYMBOLS.index(c.lower())
  88.                
  89.                 self._set_piece_at(square, piece_type, color)
  90.                 square += 1
  91.    
  92.         self.turn = chess.WHITE if parts[1] == 'w' else chess.BLACK
  93.         self.castling_rights = chess.BB_EMPTY
  94.         if '-' not in parts[2]:
  95.             if 'K' in parts[2]: self.castling_rights |= chess.BB_H1
  96.             if 'Q' in parts[2]: self.castling_rights |= chess.BB_A1
  97.             if 'k' in parts[2]: self.castling_rights |= chess.BB_H8
  98.             if 'q' in parts[2]: self.castling_rights |= chess.BB_A8
  99.         self.ep_square = chess.parse_square(parts[3]) if parts[3] != '-' else None
  100.            
  101.  
  102.     def _set_piece_at(self, square: chess.Square, piece_type: PieceType, color: Color) -> None:
  103.         self.clear_square(square)
  104.         super()._set_piece_at(square, piece_type, color)
  105.         if piece_type == AMAZON:
  106.             if color == chess.WHITE:
  107.                 self.amazons_white |= chess.BB_SQUARES[square]
  108.             else:
  109.                 self.amazons_black |= chess.BB_SQUARES[square]
  110.         elif piece_type == CYRIL:
  111.             if color == chess.WHITE:
  112.                 self.cyrils_white |= chess.BB_SQUARES[square]
  113.             else:
  114.                 self.cyrils_black |= chess.BB_SQUARES[square]
  115.         elif piece_type == EVE:
  116.             if color == chess.WHITE:
  117.                 self.eves_white |= chess.BB_SQUARES[square]
  118.             else:
  119.                 self.eves_black |= chess.BB_SQUARES[square]
  120.  
  121.     def piece_at(self, square: chess.Square) -> Optional[chess.Piece]:
  122.         if self.amazons_white & chess.BB_SQUARES[square]:
  123.             return chess.Piece(AMAZON, chess.WHITE)
  124.         elif self.amazons_black & chess.BB_SQUARES[square]:
  125.             return chess.Piece(AMAZON, chess.BLACK)
  126.         elif self.cyrils_white & chess.BB_SQUARES[square]:
  127.             return chess.Piece(CYRIL, chess.WHITE)
  128.         elif self.cyrils_black & chess.BB_SQUARES[square]:
  129.             return chess.Piece(CYRIL, chess.BLACK)
  130.         elif self.eves_white & chess.BB_SQUARES[square]:
  131.             return chess.Piece(EVE, chess.WHITE)
  132.         elif self.eves_black & chess.BB_SQUARES[square]:
  133.             return chess.Piece(EVE, chess.BLACK)
  134.         return super().piece_at(square)
  135.  
  136.     def generate_pseudo_legal_moves(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboard = BB_ALL) -> Iterator[Move]:
  137.         our_pieces = self.occupied_co[self.turn]
  138.         if self.turn == chess.WHITE:
  139.             our_amazons = self.amazons_white
  140.             our_cyrils = self.cyrils_white
  141.             our_eves = self.eves_white
  142.         else:
  143.             our_amazons = self.amazons_black
  144.             our_cyrils = self.cyrils_black
  145.             our_eves = self.eves_black
  146.    
  147.         # Generování tahů pro amazonky
  148.         for from_square in chess.scan_forward(our_amazons & from_mask):
  149.             attacks = self.amazon_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 Cyrily
  155.         for from_square in chess.scan_forward(our_cyrils & from_mask):
  156.             attacks = self.cyril_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 Evy
  162.         for from_square in chess.scan_forward(our_eves & from_mask):
  163.             attacks = self.eve_attacks(from_square)
  164.             valid_moves = attacks & ~our_pieces & to_mask
  165.             for to_square in chess.scan_forward(valid_moves):
  166.                 yield Move(from_square, to_square)
  167.    
  168.         # Generování tahů pro standardní figury
  169.         for move in super().generate_pseudo_legal_moves(from_mask, to_mask):
  170.             piece = self.piece_at(move.from_square)
  171.             if piece and piece.piece_type not in [AMAZON, CYRIL, EVE]:
  172.                 yield move
  173.  
  174.     def queen_attacks(self, square):
  175.         return self.bishop_attacks(square) | self.rook_attacks(square)
  176.  
  177.     def bishop_attacks(self, square):
  178.         return chess.BB_DIAG_ATTACKS[square][self.occupied & chess.BB_DIAG_MASKS[square]]
  179.  
  180.     def rook_attacks(self, square):
  181.         return (chess.BB_RANK_ATTACKS[square][self.occupied & chess.BB_RANK_MASKS[square]] |
  182.                 chess.BB_FILE_ATTACKS[square][self.occupied & chess.BB_FILE_MASKS[square]])
  183.  
  184.     def amazon_attacks(self, square):
  185.         return self.queen_attacks(square) | chess.BB_KNIGHT_ATTACKS[square]
  186.  
  187.     def cyril_attacks(self, square):
  188.         return self.rook_attacks(square) | chess.BB_KNIGHT_ATTACKS[quare]
  189.  
  190.     def eve_attacks(self, square):
  191.         return self.bishop_attacks(square) | chess.BB_KNIGHT_ATTACKS[square]
  192.  
  193.     def is_pseudo_legal(self, move):
  194.         from_square = move.from_square
  195.         to_square = move.to_square
  196.         piece = self.piece_at(from_square)
  197.    
  198.         if not piece or piece.color != self.turn:
  199.             return False
  200.    
  201.         if self.occupied_co[self.turn] & chess.BB_SQUARES[to_square]:
  202.             return False
  203.    
  204.         if self.is_castling(move):
  205.             return True
  206.    
  207.         if piece.piece_type == AMAZON:
  208.             return bool(self.amazon_attacks(from_square) & chess.BB_SQUARES[to_square])
  209.         elif piece.piece_type == CYRIL:
  210.             return bool(self.cyril_attacks(from_square) & chess.BB_SQUARES[to_square])
  211.         elif piece.piece_type == EVE:
  212.             return bool(self.eve_attacks(from_square) & chess.BB_SQUARES[to_square])
  213.         else:
  214.             return super().is_pseudo_legal(move)
  215.  
  216.     def is_legal(self, move):
  217.         if not self.is_pseudo_legal(move):
  218.             return False
  219.    
  220.         from_square = move.from_square
  221.         to_square = move.to_square
  222.         piece = self.piece_at(from_square)
  223.         captured_piece = self.piece_at(to_square)
  224.    
  225.         # Kontrola pro všechny figury: nelze brát figuru stejné barvy
  226.         if captured_piece and captured_piece.color == piece.color:
  227.             return False
  228.    
  229.         # Dočasně provést tah
  230.         self.clear_square(from_square)
  231.         self._set_piece_at(to_square, piece.piece_type, piece.color)
  232.    
  233.         # Najít pozici krále
  234.         king_square = to_square if piece.piece_type == chess.KING else self.king(self.turn)
  235.    
  236.         # Kontrola, zda je král v šachu po tahu
  237.         is_check = self._is_attacked_by(not self.turn, king_square) if king_square is not None else False
  238.    
  239.         # Vrátit pozici do původního stavu
  240.         self.clear_square(to_square)
  241.         self._set_piece_at(from_square, piece.piece_type, piece.color)
  242.         if captured_piece:
  243.             self._set_piece_at(to_square, captured_piece.piece_type, captured_piece.color)
  244.    
  245.         return not is_check
  246.        
  247.  
  248.     def _is_attacked_by(self, color, square):
  249.         attackers = self.attackers(color, square)
  250.         return bool(attackers)
  251.  
  252.     def attackers(self, color: Color, square: chess.Square) -> Bitboard:
  253.         if square is None:
  254.             return chess.BB_EMPTY
  255.    
  256.         attackers = chess.BB_EMPTY
  257.         occupied = self.occupied
  258.         occupied_co = self.occupied_co[color]
  259.    
  260.         # Jezdci
  261.         attackers |= chess.BB_KNIGHT_ATTACKS[square] & self.knights & occupied_co
  262.    
  263.         # Král
  264.         attackers |= chess.BB_KING_ATTACKS[square] & self.kings & occupied_co
  265.    
  266.         # Pěšci
  267.         if color == chess.WHITE:
  268.             attackers |= chess.BB_PAWN_ATTACKS[chess.BLACK][square] & self.pawns & occupied_co
  269.         else:
  270.             attackers |= chess.BB_PAWN_ATTACKS[chess.WHITE][square] & self.pawns & occupied_co
  271.    
  272.         # Střelcové útoky (včetně dam a amazonek)
  273.         bishop_attacks = chess.BB_DIAG_ATTACKS[square][occupied & chess.BB_DIAG_MASKS[square]]
  274.         attackers |= bishop_attacks & ((self.bishops | self.queens) & occupied_co)
  275.    
  276.         # Věžové útoky (včetně dam, amazonek a cyrilů)
  277.         rook_attacks = (
  278.             chess.BB_RANK_ATTACKS[square][occupied & chess.BB_RANK_MASKS[square]] |
  279.             chess.BB_FILE_ATTACKS[square][occupied & chess.BB_FILE_MASKS[square]]
  280.         )
  281.         attackers |= rook_attacks & ((self.rooks | self.queens) & occupied_co)
  282.    
  283.         # Amazonky (Dáma + Jezdec)
  284.         amazons = self.amazons_white if color == chess.WHITE else self.amazons_black
  285.         amazon_attacks = bishop_attacks | rook_attacks | chess.BB_KNIGHT_ATTACKS[square]
  286.         attackers |= amazon_attacks & amazons
  287.    
  288.         # Cyrilové (Věž + Jezdec)
  289.         cyrils = self.cyrils_white if color == chess.WHITE else self.cyrils_black
  290.         cyril_attacks = rook_attacks | chess.BB_KNIGHT_ATTACKS[square]
  291.         attackers |= cyril_attacks & cyrils
  292.    
  293.         # Evy (Střelec + Jezdec)
  294.         eves = self.eves_white if color == chess.WHITE else self.eves_black
  295.         eve_attacks = bishop_attacks | chess.BB_KNIGHT_ATTACKS[square]
  296.         attackers |= eve_attacks & eves
  297.    
  298.         return attackers
  299.        
  300.     def push(self, move):
  301.         if not self.is_legal(move):
  302.             raise ValueError(f"Move {move} is not legal in position {self.fen()}")
  303.  
  304.         piece = self.piece_at(move.from_square)
  305.         captured_piece = self.piece_at(move.to_square)
  306.  
  307.         self.clear_square(move.from_square)
  308.         self.clear_square(move.to_square)
  309.         self._set_piece_at(move.to_square, piece.piece_type, piece.color)
  310.  
  311.         self.turn = not self.turn
  312.  
  313.         self.move_stack.append((move, captured_piece))
  314.  
  315.     def pop(self):
  316.         if not self.move_stack:
  317.             return None
  318.  
  319.         move, captured_piece = self.move_stack.pop()
  320.  
  321.         piece = self.piece_at(move.to_square)
  322.        
  323.         self.clear_square(move.from_square)
  324.         self.clear_square(move.to_square)
  325.  
  326.         self._set_piece_at(move.from_square, piece.piece_type, piece.color)
  327.  
  328.         if captured_piece:
  329.             self._set_piece_at(move.to_square, captured_piece.piece_type, captured_piece.color)
  330.  
  331.         self.turn = not self.turn
  332.  
  333.         return move
  334.  
  335.     def is_check(self):
  336.         king_square = self.king(self.turn)
  337.         if king_square is None:
  338.             return False
  339.         is_check = self._is_attacked_by(not self.turn, king_square)
  340.         return is_check
  341.  
  342.     def is_checkmate(self):
  343.         if not self.is_check():
  344.             return False
  345.         legal_moves = list(self.generate_legal_moves())
  346.         return len(legal_moves) == 0
  347.  
  348.     def is_game_over(self):
  349.         return self.is_checkmate() or self.is_stalemate() or self.is_insufficient_material()
  350.  
  351.     def is_stalemate(self):
  352.         if self.is_check():
  353.             return False
  354.         legal_moves = list(self.generate_legal_moves())
  355.         return len(legal_moves) == 0
  356.    
  357.     def is_insufficient_material(self):
  358.         return (self.pawns | self.rooks | self.queens | self.amazons_white | self.amazons_black |
  359.                 self.cyrils_white | self.cyrils_black | self.eves_white | self.eves_black) == 0 and (
  360.             chess.popcount(self.occupied) <= 3
  361.         )
  362.  
  363.     def generate_legal_moves(self, from_mask=chess.BB_ALL, to_mask=chess.BB_ALL):
  364.         for move in self.generate_pseudo_legal_moves(from_mask, to_mask):
  365.             if self.is_legal(move):
  366.                 yield move
  367.  
  368.     def debug_amazons(self):
  369.         pass
  370.  
  371.     def debug_cyrils(self):
  372.         pass
  373.  
  374.     def debug_eves(self):
  375.         pass
  376.  
  377.     def piece_symbol(self, piece):
  378.         if piece is None:
  379.             return '.'
  380.         if piece.piece_type == AMAZON:
  381.             return 'A' if piece.color == chess.WHITE else 'a'
  382.         if piece.piece_type == CYRIL:
  383.             return 'C' if piece.color == chess.WHITE else 'c'
  384.         if piece.piece_type == EVE:
  385.             return 'E' if piece.color == chess.WHITE else 'e'
  386.         return piece.symbol()
  387.  
  388.     def piece_type_at(self, square):
  389.         if (self.amazons_white | self.amazons_black) & chess.BB_SQUARES[square]:
  390.             return AMAZON
  391.         if (self.cyrils_white | self.cyrils_black) & chess.BB_SQUARES[square]:
  392.             return CYRIL
  393.         if (self.eves_white | self.eves_black) & chess.BB_SQUARES[square]:
  394.             return EVE
  395.         return super().piece_type_at(square)
  396.  
  397.     def color_at(self, square):
  398.         if self.amazons_white & chess.BB_SQUARES[square]:
  399.             return chess.WHITE
  400.         if self.amazons_black & chess.BB_SQUARES[square]:
  401.             return chess.BLACK
  402.         if self.cyrils_white & chess.BB_SQUARES[square]:
  403.             return chess.WHITE
  404.         if self.cyrils_black & chess.BB_SQUARES[square]:
  405.             return chess.BLACK
  406.         if self.eves_white & chess.BB_SQUARES[square]:
  407.             return chess.WHITE
  408.         if self.eves_black & chess.BB_SQUARES[square]:
  409.             return chess.BLACK
  410.         return super().color_at(square)
  411.  
  412.     @property
  413.     def legal_moves(self):
  414.         return list(self.generate_legal_moves())
  415.  
  416.     def __str__(self):
  417.         builder = []
  418.         for square in chess.SQUARES_180:
  419.             piece = self.piece_at(square)
  420.             symbol = self.piece_symbol(piece) if piece else '.'
  421.             builder.append(symbol)
  422.             if chess.square_file(square) == 7:
  423.                 if square != chess.H1:
  424.                     builder.append('\n')
  425.         return ''.join(builder)
  426.  
  427. def format_time(seconds):
  428.     hours, remainder = divmod(seconds, 3600)
  429.     minutes, seconds = divmod(remainder, 60)
  430.     return f"{int(hours):02d}h {int(minutes):02d}m {int(seconds):02d}s"
  431.  
  432. def print_elapsed_time(stop_event, start_time):
  433.     while not stop_event.is_set():
  434.         elapsed_time = time.time() - start_time
  435.         print(f"\rUplynulý čas: {format_time(elapsed_time)}", end="", flush=True)
  436.         time.sleep(1)
  437.  
  438. def simplify_fen(fen):
  439.     return ' '.join(fen.split()[:4])
  440.  
  441. def calculate_optimal_moves(start_fen: str) -> Dict[str, Tuple[int, str]]:
  442.     print("Funkce calculate_optimal_moves byla zavolána8")
  443.     print(f"Počáteční FEN: {start_fen}")
  444.    
  445.     board = CustomBoard(start_fen)
  446.     POZ = {1: simplify_fen(start_fen)}
  447.     AR = {simplify_fen(start_fen): {'used': 0, 'to_end': None, 'depth': 0, 'type': 'normal', 'parent': None}}
  448.     N = 1
  449.     M = 0
  450.  
  451.     start_time = time.time()
  452.     current_depth = 0
  453.     positions_at_depth = {0: 0}
  454.     depth_start_time = start_time
  455.  
  456.     stop_event = threading.Event()
  457.     timer_thread = threading.Thread(target=print_elapsed_time, args=(stop_event, start_time))
  458.     timer_thread.start()
  459.  
  460.     try:
  461.         print("Začínám generovat pozice...")
  462.         print("Počáteční pozice:7")
  463.         print_board(start_fen)
  464.        
  465.         depth_1_positions = []  # Seznam pro ukládání pozic v hloubce 1
  466.  
  467.         # Generate all positions
  468.         while M < N:
  469.             M += 1
  470.             current_fen = POZ[M]
  471.             board.set_custom_fen(current_fen)
  472.             simplified_current_fen = simplify_fen(current_fen)
  473.             current_depth = AR[simplified_current_fen]['depth']
  474.  
  475.             if current_depth not in positions_at_depth:
  476.                 positions_at_depth[current_depth] = 0
  477.                 if current_depth > 0:
  478.                     depth_time = time.time() - depth_start_time
  479.                     total_time = time.time() - start_time
  480.                     print(f"\nHloubka {current_depth - 1}: {positions_at_depth[current_depth - 1]} pozic, "
  481.                           f"Čas hloubky: {format_time(depth_time)} / Celkový čas: {format_time(total_time)}")
  482.                    
  483.                     if current_depth == 1:
  484.                         print("Všechny pozice v hloubce 1:")
  485.                         for pos in depth_1_positions:
  486.                             print_board(pos)
  487.                             print()
  488.                
  489.                 depth_start_time = time.time()
  490.  
  491.             positions_at_depth[current_depth] += 1
  492.  
  493.             if current_depth == 1:
  494.                 depth_1_positions.append(current_fen)
  495.  
  496.             if AR[simplified_current_fen]['used'] == 0:
  497.                 AR[simplified_current_fen]['used'] = 1
  498.                 legal_moves = list(board.legal_moves)
  499.                 for move in legal_moves:
  500.                     board.push(move)
  501.                     POZ2 = board.fen()
  502.                     simplified_POZ2 = simplify_fen(POZ2)
  503.                     if simplified_POZ2 not in AR:
  504.                         N += 1
  505.                         POZ[N] = simplified_POZ2
  506.                         AR[simplified_POZ2] = {
  507.                             'used': 0,
  508.                             'to_end': None,
  509.                             'depth': current_depth + 1,
  510.                             'type': 'normal',
  511.                             'parent': simplified_current_fen
  512.                         }
  513.                     board.pop()
  514.    
  515.         # Print last depth
  516.         depth_time = time.time() - depth_start_time
  517.         total_time = time.time() - start_time
  518.         print(f"\nHloubka {current_depth}: {positions_at_depth[current_depth]} pozic, "
  519.               f"Čas hloubky: {format_time(depth_time)} / Celkový čas: {format_time(total_time)}")
  520.         print(f"Příklad pozice v hloubce {current_depth}:")
  521.         print_board(current_fen)
  522.  
  523.         print(f"Generování pozic dokončeno. Celkový počet pozic: {N}")
  524.  
  525.         # Initial evaluation
  526.         print("\nZačínám počáteční ohodnocení...")
  527.         F_checkmate = 0
  528.         F_stalemate = 0
  529.         F_drawing = 0
  530.         F_check = 0
  531.         F_normal = 0
  532.         for i in range(1, N + 1):
  533.             current_fen = POZ[i]
  534.             board.set_custom_fen(current_fen)
  535.             simplified_current_fen = simplify_fen(current_fen)
  536.  
  537.             if board.is_checkmate():
  538.                 AR[simplified_current_fen]['to_end'] = -1000
  539.                 AR[simplified_current_fen]['type'] = 'checkmate'
  540.                 F_checkmate += 1
  541.             elif board.is_stalemate():
  542.                 AR[simplified_current_fen]['to_end'] = 0
  543.                 AR[simplified_current_fen]['type'] = 'stalemate'
  544.                 F_stalemate += 1
  545.             elif board.is_insufficient_material():
  546.                 AR[simplified_current_fen]['to_end'] = 0
  547.                 AR[simplified_current_fen]['type'] = 'drawing'
  548.                 F_drawing += 1
  549.             elif board.is_check():
  550.                 AR[simplified_current_fen]['to_end'] = None
  551.                 AR[simplified_current_fen]['type'] = 'check'
  552.                 F_check += 1
  553.             else:
  554.                 AR[simplified_current_fen]['to_end'] = None
  555.                 AR[simplified_current_fen]['type'] = 'normal'
  556.                 F_normal += 1
  557.  
  558.         print(f"Počet pozic v matu je {F_checkmate}")
  559.         print(f"Počet pozic v patu je {F_stalemate}")
  560.         print(f"Počet pozic v remíze je {F_drawing}")
  561.         print(f"Počet pozic v šachu je {F_check}")
  562.         print(f"Počet normálních pozic je {F_normal}")
  563.  
  564.         # Iterative evaluation
  565.         print("\nZačínám iterativní ohodnocení...6")
  566.         uroven = 0
  567.         while True:
  568.             uroven += 1
  569.             level_start_time = time.time()
  570.             print(f"Výpočet v úrovni {uroven}")
  571.            
  572.             changed = False
  573.             current_level_positions = 0
  574.             for i in range(1, N + 1):
  575.                 current_fen = POZ[i]
  576.                 board.set_custom_fen(current_fen)
  577.                 simplified_current_fen = simplify_fen(current_fen)
  578.                 if AR[simplified_current_fen]['to_end'] is None or AR[simplified_current_fen]['to_end'] == 0:
  579.                     hod = -2000
  580.                     for move in board.legal_moves:
  581.                         board.push(move)
  582.                         POZ2 = board.fen()
  583.                         simplified_POZ2 = simplify_fen(POZ2)
  584.                         if simplified_POZ2 in AR and AR[simplified_POZ2]['to_end'] is not None:
  585.                             hod2 = -AR[simplified_POZ2]['to_end']
  586.                             if hod2 > hod:
  587.                                 hod = hod2
  588.                         board.pop()
  589.                    
  590.                     if hod == 1001 - uroven:
  591.                         new_to_end = 1000 - uroven
  592.                         new_type = 'winning'
  593.                     elif hod == -1001 + uroven:
  594.                         new_to_end = -1000 + uroven
  595.                         new_type = 'losing'
  596.                     elif hod == 0:
  597.                         new_to_end = 0
  598.                         new_type = 'drawing'
  599.                     else:
  600.                         new_to_end = None
  601.                         new_type = None
  602.                    
  603.                     if new_to_end is not None and (AR[simplified_current_fen]['to_end'] != new_to_end or AR[simplified_current_fen]['type'] != new_type):
  604.                         AR[simplified_current_fen]['to_end'] = new_to_end
  605.                         AR[simplified_current_fen]['type'] = new_type
  606.                         changed = True
  607.                         current_level_positions += 1
  608.            
  609.             level_end_time = time.time()
  610.             total_elapsed_time = level_end_time - start_time
  611.             level_elapsed_time = level_end_time - level_start_time
  612.             print(f"Nalezeno {current_level_positions} pozic v úrovni {uroven}")
  613.             print(f"Čas úrovně: {format_time(level_elapsed_time)} / Celkový čas: {format_time(total_elapsed_time)}")
  614.            
  615.             if not changed:
  616.                 print("Hodnocení ukončeno - žádné další změny.5")
  617.                 break
  618.        
  619.         print(f"Celkem nalezeno {sum(1 for data in AR.values() if data['to_end'] is not None)} ohodnocených pozic")
  620.         print(f"Celkem nalezeno {sum(1 for data in AR.values() if data['to_end'] is None)} neohodnocených pozic")
  621.  
  622.         print("\nVýpočet dokončen.")
  623.        
  624.         # Print optimal moves with parent check
  625.         current_fen = start_fen
  626.         simplified_current_fen = simplify_fen(current_fen)
  627.         optimal_moves = [simplified_current_fen]
  628.        
  629.         while True:
  630.             board = CustomBoard(current_fen)
  631.             if board.is_checkmate():
  632.                 print("Mat detekován!4")
  633.                 break
  634.            
  635.             if board.is_insufficient_material():
  636.                 print("Nedostatečný materiál detekován!")
  637.                 break
  638.            
  639.             half_move_clock = current_fen.split()[-2]
  640.             if half_move_clock != '-' and int(half_move_clock) >= 100:
  641.                 print("Remíza pravidlem 50 tahů detekována!")
  642.                 break
  643.            
  644.             if simplified_current_fen not in AR:
  645.                 print(f"Pozice {simplified_current_fen} není v AR.")
  646.                 break
  647.            
  648.             current_value = AR[simplified_current_fen]['to_end']
  649.            
  650.             if current_value == 0:
  651.                 print("Remíza dosažena!")
  652.                 break
  653.            
  654.             hod = -2000 if current_value > 0 else 2000
  655.             best_fen = None
  656.             for move in board.legal_moves:
  657.                 board.push(move)
  658.                 POZ2 = board.fen()
  659.                 simplified_POZ2 = simplify_fen(POZ2)
  660.                 if simplified_POZ2 in AR and AR[simplified_POZ2]['parent'] == simplified_current_fen:
  661.                     hod2 = -AR[simplified_POZ2]['to_end']
  662.                     if current_value > 0:  # Silnější hráč
  663.                         if hod2 > hod:
  664.                             hod = hod2
  665.                             best_fen = simplified_POZ2
  666.                     else:  # Slabší hráč
  667.                         if hod2 < hod:
  668.                             hod = hod2
  669.                             best_fen = simplified_POZ2
  670.                 board.pop()
  671.            
  672.             if best_fen is None:
  673.                 print("Žádný další tah nebyl nalezen.")
  674.                 break
  675.            
  676.             optimal_moves.append(best_fen)
  677.             current_fen = best_fen
  678.             simplified_current_fen = simplify_fen(current_fen)
  679.        
  680.         print("\nOptimální tahy3:")
  681.         for fen in optimal_moves:
  682.             print_board(fen)
  683.             hodnota = AR[simplify_fen(fen)]['to_end']
  684.             typ_pozice = AR[simplify_fen(fen)]['type']
  685.             print(f"Hodnota: {hodnota}, Typ: {typ_pozice}")
  686.             print(fen)
  687.             print("\n")
  688.        
  689.         return {fen: (data['to_end'], data['type']) for fen, data in AR.items() if data['to_end'] is not None}
  690.  
  691.     finally:
  692.         stop_event.set()
  693.         timer_thread.join()
  694.  
  695. # Helper function to print the board
  696. def print_board(fen):
  697.     board = CustomBoard(fen)
  698.     print(board)
  699.  
  700. # Najděte nejmenší kladnou hodnotu to_end ve všech FEN záznamech v AR
  701. def find_min_positive_value(AR):
  702.     min_positive_value = float('inf')
  703.     min_fen = None
  704.    
  705.     for fen, (value, type_pozice) in AR.items():
  706.         if value is not None and value > 0 and value < min_positive_value:
  707.             min_positive_value = value
  708.             min_fen = fen
  709.    
  710.     if min_positive_value == float('inf'):
  711.         print("Žádná kladná hodnota nebyla nalezena.")
  712.     else:
  713.         print(f"Nejmenší kladná hodnota: {min_positive_value}, FEN: {min_fen}")
  714.  
  715. # # Main execution
  716. # # Main execution
  717. # if __name__ == "__main__":
  718. #     start_fen = "7K/8/k1P5/7p/8/8/8/8 w - - 0 1"
  719.  
  720. #     start_fen = "7K/8/8/8/8/k7/8/7A w - - 0 1"
  721.  
  722. #  #   start_fen = "7K/8/8/2a5/8/1k6/8/7A w - - 0 1"
  723.  
  724. #     start_fen = "7K/8/k1P5/7p/8/8/8/8 w - - 0 1"
  725.  
  726. #     start_fen = "6K1/3E4/8/8/8/k7/8/8 w - - 0 1"
  727.  
  728. #     start_fen = "8/5A2/8/8/2K5/8/ka6/8 w - - 0 1"
  729.  
  730. #     start_fen = "8/8/8/2k5/8/8/1K6/3Q4 w - - 0 1"
  731.  
  732.  #    start_fen = "8/7k/7r/8/8/RK6/8/8 w - - 0 1"
  733.  
  734.    
  735.  #    AR = calculate_optimal_moves(start_fen)
  736.  
  737. #     find_min_positive_value(AR)
  738.  
  739. def print_20_successors(AR, start_fen):
  740.     print("\nVýpis 20 následníků počáteční pozice:")
  741.     simplified_start_fen = simplify_fen(start_fen)
  742.    
  743.     if simplified_start_fen not in AR:
  744.         print(f"Počáteční pozice {simplified_start_fen} nebyla nalezena v AR.")
  745.         return
  746.  
  747.     count = 0
  748.     for fen, (hodnota, typ_pozice) in AR.items():
  749.         if count >= 20:
  750.             break
  751.        
  752.         print(f"\nFEN: {fen}")
  753.         print("Hodnoty:")
  754.         print(f"  Hodnota: {hodnota}")
  755.         print(f"  Typ pozice: {typ_pozice}")
  756.        
  757.         print_board(fen)
  758.         count += 1
  759.        
  760. if __name__ == "__main__":
  761.     start_fen = "8/8/8/2k5/8/8/1K6/1Q6 w - - 0 1"
  762. #    start_fen = "8/7k/7r/8/8/RK6/8/8 w - - 0 1"
  763.    
  764.     AR = calculate_optimal_moves(start_fen)
  765.  
  766.     find_min_positive_value(AR)
  767.  
  768.     # Přidáno: Volání nové funkce pro výpis 20 následníků
  769.     print_20_successors(AR, start_fen)
  770.  
  771.     # print("\nVýsledky:")
  772.     # for hodnota in range(-996, -1001, -1):  # Generuje hodnoty -996, -997, -998, -999, -1000
  773.     #     for fen, (fen_hodnota, typ_pozice) in AR.items():
  774.     #         if fen_hodnota == hodnota:
  775.     #             print(f"FEN: {fen}")
  776.     #             print(f"Hodnota: {fen_hodnota}")
  777.     #             print(f"Typ pozice: {typ_pozice}")
  778.                
  779.     #             temp_board = CustomBoard(fen)
  780.                
  781.     #             if temp_board.is_checkmate():
  782.     #                 print("Stav: Mat")
  783.     #             elif temp_board.is_stalemate():
  784.     #                 print("Stav: Pat")
  785.     #             elif temp_board.is_insufficient_material():
  786.     #                 print("Stav: Nedostatečný materiál")
  787.     #             elif temp_board.is_check():
  788.     #                 print("Stav: Šach")
  789.     #             else:
  790.     #                 print("Stav: Normální pozice")
  791.      
  792.     #             print_board(fen)
  793.                
  794.     #             print()
  795.  
  796.     # Print optimal moves
  797. # Print optimal moves
  798.     current_fen = start_fen
  799.     simplified_current_fen = simplify_fen(current_fen)
  800.     simplified_current_fen1 = simplified_current_fen
  801.     optimal_moves = [start_fen]
  802.    
  803.     while True:
  804.         board = CustomBoard(current_fen)
  805.         if board.is_checkmate():
  806.             print("Mat detekován!2")
  807.             break
  808.        
  809.         # Opravená část
  810.         half_move_clock = current_fen.split()[-2]
  811.         if board.is_insufficient_material() or (half_move_clock != '-' and int(half_move_clock) >= 100):
  812.             if board.is_insufficient_material():
  813.                 print("Nedostatečný materiál detekován!")
  814.             else:
  815.                 print("Remíza pravidlem 50 tahů detekována!")
  816.             AR[simplified_current_fen] = (0, 'drawing')  # Aktualizujeme AR pro tuto pozici
  817.             break
  818.        
  819.         if simplified_current_fen not in AR:
  820.             print(f"Pozice {simplified_current_fen} není v AR.")
  821.             break
  822.        
  823.         current_value = AR[simplified_current_fen][0]
  824.        
  825.         if current_value == 0:
  826.             print("Remíza dosažena!")
  827.             break
  828.        
  829.         hod = -2000 if current_value > 0 else 2000
  830.         best_fen = None
  831.         for move in board.legal_moves:
  832.             board.push(move)
  833.             POZ2 = board.fen()
  834.             simplified_POZ2 = simplify_fen(POZ2)
  835.             if simplified_POZ2 in AR:
  836.                 hod2 = -AR[simplified_POZ2][0]
  837.                 if current_value > 0:  # Silnější hráč
  838.                     if hod2 > hod:
  839.                         hod = hod2
  840.                         best_fen = simplified_POZ2
  841.                 else:  # Slabší hráč
  842.                     if hod2 < hod:
  843.                         hod = hod2
  844.                         best_fen = simplified_POZ2
  845.             board.pop()
  846.        
  847.         if best_fen is None:
  848.             print("Žádný další tah nebyl nalezen.")
  849.             break
  850.         optimal_moves.append(best_fen)
  851.         current_fen = best_fen
  852.         simplified_current_fen = simplify_fen(current_fen)
  853.            
  854.    
  855.     print("\nOptimální tahy1:")
  856.     for fen in reversed(optimal_moves):
  857.         print_board(fen)
  858.         hodnota, typ_pozice = AR[simplify_fen(fen)]
  859.         print(f"Hodnota: {hodnota}, Typ: {typ_pozice}")
  860.         print(fen)
  861.         print("\n")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement