Advertisement
max2201111

opraveno stalemate

Jul 26th, 2024
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 40.35 KB | Science | 0 0
  1. # Import knihovny chess a dalších potřebných modulů
  2. import chess
  3. from typing import Iterator, Optional, Dict, Tuple
  4. from chess import Move, BB_ALL, Bitboard, PieceType, Color
  5. import time
  6. from collections import deque
  7. import threading
  8.  
  9. # Definice nových figur
  10. AMAZON = 7
  11. CYRIL = 8
  12. EVE = 9
  13.  
  14. # Rozšíření seznamu PIECE_SYMBOLS
  15. chess.PIECE_SYMBOLS.append('a')
  16. chess.PIECE_SYMBOLS.append('c')
  17. chess.PIECE_SYMBOLS.append('e')
  18.  
  19. class CustomBoard(chess.Board):
  20.     def __init__(self, fen=None):
  21.         self.amazons_white = chess.BB_EMPTY
  22.         self.amazons_black = chess.BB_EMPTY
  23.         self.cyrils_white = chess.BB_EMPTY
  24.         self.cyrils_black = chess.BB_EMPTY
  25.         self.eves_white = chess.BB_EMPTY
  26.         self.eves_black = chess.BB_EMPTY
  27.         super().__init__(None)
  28.         if fen:
  29.             self.set_custom_fen(fen)
  30.         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_attacked_by(self, color, square):
  210.         attackers = self.attackers(color, square)
  211.         return bool(attackers)
  212.  
  213.     def attackers(self, color, square):
  214.         if square is None:
  215.             return chess.BB_EMPTY
  216.        
  217.         attackers = chess.BB_EMPTY
  218.        
  219.         # Knights
  220.         knights = self.knights & self.occupied_co[color]
  221.         if chess.BB_KNIGHT_ATTACKS[square] & knights:
  222.             attackers |= knights & chess.BB_KNIGHT_ATTACKS[square]
  223.        
  224.         # King
  225.         king = self.kings & self.occupied_co[color]
  226.         if chess.BB_KING_ATTACKS[square] & king:
  227.             attackers |= king
  228.        
  229.         # Pawns
  230.         pawns = self.pawns & self.occupied_co[color]
  231.         pawn_attacks = chess.BB_PAWN_ATTACKS[not color][square]
  232.         if pawn_attacks & pawns:
  233.             attackers |= pawns & pawn_attacks
  234.        
  235.         # Queens
  236.         queens = self.queens & self.occupied_co[color]
  237.         queen_attacks = (
  238.             chess.BB_DIAG_ATTACKS[square][self.occupied & chess.BB_DIAG_MASKS[square]] |
  239.             chess.BB_RANK_ATTACKS[square][self.occupied & chess.BB_RANK_MASKS[square]] |
  240.             chess.BB_FILE_ATTACKS[square][self.occupied & chess.BB_FILE_MASKS[square]]
  241.         )
  242.         if queen_attacks & queens:
  243.             attackers |= queens & queen_attacks
  244.        
  245.         # Bishops
  246.         bishops = self.bishops & self.occupied_co[color]
  247.         bishop_attacks = chess.BB_DIAG_ATTACKS[square][self.occupied & chess.BB_DIAG_MASKS[square]]
  248.         if bishop_attacks & bishops:
  249.             attackers |= bishops & bishop_attacks
  250.        
  251.         # Rooks
  252.         rooks = self.rooks & self.occupied_co[color]
  253.         rook_attacks = (
  254.             chess.BB_RANK_ATTACKS[square][self.occupied & chess.BB_RANK_MASKS[square]] |
  255.             chess.BB_FILE_ATTACKS[square][self.occupied & chess.BB_FILE_MASKS[square]]
  256.         )
  257.         if rook_attacks & rooks:
  258.             attackers |= rooks & rook_attacks
  259.        
  260.         # Amazons (Queen + Knight)
  261.         amazons = self.amazons_white if color == chess.WHITE else self.amazons_black
  262.         for amazon_square in chess.scan_forward(amazons):
  263.             amazon_attacks = (
  264.                 chess.BB_DIAG_ATTACKS[amazon_square][self.occupied & chess.BB_DIAG_MASKS[amazon_square]] |
  265.                 chess.BB_RANK_ATTACKS[amazon_square][self.occupied & chess.BB_RANK_MASKS[amazon_square]] |
  266.                 chess.BB_FILE_ATTACKS[amazon_square][self.occupied & chess.BB_FILE_MASKS[amazon_square]] |
  267.                 chess.BB_KNIGHT_ATTACKS[amazon_square]
  268.             )
  269.             if amazon_attacks & chess.BB_SQUARES[square]:
  270.                 attackers |= chess.BB_SQUARES[amazon_square]
  271.        
  272.         # Cyrils (Rook + Knight)
  273.         cyrils = self.cyrils_white if color == chess.WHITE else self.cyrils_black
  274.         for cyril_square in chess.scan_forward(cyrils):
  275.             cyril_attacks = (
  276.                 chess.BB_RANK_ATTACKS[cyril_square][self.occupied & chess.BB_RANK_MASKS[cyril_square]] |
  277.                 chess.BB_FILE_ATTACKS[cyril_square][self.occupied & chess.BB_FILE_MASKS[cyril_square]] |
  278.                 chess.BB_KNIGHT_ATTACKS[cyril_square]
  279.             )
  280.             if cyril_attacks & chess.BB_SQUARES[square]:
  281.                 attackers |= chess.BB_SQUARES[cyril_square]
  282.        
  283.         # Eves (Bishop + Knight)
  284.         eves = self.eves_white if color == chess.WHITE else self.eves_black
  285.         for eve_square in chess.scan_forward(eves):
  286.             eve_attacks = (
  287.                 chess.BB_DIAG_ATTACKS[eve_square][self.occupied & chess.BB_DIAG_MASKS[eve_square]] |
  288.                 chess.BB_KNIGHT_ATTACKS[eve_square]
  289.             )
  290.             if eve_attacks & chess.BB_SQUARES[square]:
  291.                 attackers |= chess.BB_SQUARES[eve_square]
  292.        
  293.         return attackers
  294.  
  295.     def is_legal(self, move):
  296.         if not self.is_pseudo_legal(move):
  297.             return False
  298.  
  299.         from_square = move.from_square
  300.         to_square = move.to_square
  301.         piece = self.piece_at(from_square)
  302.         captured_piece = self.piece_at(to_square)
  303.  
  304.         self.clear_square(from_square)
  305.         self.clear_square(to_square)
  306.         self._set_piece_at(to_square, piece.piece_type, piece.color)
  307.  
  308.         king_square = to_square if piece.piece_type == chess.KING else self.king(self.turn)
  309.         is_check = False
  310.         if king_square is not None:
  311.             is_check = self._is_attacked_by(not self.turn, king_square)
  312.  
  313.         self.clear_square(to_square)
  314.         self._set_piece_at(from_square, piece.piece_type, piece.color)
  315.         if captured_piece:
  316.             self._set_piece_at(to_square, captured_piece.piece_type, captured_piece.color)
  317.  
  318.         return not is_check        
  319.  
  320.     def push(self, move):
  321.         if not self.is_legal(move):
  322.             raise ValueError(f"Move {move} is not legal in position {self.fen()}")
  323.  
  324.         piece = self.piece_at(move.from_square)
  325.         captured_piece = self.piece_at(move.to_square)
  326.  
  327.         self.clear_square(move.from_square)
  328.         self.clear_square(move.to_square)
  329.        
  330.         # Zpracování promoce
  331.         if move.promotion:
  332.             self._set_piece_at(move.to_square, move.promotion, piece.color)
  333.         else:
  334.             self._set_piece_at(move.to_square, piece.piece_type, piece.color)
  335.  
  336.         self.turn = not self.turn
  337.  
  338.         self.move_stack.append((move, captured_piece))
  339.  
  340.     def pop(self):
  341.         if not self.move_stack:
  342.             return None
  343.  
  344.         move, captured_piece = self.move_stack.pop()
  345.  
  346.         piece = self.piece_at(move.to_square)
  347.        
  348.         self.clear_square(move.from_square)
  349.         self.clear_square(move.to_square)
  350.  
  351.         # Zpracování promoce při vracení tahu
  352.         if move.promotion:
  353.             self._set_piece_at(move.from_square, chess.PAWN, not self.turn)
  354.         else:
  355.             self._set_piece_at(move.from_square, piece.piece_type, not self.turn)
  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 print_all_possible_moves(self):
  457.         pass
  458.  
  459. def format_time(seconds):
  460.     hours, remainder = divmod(seconds, 3600)
  461.     minutes, seconds = divmod(remainder, 60)
  462.     return f"{int(hours):02d}h {int(minutes):02d}m {int(seconds):02d}s"
  463.  
  464. def print_elapsed_time(stop_event, start_time):
  465.     while not stop_event.is_set():
  466.         elapsed_time = time.time() - start_time
  467.         print(f"\rUplynulý čas: {format_time(elapsed_time)}", end="", flush=True)
  468.         time.sleep(1)
  469.  
  470. # def simplify_fen(fen):
  471. #     return ' '.join(fen.split()[:4])
  472.  
  473. # def calculate_optimal_moves(start_fen: str) -> Dict[str, Tuple[int, str]]:
  474. #     print("Funkce calculate_optimal_moves byla zavolána")
  475. #     print(f"Počáteční FEN: {start_fen}")
  476.    
  477. #     board = CustomBoard(start_fen)
  478. #     POZ = {1: simplify_fen(start_fen)}
  479. #     AR = {simplify_fen(start_fen): {'used': 0, 'to_end': None, 'depth': 0, 'type': 'normal'}}
  480. #     N = 1
  481. #     M = 0
  482.  
  483. #     start_time = time.time()
  484. #     current_depth = 0
  485. #     positions_at_depth = {0: 0}
  486. #     depth_start_time = start_time
  487.  
  488. #     stop_event = threading.Event()
  489. #     timer_thread = threading.Thread(target=print_elapsed_time, args=(stop_event, start_time))
  490. #     timer_thread.start()
  491.  
  492. #     try:
  493. #         print("Začínám generovat pozice...")
  494. #         print("Počáteční pozice:")
  495. #         print_board(start_fen)
  496.        
  497. #         depth_1_positions = []  # Seznam pro ukládání pozic v hloubce 1
  498.  
  499. #         # Generování všech pozic
  500. #         while M < N:
  501. #             M += 1
  502. #             current_fen = POZ[M]
  503. #             board.set_custom_fen(current_fen)
  504. #             simplified_current_fen = simplify_fen(current_fen)
  505. #             current_depth = AR[simplified_current_fen]['depth']
  506.  
  507. #             if current_depth not in positions_at_depth:
  508. #                 positions_at_depth[current_depth] = 0
  509. #                 if current_depth > 0:
  510. #                     depth_time = time.time() - depth_start_time
  511. #                     total_time = time.time() - start_time
  512. #                     print(f"\nHloubka {current_depth - 1}: {positions_at_depth[current_depth - 1]} pozic, "
  513. #                           f"Čas hloubky: {format_time(depth_time)} / Celkový čas: {format_time(total_time)}")
  514.                    
  515. #                     if current_depth == 1:
  516. #                         print("Všechny pozice v hloubce 1:")
  517. #                         for pos in depth_1_positions:
  518. #                             print_board(pos)
  519. #                             print(pos)
  520. #                             print()
  521.                
  522. #                 depth_start_time = time.time()
  523.  
  524. #             positions_at_depth[current_depth] += 1
  525.  
  526. #             if current_depth == 1:
  527. #                 depth_1_positions.append(current_fen)
  528.  
  529. #             if AR[simplified_current_fen]['used'] == 0:
  530. #                 AR[simplified_current_fen]['used'] = 1
  531. #                 legal_moves = list(board.legal_moves)
  532. #                 for move in legal_moves:
  533. #                     board.push(move)
  534. #                     POZ2 = board.fen()
  535. #                     simplified_POZ2 = simplify_fen(POZ2)
  536. #                     if simplified_POZ2 not in AR:
  537. #                         N += 1
  538. #                         POZ[N] = simplified_POZ2
  539. #                         AR[simplified_POZ2] = {'used': 0, 'to_end': None, 'depth': current_depth + 1, 'type': 'normal'}
  540. #                     board.pop()
  541.    
  542. #         # Tisk poslední hloubky
  543. #         depth_time = time.time() - depth_start_time
  544. #         total_time = time.time() - start_time
  545. #         print(f"\nHloubka {current_depth}: {positions_at_depth[current_depth]} pozic, "
  546. #               f"Čas hloubky: {format_time(depth_time)} / Celkový čas: {format_time(total_time)}")
  547. #         print(f"Příklad pozice v hloubce {current_depth}:")
  548. #         print_board(current_fen)
  549.  
  550. #         print(f"Generování pozic dokončeno. Celkový počet pozic: {N}")
  551.  
  552. #         # Počáteční ohodnocení
  553. #         print("\nZačínám počáteční ohodnocení...")
  554. #         F = 0
  555. #         for i in range(1, N + 1):
  556. #             current_fen = POZ[i]
  557. #             board.set_custom_fen(current_fen)
  558. #             simplified_current_fen = simplify_fen(current_fen)
  559. #             if board.is_checkmate():
  560. #                 AR[simplified_current_fen]['to_end'] = -1000 if board.turn == chess.WHITE else 1000
  561. #                 AR[simplified_current_fen]['type'] = 'checkmate'
  562. #                 F += 1
  563. #             elif board.is_stalemate():
  564. #                 AR[simplified_current_fen]['to_end'] = 0
  565. #                 AR[simplified_current_fen]['type'] = 'stalemate'
  566. #             elif board.is_insufficient_material():
  567. #                 AR[simplified_current_fen]['to_end'] = 0
  568. #                 AR[simplified_current_fen]['type'] = 'insufficient_material'
  569. #             else:
  570. #                 AR[simplified_current_fen]['type'] = 'check' if board.is_check() else 'normal'
  571.  
  572. #         print(f"Počet pozic v matu je {F}")
  573. #         print(f"Počet pozic v patu je {sum(1 for data in AR.values() if data['type'] == 'stalemate')}")
  574. #         print(f"Počet pozic s nedostatečným materiálem je {sum(1 for data in AR.values() if data['type'] == 'insufficient_material')}")
  575. #         print(f"Počet pozic v šachu je {sum(1 for data in AR.values() if data['type'] == 'check')}")
  576. #         print(f"Počet normálních pozic je {sum(1 for data in AR.values() if data['type'] == 'normal')}")
  577.  
  578. #         # Iterativní ohodnocení
  579. #         print("\nZačínám iterativní ohodnocení...")
  580. #         uroven = 0
  581. #         while F > 0:
  582. #             uroven += 1
  583. #             level_start_time = time.time()
  584. #             print(f"Výpočet v úrovni {uroven}")
  585.            
  586. #             F = 0
  587. #             current_level_positions = 0
  588. #             for i in range(1, N + 1):
  589. #                 current_fen = POZ[i]
  590. #                 board.set_custom_fen(current_fen)
  591. #                 simplified_current_fen = simplify_fen(current_fen)
  592. #                 if AR[simplified_current_fen].get('to_end') is None:
  593. #                     hod = -2000
  594. #                     for move in board.legal_moves:
  595. #                         board.push(move)
  596. #                         POZ2 = board.fen()
  597. #                         simplified_POZ2 = simplify_fen(POZ2)
  598. #                         if simplified_POZ2 in AR:
  599. #                             ar_entry = AR[simplified_POZ2]
  600. #                             if ar_entry is not None and 'to_end' in ar_entry:
  601. #                                 hod2 = -ar_entry['to_end'] if ar_entry['to_end'] is not None else 0
  602. #                             else:
  603. #                                 hod2 = 0
  604. #                         else:
  605. #                             hod2 = 0
  606. #                         if hod2 > hod:
  607. #                             hod = hod2
  608. #                         board.pop()
  609. #                     if hod == 1001 - uroven:
  610. #                         AR[simplified_current_fen]['to_end'] = 1000 - uroven
  611. #                         F += 1
  612. #                         current_level_positions += 1
  613. #                     elif hod == -1001 + uroven:
  614. #                         AR[simplified_current_fen]['to_end'] = -1000 + uroven
  615. #                         F += 1
  616. #                         current_level_positions += 1
  617. #             level_end_time = time.time()
  618. #             total_elapsed_time = level_end_time - start_time
  619. #             level_elapsed_time = level_end_time - level_start_time
  620. #             print(f"Nalezeno {current_level_positions} pozic v úrovni {uroven}")
  621. #             print(f"Čas úrovně: {format_time(level_elapsed_time)} / Celkový čas: {format_time(total_elapsed_time)}")
  622.  
  623. #         print(f"Nalezeno {F} pozic celkem")
  624.        
  625. #         print("\nVýpočet dokončen.")
  626. #         return {fen: (data['to_end'], data['type']) for fen, data in AR.items() if data['to_end'] is not None}
  627.  
  628. #     finally:
  629. #         stop_event.set()
  630. #         timer_thread.join()
  631.        
  632. # # Pomocná funkce pro tisk šachovnice
  633. # def print_board(fen):
  634. #     board = CustomBoard(fen)
  635. #     print(board)
  636.  
  637. # # Najděte nejmenší kladnou hodnotu to_end ve všech FEN záznamech v AR
  638. # def find_min_positive_value(AR):
  639. #     min_positive_value = float('inf')
  640. #     min_fen = None
  641.    
  642. #     for fen, (value, type_pozice) in AR.items():
  643. #         if value is not None and value > 0 and value < min_positive_value:
  644. #             min_positive_value = value
  645. #             min_fen = fen
  646.    
  647. #     if min_positive_value == float('inf'):
  648. #         print("Žádná kladná hodnota nebyla nalezena.")
  649. #     else:
  650. #         print(f"Nejmenší kladná hodnota: {min_positive_value}, FEN: {min_fen}")
  651.  
  652. # # Hlavní provedení
  653. # if __name__ == "__main__":
  654. #     start_fen = "8/2P5/4K3/8/8/8/k7/8 w - - 0 1"
  655.    
  656. #     AR = calculate_optimal_moves(start_fen)
  657.  
  658. #     find_min_positive_value(AR)
  659.  
  660. #     print("\nVýsledky:")
  661. #     for fen, (hodnota, typ_pozice) in AR.items():
  662. #         if hodnota == 984 or hodnota == -980:
  663. #             print(f"FEN: {fen}")
  664. #             print(f"Hodnota: {hodnota}")
  665. #             print(f"Typ pozice: {typ_pozice}")
  666.            
  667. #             temp_board = CustomBoard(fen)
  668.            
  669. #             if temp_board.is_checkmate():
  670. #                 print("Stav: Mat")
  671. #             elif temp_board.is_stalemate():
  672. #                 print("Stav: Pat")
  673. #             elif temp_board.is_insufficient_material():
  674. #                 print("Stav: Nedostatečný materiál")
  675. #             elif temp_board.is_check():
  676. #                 print("Stav: Šach")
  677. #             else:
  678. #                 print("Stav: Normální pozice")
  679.  
  680. #             print_board(fen)
  681.            
  682. #             print()
  683.  
  684. #     # Tisk optimálních tahů
  685. #     current_fen = start_fen
  686. #     simplified_current_fen = simplify_fen(current_fen)
  687. #     simplified_current_fen1 = simplify_fen(current_fen)
  688. #     optimal_moves = []
  689.  
  690. #             while True:
  691. #         board = CustomBoard(current_fen)
  692. #         if board.is_game_over():
  693. #             break
  694.  
  695. #         hod = -2000
  696. #         best_fen = None
  697. #         for move in board.legal_moves:
  698. #             board.push(move)
  699. #             POZ2 = board.fen()
  700. #             simplified_POZ2 = simplify_fen(POZ2)
  701. #             if simplified_POZ2 in AR:
  702. #                 hod2 = -AR[simplified_POZ2][0] if AR[simplified_POZ2][0] is not None else 0
  703. #                 if hod2 > hod:
  704. #                     hod = hod2
  705. #                     best_fen = simplified_POZ2
  706. #             board.pop()
  707.  
  708. #         if best_fen is None:
  709. #             break
  710.  
  711. #         optimal_moves.append(best_fen)
  712. #         current_fen = best_fen
  713. #         simplified_current_fen = simplify_fen(current_fen)
  714.  
  715. #     print("\nOptimální tahy:")
  716. #     for fen in reversed(optimal_moves):
  717. #         print_board(fen)
  718. #         print(AR[fen])
  719. #         print(fen)
  720. #         print("\n")
  721.  
  722. #     print_board(simplified_current_fen1)
  723. # #    print(AR[simplified_current_fen1])
  724. #     print(simplified_current_fen1)
  725. #     print("\n")
  726.  
  727.  
  728. def simplify_fen(fen):
  729.     parts = fen.split()
  730.     return ' '.join(parts[:4])  # Vrátí první 4 části FEN, včetně počtu tahů a počítadla půltahů
  731.  
  732. def calculate_optimal_moves(start_fen: str) -> Dict[str, Tuple[int, str]]:
  733.     print("Funkce calculate_optimal_moves byla zavolána")
  734.     print(f"Počáteční FEN: {start_fen}")
  735.    
  736.     board = CustomBoard(start_fen)
  737.     POZ = {1: simplify_fen(start_fen)}
  738.     AR = {simplify_fen(start_fen): {'used': 0, 'to_end': None, 'depth': 0, 'type': 'normal'}}
  739.     N = 1
  740.     M = 0
  741.  
  742.     start_time = time.time()
  743.     current_depth = 0
  744.     positions_at_depth = {0: 0}
  745.     depth_start_time = start_time
  746.  
  747.     stop_event = threading.Event()
  748.     timer_thread = threading.Thread(target=print_elapsed_time, args=(stop_event, start_time))
  749.     timer_thread.start()
  750.  
  751.     try:
  752.         print("Začínám generovat pozice...")
  753.         print("Počáteční pozice:")
  754.         print_board(start_fen)
  755.        
  756.         depth_1_positions = []  # Seznam pro ukládání pozic v hloubce 1
  757.  
  758.         # Generování všech pozic
  759.         while M < N:
  760.             M += 1
  761.             current_fen = POZ[M]
  762.             board.set_custom_fen(current_fen)
  763.             simplified_current_fen = simplify_fen(current_fen)
  764.             current_depth = AR[simplified_current_fen]['depth']
  765.  
  766.             if current_depth not in positions_at_depth:
  767.                 positions_at_depth[current_depth] = 0
  768.                 if current_depth > 0:
  769.                     depth_time = time.time() - depth_start_time
  770.                     total_time = time.time() - start_time
  771.                     print(f"\nHloubka {current_depth - 1}: {positions_at_depth[current_depth - 1]} pozic, "
  772.                           f"Čas hloubky: {format_time(depth_time)} / Celkový čas: {format_time(total_time)}")
  773.                    
  774.                     if current_depth == 1:
  775.                         print("Všechny pozice v hloubce 1:")
  776.                         for pos in depth_1_positions:
  777.                             print_board(pos)
  778.                             print(pos)
  779.                             print()
  780.                
  781.                 depth_start_time = time.time()
  782.  
  783.             positions_at_depth[current_depth] += 1
  784.  
  785.             if current_depth == 1:
  786.                 depth_1_positions.append(current_fen)
  787.  
  788.             if AR[simplified_current_fen]['used'] == 0:
  789.                 AR[simplified_current_fen]['used'] = 1
  790.                 legal_moves = list(board.legal_moves)
  791.                 for move in legal_moves:
  792.                     board.push(move)
  793.                     POZ2 = board.fen()
  794.                    
  795.                     # Zpracování proměny pěšce
  796.                     if move.promotion:
  797.                         promotion_piece = 'Q' if board.turn == chess.BLACK else 'q'
  798.                         POZ2_parts = POZ2.split()
  799.                         POZ2_board = POZ2_parts[0].split('/')
  800.                         promotion_rank = 7 if board.turn == chess.BLACK else 0
  801.                         POZ2_board[promotion_rank] = POZ2_board[promotion_rank].replace('P', promotion_piece).replace('p', promotion_piece)
  802.                         POZ2_parts[0] = '/'.join(POZ2_board)
  803.                         POZ2 = ' '.join(POZ2_parts)
  804.                    
  805.                     simplified_POZ2 = simplify_fen(POZ2)
  806.                     if simplified_POZ2 not in AR:
  807.                         N += 1
  808.                         POZ[N] = simplified_POZ2
  809.                         AR[simplified_POZ2] = {'used': 0, 'to_end': None, 'depth': current_depth + 1, 'type': 'normal'}
  810.                     board.pop()
  811.    
  812.         # Tisk poslední hloubky
  813.         depth_time = time.time() - depth_start_time
  814.         total_time = time.time() - start_time
  815.         print(f"\nHloubka {current_depth}: {positions_at_depth[current_depth]} pozic, "
  816.               f"Čas hloubky: {format_time(depth_time)} / Celkový čas: {format_time(total_time)}")
  817.         print(f"Příklad pozice v hloubce {current_depth}:")
  818.         print_board(current_fen)
  819.  
  820.         print(f"Generování pozic dokončeno. Celkový počet pozic: {N}")
  821.  
  822.         # Počáteční ohodnocení
  823.         print("\nZačínám počáteční ohodnocení...")
  824.         F = 0
  825.         for i in range(1, N + 1):
  826.             current_fen = POZ[i]
  827.             board.set_custom_fen(current_fen)
  828.             simplified_current_fen = simplify_fen(current_fen)
  829.             if board.is_checkmate():
  830.                 AR[simplified_current_fen]['to_end'] = -1000 if board.turn == chess.WHITE else 1000
  831.                 AR[simplified_current_fen]['type'] = 'checkmate'
  832.                 F += 1
  833.             elif board.is_stalemate():
  834.                 AR[simplified_current_fen]['to_end'] = 0
  835.                 AR[simplified_current_fen]['type'] = 'stalemate'
  836.             elif board.is_insufficient_material():
  837.                 AR[simplified_current_fen]['to_end'] = 0
  838.                 AR[simplified_current_fen]['type'] = 'insufficient_material'
  839.             else:
  840.                 AR[simplified_current_fen]['type'] = 'check' if board.is_check() else 'normal'
  841.  
  842.         print(f"Počet pozic v matu je {F}")
  843.         print(f"Počet pozic v patu je {sum(1 for data in AR.values() if data['type'] == 'stalemate')}")
  844.         print(f"Počet pozic s nedostatečným materiálem je {sum(1 for data in AR.values() if data['type'] == 'insufficient_material')}")
  845.         print(f"Počet pozic v šachu je {sum(1 for data in AR.values() if data['type'] == 'check')}")
  846.         print(f"Počet normálních pozic je {sum(1 for data in AR.values() if data['type'] == 'normal')}")
  847.  
  848.         # Iterativní ohodnocení
  849.         print("\nZačínám iterativní ohodnocení...")
  850.         uroven = 0
  851.         while F > 0:
  852.             uroven += 1
  853.             level_start_time = time.time()
  854.             print(f"Výpočet v úrovni {uroven}")
  855.            
  856.             F = 0
  857.             current_level_positions = 0
  858.             for i in range(1, N + 1):
  859.                 current_fen = POZ[i]
  860.                 board.set_custom_fen(current_fen)
  861.                 simplified_current_fen = simplify_fen(current_fen)
  862.                 if AR[simplified_current_fen].get('to_end') is None:
  863.                     hod = -2000
  864.                     for move in board.legal_moves:
  865.                         board.push(move)
  866.                         POZ2 = board.fen()
  867.                         simplified_POZ2 = simplify_fen(POZ2)
  868.                         if simplified_POZ2 in AR:
  869.                             ar_entry = AR[simplified_POZ2]
  870.                             if ar_entry is not None and 'to_end' in ar_entry:
  871.                                 hod2 = -ar_entry['to_end'] if ar_entry['to_end'] is not None else 0
  872.                             else:
  873.                                 hod2 = 0
  874.                         else:
  875.                             hod2 = 0
  876.                         if hod2 > hod:
  877.                             hod = hod2
  878.                         board.pop()
  879.                     if hod == 1001 - uroven:
  880.                         AR[simplified_current_fen]['to_end'] = 1000 - uroven
  881.                         F += 1
  882.                         current_level_positions += 1
  883.                     elif hod == -1001 + uroven:
  884.                         AR[simplified_current_fen]['to_end'] = -1000 + uroven
  885.                         F += 1
  886.                         current_level_positions += 1
  887.             level_end_time = time.time()
  888.             total_elapsed_time = level_end_time - start_time
  889.             level_elapsed_time = level_end_time - level_start_time
  890.             print(f"Nalezeno {current_level_positions} pozic v úrovni {uroven}")
  891.             print(f"Čas úrovně: {format_time(level_elapsed_time)} / Celkový čas: {format_time(total_elapsed_time)}")
  892.  
  893.         print(f"Nalezeno {F} pozic celkem")
  894.        
  895.         print("\nVýpočet dokončen.")
  896.         return {fen: (data['to_end'], data['type']) for fen, data in AR.items() if data['to_end'] is not None}
  897.  
  898.     finally:
  899.         stop_event.set()
  900.         timer_thread.join()
  901.  
  902. # Hlavní provedení
  903. if __name__ == "__main__":
  904.     start_fen = "8/2P5/4K3/8/8/8/k7/8 w - - 0 1"
  905.    
  906.     AR = calculate_optimal_moves(start_fen)
  907.  
  908.     find_min_positive_value(AR)
  909.  
  910.     print("\nVýsledky:")
  911.     for fen, (hodnota, typ_pozice) in AR.items():
  912.         if hodnota == 984 or hodnota == -1000:
  913.             print(f"FEN: {fen}")
  914.             print(f"Hodnota: {hodnota}")
  915.             print(f"Typ pozice: {typ_pozice}")
  916.            
  917.             temp_board = CustomBoard(fen)
  918.            
  919.             if temp_board.is_checkmate():
  920.                 print("Stav: Mat")
  921.             elif temp_board.is_stalemate():
  922.                 print("Stav: Pat")
  923.             elif temp_board.is_insufficient_material():
  924.                 print("Stav: Nedostatečný materiál")
  925.             elif temp_board.is_check():
  926.                 print("Stav: Šach")
  927.             else:
  928.                 print("Stav: Normální pozice")
  929.  
  930.             print_board(fen)
  931.            
  932.             print()
  933.  
  934.     # Tisk optimálních tahů
  935.     current_fen = start_fen
  936.     simplified_current_fen = simplify_fen(current_fen)
  937.     simplified_current_fen1 = simplify_fen(current_fen)
  938.     optimal_moves = []
  939.  
  940.     while True:
  941.         board = CustomBoard(current_fen)
  942.         if board.is_game_over():
  943.             break
  944.  
  945.         hod = -2000
  946.         best_fen = None
  947.         for move in board.legal_moves:
  948.             board.push(move)
  949.             POZ2 = board.fen()
  950.            
  951.             # Zpracování proměny pěšce
  952.             if move.promotion:
  953.                 promotion_piece = 'Q' if board.turn == chess.BLACK else 'q'
  954.                 POZ2_parts = POZ2.split()
  955.                 POZ2_board = POZ2_parts[0].split('/')
  956.                 promotion_rank = 7 if board.turn == chess.BLACK else 0
  957.                 POZ2_board[promotion_rank] = POZ2_board[promotion_rank].replace('P', promotion_piece).replace('p', promotion_piece)
  958.                 POZ2_parts[0] = '/'.join(POZ2_board)
  959.                 POZ2 = ' '.join(POZ2_parts)
  960.            
  961.             simplified_POZ2 = simplify_fen(POZ2)
  962.             if simplified_POZ2 in AR:
  963.                 hod2 = -AR[simplified_POZ2][0] if AR[simplified_POZ2][0] is not None else 0
  964.                 if hod2 > hod:
  965.                     hod = hod2
  966.                     best_fen = simplified_POZ2
  967.             board.pop()
  968.  
  969.         if best_fen is None:
  970.             break
  971.  
  972.         optimal_moves.append(best_fen)
  973.         current_fen = best_fen
  974.         simplified_current_fen = simplify_fen(current_fen)
  975.  
  976.     print("\nOptimální tahy:")
  977.     for fen in reversed(optimal_moves):
  978.         print_board(fen)
  979.         print(AR[fen])
  980.         print(fen)
  981.         print("\n")
  982.  
  983.     print_board("Q7/8/8/k1K5/8/8/8/8 b - - 0 1")
  984.  #   if " Q7/8/8/k1K5/8/8/8/8 b - - 0 1" in AR:
  985.     print(AR["Q7/8/8/k1K5/8/8/8/8 b - -"])
  986.     #else:
  987.     #    print(f"Pozice {simplified_current_fen1} není v AR")
  988.     #print(simplified_current_fen1)
  989.     #print("\n")
  990.  
  991.     print("\nPrvních 10 pozic s typem 'checkmate':")
  992.     count = 0
  993.     for fen, (to_end, type_pozice) in AR.items():
  994.         if type_pozice == 'stalemate':
  995.             print(f"FEN: {fen}")
  996.             print(f"To End: {to_end}")
  997.             print(f"Type: {type_pozice}")
  998.             print_board(fen)
  999.             print()
  1000.             count += 1
  1001.             if count >= 10:
  1002.                 break
  1003.    
  1004.     print(f"Celkový počet pozic 'checkmate': {sum(1 for _, (_, type_pozice) in AR.items() if type_pozice == 'checkmate')}")
  1005.     print(f"Celkový počet pozic 'stalemate': {sum(1 for _, (_, type_pozice) in AR.items() if type_pozice == 'stalemate')}")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement