Advertisement
max2201111

proc se nevybere e5f4??

Aug 1st, 2024
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 31.92 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 = chess.QUEEN
  82.                     color = chess.WHITE
  83.                 elif c == 'p' and chess.square_rank(square) == 0:
  84.                     piece_type = chess.QUEEN
  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(square)
  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.         self.clear_square(from_square)
  226.         self.clear_square(to_square)
  227.         self._set_piece_at(to_square, piece.piece_type, piece.color)
  228.    
  229.         king_square = to_square if piece.piece_type == chess.KING else self.king(self.turn)
  230.         is_check = False
  231.         if king_square is not None:
  232.             is_check = self._is_attacked_by(not self.turn, king_square)
  233.    
  234.         self.clear_square(to_square)
  235.         self._set_piece_at(from_square, piece.piece_type, piece.color)
  236.         if captured_piece:
  237.             self._set_piece_at(to_square, captured_piece.piece_type, captured_piece.color)
  238.    
  239.         return not is_check
  240.    
  241.  
  242.     def _is_attacked_by(self, color, square):
  243.         attackers = self.attackers(color, square)
  244.         return bool(attackers)
  245.  
  246.     def attackers(self, color, square):
  247.         if square is None:
  248.             return chess.BB_EMPTY
  249.  
  250.         attackers = chess.BB_EMPTY
  251.        
  252.         # Knights
  253.         knights = self.knights & self.occupied_co[color]
  254.         if chess.BB_KNIGHT_ATTACKS[square] & knights:
  255.             attackers |= knights & chess.BB_KNIGHT_ATTACKS[square]
  256.        
  257.         # King
  258.         king = self.kings & self.occupied_co[color]
  259.         if chess.BB_KING_ATTACKS[square] & king:
  260.             attackers |= king
  261.        
  262.         # Pawns
  263.         pawns = self.pawns & self.occupied_co[color]
  264.         pawn_attacks = chess.BB_PAWN_ATTACKS[not color][square]
  265.         if pawn_attacks & pawns:
  266.             attackers |= pawns & pawn_attacks
  267.        
  268.         # Queens
  269.         queens = self.queens & self.occupied_co[color]
  270.         queen_attacks = (
  271.             chess.BB_DIAG_ATTACKS[square][self.occupied & chess.BB_DIAG_MASKS[square]] |
  272.             chess.BB_RANK_ATTACKS[square][self.occupied & chess.BB_RANK_MASKS[square]] |
  273.             chess.BB_FILE_ATTACKS[square][self.occupied & chess.BB_FILE_MASKS[square]]
  274.         )
  275.         if queen_attacks & queens:
  276.             attackers |= queens & queen_attacks
  277.        
  278.         # Bishops
  279.         bishops = self.bishops & self.occupied_co[color]
  280.         bishop_attacks = chess.BB_DIAG_ATTACKS[square][self.occupied & chess.BB_DIAG_MASKS[square]]
  281.         if bishop_attacks & bishops:
  282.             attackers |= bishops & bishop_attacks
  283.        
  284.         # Rooks
  285.         rooks = self.rooks & self.occupied_co[color]
  286.         rook_attacks = (
  287.             chess.BB_RANK_ATTACKS[square][self.occupied & chess.BB_RANK_MASKS[square]] |
  288.             chess.BB_FILE_ATTACKS[square][self.occupied & chess.BB_FILE_MASKS[square]]
  289.         )
  290.         if rook_attacks & rooks:
  291.             attackers |= rooks & rook_attacks
  292.        
  293.         # Amazons (Queen + Knight)
  294.         amazons = self.amazons_white if color == chess.WHITE else self.amazons_black
  295.         for amazon_square in chess.scan_forward(amazons):
  296.             amazon_attacks = (
  297.                 chess.BB_DIAG_ATTACKS[amazon_square][self.occupied & chess.BB_DIAG_MASKS[amazon_square]] |
  298.                 chess.BB_RANK_ATTACKS[amazon_square][self.occupied & chess.BB_RANK_MASKS[amazon_square]] |
  299.                 chess.BB_FILE_ATTACKS[amazon_square][self.occupied & chess.BB_FILE_MASKS[amazon_square]] |
  300.                 chess.BB_KNIGHT_ATTACKS[amazon_square]
  301.             )
  302.             if amazon_attacks & chess.BB_SQUARES[square]:
  303.                 attackers |= chess.BB_SQUARES[amazon_square]
  304.        
  305.         # Cyrils (Rook + Knight)
  306.         cyrils = self.cyrils_white if color == chess.WHITE else self.cyrils_black
  307.         for cyril_square in chess.scan_forward(cyrils):
  308.             cyril_attacks = (
  309.                 chess.BB_RANK_ATTACKS[cyril_square][self.occupied & chess.BB_RANK_MASKS[cyril_square]] |
  310.                 chess.BB_FILE_ATTACKS[cyril_square][self.occupied & chess.BB_FILE_MASKS[cyril_square]] |
  311.                 chess.BB_KNIGHT_ATTACKS[cyril_square]
  312.             )
  313.             if cyril_attacks & chess.BB_SQUARES[square]:
  314.                 attackers |= chess.BB_SQUARES[cyril_square]
  315.        
  316.         # Eves (Bishop + Knight)
  317. # Eves (Bishop + Knight)
  318.         eves = self.eves_white if color == chess.WHITE else self.eves_black
  319.         for eve_square in chess.scan_forward(eves):
  320.             eve_attacks = (
  321.                 chess.BB_DIAG_ATTACKS[eve_square][self.occupied & chess.BB_DIAG_MASKS[eve_square]] |
  322.                 chess.BB_KNIGHT_ATTACKS[eve_square]
  323.             )
  324.             if eve_attacks & chess.BB_SQUARES[square]:
  325.                 attackers |= chess.BB_SQUARES[eve_square]
  326.        
  327.         return attackers
  328.  
  329.     def push(self, move):
  330.         if not self.is_legal(move):
  331.             raise ValueError(f"Move {move} is not legal in position {self.fen()}")
  332.  
  333.         piece = self.piece_at(move.from_square)
  334.         captured_piece = self.piece_at(move.to_square)
  335.  
  336.         self.clear_square(move.from_square)
  337.         self.clear_square(move.to_square)
  338.         self._set_piece_at(move.to_square, piece.piece_type, piece.color)
  339.  
  340.         self.turn = not self.turn
  341.  
  342.         self.move_stack.append((move, captured_piece))
  343.  
  344.     def pop(self):
  345.         if not self.move_stack:
  346.             return None
  347.  
  348.         move, captured_piece = self.move_stack.pop()
  349.  
  350.         piece = self.piece_at(move.to_square)
  351.        
  352.         self.clear_square(move.from_square)
  353.         self.clear_square(move.to_square)
  354.  
  355.         self._set_piece_at(move.from_square, piece.piece_type, piece.color)
  356.  
  357.         if captured_piece:
  358.             self._set_piece_at(move.to_square, captured_piece.piece_type, captured_piece.color)
  359.  
  360.         self.turn = not self.turn
  361.  
  362.         return move
  363.  
  364.     def is_check(self):
  365.         king_square = self.king(self.turn)
  366.         if king_square is None:
  367.             return False
  368.         is_check = self._is_attacked_by(not self.turn, king_square)
  369.         return is_check
  370.  
  371.     def is_checkmate(self):
  372.         if not self.is_check():
  373.             return False
  374.         legal_moves = list(self.generate_legal_moves())
  375.         return len(legal_moves) == 0
  376.  
  377.     def is_game_over(self):
  378.         return self.is_checkmate() or self.is_stalemate() or self.is_insufficient_material()
  379.  
  380.     def is_stalemate(self):
  381.         if self.is_check():
  382.             return False
  383.         legal_moves = list(self.generate_legal_moves())
  384.         return len(legal_moves) == 0
  385.    
  386.     def is_insufficient_material(self):
  387.         return (self.pawns | self.rooks | self.queens | self.amazons_white | self.amazons_black |
  388.                 self.cyrils_white | self.cyrils_black | self.eves_white | self.eves_black) == 0 and (
  389.             chess.popcount(self.occupied) <= 3
  390.         )
  391.  
  392.     def generate_legal_moves(self, from_mask=chess.BB_ALL, to_mask=chess.BB_ALL):
  393.         for move in self.generate_pseudo_legal_moves(from_mask, to_mask):
  394.             if self.is_legal(move):
  395.                 yield move
  396.  
  397.     def debug_amazons(self):
  398.         pass
  399.  
  400.     def debug_cyrils(self):
  401.         pass
  402.  
  403.     def debug_eves(self):
  404.         pass
  405.  
  406.     def piece_symbol(self, piece):
  407.         if piece is None:
  408.             return '.'
  409.         if piece.piece_type == AMAZON:
  410.             return 'A' if piece.color == chess.WHITE else 'a'
  411.         if piece.piece_type == CYRIL:
  412.             return 'C' if piece.color == chess.WHITE else 'c'
  413.         if piece.piece_type == EVE:
  414.             return 'E' if piece.color == chess.WHITE else 'e'
  415.         return piece.symbol()
  416.  
  417.     def piece_type_at(self, square):
  418.         if (self.amazons_white | self.amazons_black) & chess.BB_SQUARES[square]:
  419.             return AMAZON
  420.         if (self.cyrils_white | self.cyrils_black) & chess.BB_SQUARES[square]:
  421.             return CYRIL
  422.         if (self.eves_white | self.eves_black) & chess.BB_SQUARES[square]:
  423.             return EVE
  424.         return super().piece_type_at(square)
  425.  
  426.     def color_at(self, square):
  427.         if self.amazons_white & chess.BB_SQUARES[square]:
  428.             return chess.WHITE
  429.         if self.amazons_black & chess.BB_SQUARES[square]:
  430.             return chess.BLACK
  431.         if self.cyrils_white & chess.BB_SQUARES[square]:
  432.             return chess.WHITE
  433.         if self.cyrils_black & chess.BB_SQUARES[square]:
  434.             return chess.BLACK
  435.         if self.eves_white & chess.BB_SQUARES[square]:
  436.             return chess.WHITE
  437.         if self.eves_black & chess.BB_SQUARES[square]:
  438.             return chess.BLACK
  439.         return super().color_at(square)
  440.  
  441.     @property
  442.     def legal_moves(self):
  443.         return list(self.generate_legal_moves())
  444.  
  445.     def __str__(self):
  446.         builder = []
  447.         for square in chess.SQUARES_180:
  448.             piece = self.piece_at(square)
  449.             symbol = self.piece_symbol(piece) if piece else '.'
  450.             builder.append(symbol)
  451.             if chess.square_file(square) == 7:
  452.                 if square != chess.H1:
  453.                     builder.append('\n')
  454.         return ''.join(builder)
  455.  
  456. def format_time(seconds):
  457.     hours, remainder = divmod(seconds, 3600)
  458.     minutes, seconds = divmod(remainder, 60)
  459.     return f"{int(hours):02d}h {int(minutes):02d}m {int(seconds):02d}s"
  460.  
  461. def print_elapsed_time(stop_event, start_time):
  462.     while not stop_event.is_set():
  463.         elapsed_time = time.time() - start_time
  464.         print(f"\rUplynulý čas: {format_time(elapsed_time)}", end="", flush=True)
  465.         time.sleep(1)
  466.  
  467. def simplify_fen(fen):
  468.     return ' '.join(fen.split()[:4])
  469.  
  470. def calculate_optimal_moves(start_fen: str) -> Dict[str, Tuple[int, str]]:
  471.     print("Funkce calculate_optimal_moves byla zavolána")
  472.     print(f"Počáteční FEN: {start_fen}")
  473.    
  474.     board = CustomBoard(start_fen)
  475.     POZ = {1: simplify_fen(start_fen)}
  476.     AR = {simplify_fen(start_fen): {'used': 0, 'to_end': None, 'depth': 0, 'type': 'normal'}}
  477.     N = 1
  478.     M = 0
  479.  
  480.     start_time = time.time()
  481.     current_depth = 0
  482.     positions_at_depth = {0: 0}
  483.     depth_start_time = start_time
  484.  
  485.     stop_event = threading.Event()
  486.     timer_thread = threading.Thread(target=print_elapsed_time, args=(stop_event, start_time))
  487.     timer_thread.start()
  488.  
  489.     try:
  490.         print("Začínám generovat pozice...")
  491.         print("Počáteční pozice:")
  492.         print_board(start_fen)
  493.        
  494.         depth_1_positions = []  # Seznam pro ukládání pozic v hloubce 1
  495.  
  496.         # Generate all positions
  497.         while M < N:
  498.             M += 1
  499.             current_fen = POZ[M]
  500.             board.set_custom_fen(current_fen)
  501.             simplified_current_fen = simplify_fen(current_fen)
  502.             current_depth = AR[simplified_current_fen]['depth']
  503.  
  504.             if current_depth not in positions_at_depth:
  505.                 positions_at_depth[current_depth] = 0
  506.                 if current_depth > 0:
  507.                     depth_time = time.time() - depth_start_time
  508.                     total_time = time.time() - start_time
  509.                     print(f"\nHloubka {current_depth - 1}: {positions_at_depth[current_depth - 1]} pozic, "
  510.                           f"Čas hloubky: {format_time(depth_time)} / Celkový čas: {format_time(total_time)}")
  511.                    
  512.                     if current_depth == 1:
  513.                         print("Všechny pozice v hloubce 1:")
  514.                         for pos in depth_1_positions:
  515.                             print_board(pos)
  516.                             print()
  517.                
  518.                 depth_start_time = time.time()
  519.  
  520.             positions_at_depth[current_depth] += 1
  521.  
  522.             if current_depth == 1:
  523.                 depth_1_positions.append(current_fen)
  524.  
  525.             if AR[simplified_current_fen]['used'] == 0:
  526.                 AR[simplified_current_fen]['used'] = 1
  527.                 legal_moves = list(board.legal_moves)
  528.                 for move in legal_moves:
  529.                     board.push(move)
  530.                     POZ2 = board.fen()
  531.                     simplified_POZ2 = simplify_fen(POZ2)
  532.                     if simplified_POZ2 not in AR:
  533.                         N += 1
  534.                         POZ[N] = simplified_POZ2
  535.                         AR[simplified_POZ2] = {'used': 0, 'to_end': None, 'depth': current_depth + 1, 'type': 'normal'}
  536.                     board.pop()
  537.    
  538.         # Print last depth
  539.         depth_time = time.time() - depth_start_time
  540.         total_time = time.time() - start_time
  541.         print(f"\nHloubka {current_depth}: {positions_at_depth[current_depth]} pozic, "
  542.               f"Čas hloubky: {format_time(depth_time)} / Celkový čas: {format_time(total_time)}")
  543.         print(f"Příklad pozice v hloubce {current_depth}:")
  544.         print_board(current_fen)
  545.  
  546.         print(f"Generování pozic dokončeno. Celkový počet pozic: {N}")
  547.  
  548.         # Initial evaluation
  549.         print("\nZačínám počáteční ohodnocení...")
  550.         for i in range(1, N + 1):
  551.             current_fen = POZ[i]
  552.             board.set_custom_fen(current_fen)
  553.             simplified_current_fen = simplify_fen(current_fen)
  554.  
  555.             if board.is_checkmate():
  556.                 AR[simplified_current_fen]['to_end'] = -1000 if board.turn == chess.WHITE else 1000
  557.                 AR[simplified_current_fen]['type'] = 'checkmate'
  558.             elif board.is_stalemate() or board.is_insufficient_material():
  559.                 AR[simplified_current_fen]['to_end'] = 0
  560.                 AR[simplified_current_fen]['type'] = 'drawing'
  561.             else:
  562.                 AR[simplified_current_fen]['to_end'] = None
  563.                 AR[simplified_current_fen]['type'] = 'normal'
  564.  
  565.         # Iterative evaluation
  566.         print("\nZačínám iterativní ohodnocení...")
  567.         max_depth = max(data['depth'] for data in AR.values())
  568.         for depth in range(max_depth, -1, -1):
  569.             print(f"Výpočet v hloubce {depth}")
  570.             for fen, data in AR.items():
  571.                 if data['depth'] == depth and data['to_end'] is None:
  572.                     board.set_custom_fen(fen)
  573.                     legal_moves = list(board.legal_moves)
  574.                    
  575.                     if not legal_moves or board.halfmove_clock >= 100:
  576.                         data['to_end'] = 0
  577.                         data['type'] = 'drawing'
  578.                         continue
  579.  
  580.                     best_value = float('-inf') if board.turn == chess.WHITE else float('inf')
  581.                     all_moves_draw = True
  582.                     for move in legal_moves:
  583.                         board.push(move)
  584.                         next_fen = simplify_fen(board.fen())
  585.                         if next_fen in AR and AR[next_fen]['to_end'] is not None:
  586.                             value = -AR[next_fen]['to_end']
  587.                             if AR[next_fen]['type'] != 'drawing':
  588.                                 all_moves_draw = False
  589.                             if board.turn == chess.WHITE:
  590.                                 best_value = max(best_value, value)
  591.                             else:
  592.                                 best_value = min(best_value, value)
  593.                         board.pop()
  594.                    
  595.                     if all_moves_draw:
  596.                         data['to_end'] = 0
  597.                         data['type'] = 'drawing'
  598.                     elif best_value != float('-inf') and best_value != float('inf'):
  599.                         new_value = -best_value
  600.                         if abs(new_value) == 1000:
  601.                             data['type'] = 'checkmate'
  602.                         elif new_value > 0:
  603.                             new_value = min(999, new_value)
  604.                             data['type'] = 'winning'
  605.                         elif new_value < 0:
  606.                             new_value = max(-999, new_value)
  607.                             data['type'] = 'losing'
  608.                         else:
  609.                             data['type'] = 'drawing'
  610.                         data['to_end'] = new_value
  611.  
  612.         print(f"Celkem nalezeno {sum(1 for data in AR.values() if data['to_end'] is not None)} ohodnocených pozic")
  613.  
  614.         print("\nVýpočet dokončen.")
  615.         return {fen: (data['to_end'], data['type']) for fen, data in AR.items() if data['to_end'] is not None}
  616.  
  617.     finally:
  618.         stop_event.set()
  619.         timer_thread.join()
  620.  
  621. def print_board_for_value(AR, target_value):
  622.     for fen, (value, type_) in AR.items():
  623.         if value == target_value:
  624.             print(f"Nalezena pozice s hodnotou {target_value}:")
  625.             print(f"FEN: {fen}")
  626.             print(f"Typ: {type_}")
  627.             board = CustomBoard(fen)
  628.             print(board)
  629.             print()  # Prázdný řádek pro lepší čitelnost
  630.  
  631. def find_min_positive_value(AR):
  632.     min_positive_value = float('inf')
  633.     min_fen = None
  634.    
  635.     for fen, (value, type_pozice) in AR.items():
  636.         if value is not None and value > 0 and value < min_positive_value:
  637.             min_positive_value = value
  638.             min_fen = fen
  639.    
  640.     if min_positive_value == float('inf'):
  641.         print("Žádná kladná hodnota nebyla nalezena.")
  642.     else:
  643.         print(f"Nejmenší kladná hodnota: {min_positive_value}, FEN: {min_fen}")
  644.  
  645. # if __name__ == "__main__":
  646. #     start_fen = "7K/8/k1P5/7p/8/8/8/8 w - - 0 1"
  647. #     start_fen = "7K/8/8/8/8/k7/8/8 w - - 0 1"
  648. #     start_fen = "7K/8/8/2a5/8/1k6/8/7A w - - 0 1"
  649. #     start_fen = "8/8/8/4K3/1a1A4/8/8/1k6 b - - 0 1"
  650. #     start_fen = "8/4a3/8/4K3/3A4/8/8/1k6 w - - 0 1"
  651.  
  652. #     start_fen = "8/4a3/8/4K3/3A4/8/8/1k6 w - - 0 1"
  653.    
  654. # #    AR = calculate_optimal_moves(start_fen)
  655. #     find_min_positive_value(AR)
  656. # #    print_board_for_value(AR, -996)
  657.  
  658. #     current_fen = start_fen
  659. #     simplified_current_fen = simplify_fen(current_fen)
  660. #     simplified_current_fen1 = simplified_current_fen
  661. #     optimal_moves = []
  662.    
  663. #     while True:
  664. #         board = CustomBoard(current_fen)
  665. #         if board.is_checkmate():
  666. #             print("Mat detekován!")
  667. #             break
  668.        
  669. #         if board.is_insufficient_material() or board.halfmove_clock >= 100:
  670. #             if board.is_insufficient_material():
  671. #                 print("Nedostatečný materiál detekován!")
  672. #             else:
  673. #                 print("Remíza pravidlem 50 tahů detekována!")
  674. #             AR[simplified_current_fen] = (0, 'drawing')
  675. #             break
  676.        
  677. #         if simplified_current_fen not in AR:
  678. #             print(f"Pozice {simplified_current_fen} není v AR.")
  679. #             break
  680.        
  681. #         current_value = AR[simplified_current_fen][0]
  682.        
  683. #         if current_value == 0:
  684. #             print("Remíza dosažena!")
  685. #             break
  686.        
  687. #         best_move = None
  688. #         best_value = float('-inf') if current_value > 0 else float('inf')
  689. #         for move in board.legal_moves:
  690. #             board.push(move)
  691. #             next_fen = simplify_fen(board.fen())
  692. #             if next_fen in AR:
  693. #                 value = -AR[next_fen][0]
  694. #                 if (current_value > 0 and value > best_value) or (current_value < 0 and value < best_value):
  695. #                     best_value = value
  696. #                     best_move = move
  697. #             board.pop()
  698.        
  699. #         if best_move is None:
  700. #             print("Žádný další tah nebyl nalezen.")
  701. #             break
  702.        
  703. #         board.push(best_move)
  704. #         next_fen = board.fen()
  705. #         simplified_next_fen = simplify_fen(next_fen)
  706. #         optimal_moves.append(simplified_next_fen)
  707. #         current_fen = next_fen
  708. #         simplified_current_fen = simplified_next_fen
  709.    
  710. #     print("\nOptimální tahy:")
  711. #     for fen in reversed(optimal_moves):
  712. #         print_board(fen)
  713. #         hodnota, typ_pozice = AR[simplify_fen(fen)]
  714. #         print(f"Hodnota: {hodnota}, Typ: {typ_pozice}")
  715. #         print(fen)
  716. #         print("\n")
  717.    
  718. #     print_board(simplified_current_fen1)
  719. #     hodnota, typ_pozice = AR[simplified_current_fen1]
  720. #     print(f"Počáteční hodnota: {hodnota}, Typ: {typ_pozice}")
  721. #     print(simplified_current_fen1)
  722. #     print("\n")
  723.  
  724. if __name__ == "__main__":
  725.     start_fen = "8/4a3/8/4K3/3A4/8/8/1k6 w - - 0 1"
  726.    
  727.     # AR = calculate_optimal_moves(start_fen)
  728.     find_min_positive_value(AR)
  729.     # print_board_for_value(AR, -996)
  730.  
  731.     current_fen = start_fen
  732.     simplified_current_fen = simplify_fen(current_fen)
  733.     simplified_current_fen1 = simplified_current_fen
  734.     optimal_moves = [simplified_current_fen]
  735.    
  736.     max_moves = 50
  737.     move_count = 0
  738.  
  739.     while move_count < max_moves:
  740.         board = CustomBoard(current_fen)
  741.         print(f"\nAktuální pozice (tah {move_count + 1}):")
  742.         print(board)
  743.         print(f"FEN: {current_fen}")
  744.        
  745.         if board.is_checkmate():
  746.             print("Mat detekován!")
  747.             break
  748.        
  749.         if board.is_insufficient_material() or board.halfmove_clock >= 100:
  750.             if board.is_insufficient_material():
  751.                 print("Nedostatečný materiál detekován!")
  752.             else:
  753.                 print("Remíza pravidlem 50 tahů detekována!")
  754.             AR[simplified_current_fen] = (0, 'drawing')
  755.             break
  756.        
  757.         if simplified_current_fen not in AR:
  758.             print(f"Pozice {simplified_current_fen} není v AR.")
  759.             break
  760.        
  761.         current_value = AR[simplified_current_fen][0]
  762.         print(f"Aktuální hodnota: {current_value}")
  763.        
  764.         if current_value == 0:
  765.             print("Remíza dosažena!")
  766.             break
  767.        
  768.         best_move = None
  769.         best_value = float('inf') if board.turn == chess.WHITE else float('-inf')
  770.         print("Možné tahy:")
  771.         for move in board.legal_moves:
  772.             board.push(move)
  773.             next_fen = simplify_fen(board.fen())
  774.             if next_fen in AR:
  775.                 value = AR[next_fen][0]
  776.                 print(f"  Tah {move}: hodnota = {value}")
  777.                 if board.turn == chess.WHITE:
  778.                     if value < best_value:
  779.                         best_value = value
  780.                         best_move = move
  781.                 else:
  782.                     if value > best_value:
  783.                         best_value = value
  784.                         best_move = move
  785.             else:
  786.                 print(f"  Tah {move}: není v AR")
  787.             board.pop()
  788.        
  789.         if best_move is None:
  790.             print("Žádný další tah nebyl nalezen.")
  791.             break
  792.        
  793.         print(f"Nejlepší tah: {best_move}, hodnota: {best_value}")
  794.        
  795.         board.push(best_move)
  796.         next_fen = board.fen()
  797.         simplified_next_fen = simplify_fen(next_fen)
  798.         optimal_moves.append(simplified_next_fen)
  799.         current_fen = next_fen
  800.         simplified_current_fen = simplified_next_fen
  801.         move_count += 1
  802.    
  803.     print("\nOptimální tahy:")
  804.     for fen in optimal_moves:
  805.         print_board(fen)
  806.         hodnota, typ_pozice = AR[simplify_fen(fen)]
  807.         print(f"Hodnota: {hodnota}, Typ: {typ_pozice}")
  808.         print(fen)
  809.         print("\n")
  810.    
  811.     print_board(simplified_current_fen1)
  812.     hodnota, typ_pozice = AR[simplified_current_fen1]
  813.     print(f"Počáteční hodnota: {hodnota}, Typ: {typ_pozice}")
  814.     print(simplified_current_fen1)
  815.     print("\n")
  816.  
  817.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement