Advertisement
max2201111

amazonka,bob a cyril, Petr posledni verze still 0 pozic

Jun 27th, 2024
446
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.14 KB | Science | 0 0
  1. import chess
  2. import time
  3. from functools import lru_cache
  4.  
  5. # Custom piece classes
  6. class CustomPiece(chess.Piece):
  7.     def __init__(self, piece_type, color):
  8.         super().__init__(piece_type, color)
  9.  
  10. class Amazon(CustomPiece):
  11.     def __init__(self, color):
  12.         super().__init__(chess.PAWN, color)  # PAWN as a placeholder
  13.  
  14.     def symbol(self):
  15.         return 'A' if self.color == chess.WHITE else 'a'
  16.  
  17. class Bob(CustomPiece):
  18.     def __init__(self, color):
  19.         super().__init__(chess.PAWN, color)  # PAWN as a placeholder
  20.  
  21.     def symbol(self):
  22.         return 'B' if self.color == chess.WHITE else 'b'
  23.  
  24. class Cyryl(CustomPiece):
  25.     def __init__(self, color):
  26.         super().__init__(chess.PAWN, color)  # PAWN as a placeholder
  27.  
  28.     def symbol(self):
  29.         return 'C' if self.color == chess.WHITE else 'c'
  30.  
  31. class CustomBoard(chess.Board):
  32.     def __init__(self, fen=None):
  33.         self.custom_pieces = {
  34.             'A': Amazon(chess.WHITE), 'a': Amazon(chess.BLACK),
  35.             'B': Bob(chess.WHITE), 'b': Bob(chess.BLACK),
  36.             'C': Cyryl(chess.WHITE), 'c': Cyryl(chess.BLACK)
  37.         }
  38.         super().__init__(fen)
  39.  
  40.     def set_fen(self, fen):
  41.         parts = fen.split(' ')
  42.         while len(parts) < 6:
  43.             parts.append("0")
  44.         board_part = parts[0]
  45.         turn_part = parts[1]
  46.         castling_part = parts[2]
  47.         en_passant_part = parts[3]
  48.         halfmove_clock = parts[4]
  49.         fullmove_number = parts[5]
  50.  
  51.         self.set_board_fen(board_part)
  52.         self.turn = chess.WHITE if turn_part == 'w' else chess.BLACK
  53.         self.castling_rights = chess.BB_EMPTY if castling_part == '-' else chess.SquareSet.from_square(chess.parse_square(castling_part))
  54.         self.ep_square = None if en_passant_part == '-' else chess.parse_square(en_passant_part)
  55.         self.halfmove_clock = int(halfmove_clock)
  56.         self.fullmove_number = int(fullmove_number)
  57.  
  58.     def set_board_fen(self, fen):
  59.         self.clear()
  60.         rows = fen.split('/')
  61.         for rank, row in enumerate(rows):
  62.             file = 0
  63.             for char in row:
  64.                 if char.isdigit():
  65.                     file += int(char)
  66.                 else:
  67.                     square = chess.square(file, 7 - rank)
  68.                     if char in self.custom_pieces:
  69.                         self.set_piece_at(square, self.custom_pieces[char])
  70.                     else:
  71.                         self.set_piece_at(square, chess.Piece.from_symbol(char))
  72.                     file += 1
  73.  
  74.     def generate_legal_moves(self, from_mask=chess.BB_ALL, to_mask=chess.BB_ALL):
  75.         for move in super().generate_legal_moves(from_mask, to_mask):
  76.             yield move
  77.        
  78.         for square in self.piece_map():
  79.             piece = self.piece_at(square)
  80.             if piece.symbol().lower() in ['a', 'b', 'c']:
  81.                 yield from self.generate_custom_piece_moves(square, piece)
  82.  
  83.     def generate_custom_piece_moves(self, square, piece):
  84.         directions = []
  85.         knight_moves = [
  86.             (2, 1), (2, -1), (-2, 1), (-2, -1),
  87.             (1, 2), (1, -2), (-1, 2), (-1, -2)
  88.         ]
  89.  
  90.         if piece.symbol().lower() == 'a':  # Amazon: Bishop + Knight moves
  91.             directions = [
  92.                 (1, 1), (1, -1), (-1, 1), (-1, -1)  # Bishop directions
  93.             ]
  94.             moves = self.generate_sliding_moves(square, directions) + self.generate_knight_moves(square, knight_moves)
  95.         elif piece.symbol().lower() == 'b':  # Bob: Rook + Knight moves
  96.             directions = [
  97.                 (1, 0), (0, 1), (-1, 0), (0, -1)  # Rook directions
  98.             ]
  99.             moves = self.generate_sliding_moves(square, directions) + self.generate_knight_moves(square, knight_moves)
  100.         elif piece.symbol().lower() == 'c':  # Cyryl: Queen + Knight moves
  101.             directions = [
  102.                 (1, 1), (1, -1), (-1, 1), (-1, -1),  # Bishop directions
  103.                 (1, 0), (0, 1), (-1, 0), (0, -1)  # Rook directions
  104.             ]
  105.             moves = self.generate_sliding_moves(square, directions) + self.generate_knight_moves(square, knight_moves)
  106.        
  107.         for move in moves:
  108.             if self.is_pseudo_legal(move):
  109.                 yield move
  110.  
  111.     def generate_sliding_moves(self, square, directions):
  112.         moves = []
  113.         for dx, dy in directions:
  114.             x, y = chess.square_file(square), chess.square_rank(square)
  115.             while True:
  116.                 x, y = x + dx, y + dy
  117.                 if 0 <= x < 8 and 0 <= y < 8:
  118.                     dest_square = chess.square(x, y)
  119.                     move = chess.Move(square, dest_square)
  120.                     moves.append(move)
  121.                     if self.piece_at(dest_square):
  122.                         break
  123.                 else:
  124.                     break
  125.         return moves
  126.  
  127.     def generate_knight_moves(self, square, knight_moves):
  128.         moves = []
  129.         for dx, dy in knight_moves:
  130.             file = chess.square_file(square) + dx
  131.             rank = chess.square_rank(square) + dy
  132.             if 0 <= file < 8 and 0 <= rank < 8:
  133.                 dest_square = chess.square(file, rank)
  134.                 move = chess.Move(square, dest_square)
  135.                 moves.append(move)
  136.         return moves
  137.  
  138. @lru_cache(maxsize=None)
  139. def simplify_fen_string(fen):
  140.     parts = fen.split(' ')
  141.     simplified_fen = ' '.join(parts[:4])  # Zachováváme pouze informace o pozici
  142.     if len(parts) < 6:
  143.         simplified_fen += " 0 1"
  144.     return simplified_fen
  145.  
  146. def print_board(fen):
  147.     board = CustomBoard(fen)
  148.     print(board)
  149.  
  150. # Startovní pozice
  151. start_fen = "8/6A1/8/8/8/k1K5/8/8 w - - 0 1"
  152. simplified_POZ2 = simplify_fen_string(start_fen)
  153. POZ = {1: simplified_POZ2}
  154.  
  155. AR = {simplified_POZ2: {'used': 0, 'to_end': 0}}
  156. N = 1
  157. M = 0
  158.  
  159. start_time = time.time()
  160.  
  161. def format_elapsed_time(elapsed_time):
  162.     hours, remainder = divmod(elapsed_time, 3600)
  163.     minutes, seconds = divmod(remainder, 60)
  164.     return f"{int(hours)}h {int(minutes)}m {int(seconds)}s"
  165.  
  166. def print_elapsed_time(total_time, level_time):
  167.     print(f"{format_elapsed_time(total_time)} / {format_elapsed_time(level_time)}")
  168.  
  169. while M < N:
  170.     M += 1
  171.     current_fen = POZ[M]
  172.     board = CustomBoard(current_fen)
  173.     simplified_current_fen = simplify_fen_string(current_fen)
  174.  
  175.     if simplified_current_fen not in AR:
  176.         AR[simplified_current_fen] = {'used': 0, 'to_end': 0}
  177.  
  178.     if AR[simplified_current_fen]['used'] == 0:
  179.         AR[simplified_current_fen]['used'] = 1
  180.         for move in board.legal_moves:
  181.             # Check if the move is a promotion
  182.             if move.promotion:
  183.                 move.promotion = chess.QUEEN  # Set promotion to queen only
  184.  
  185.             board.push(move)
  186.             POZ2 = board.fen()
  187.             simplified_POZ2 = simplify_fen_string(POZ2)
  188.  
  189.             if simplified_POZ2 not in AR:
  190.                 AR[simplified_POZ2] = {'used': None, 'to_end': 0}
  191.  
  192.             if AR[simplified_POZ2]['used'] is None:
  193.                 N += 1
  194.                 POZ[N] = simplified_POZ2
  195.                 AR[simplified_POZ2] = {'used': 0, 'to_end': 0}
  196.  
  197.             board.pop()  # Vrátíme tah zpět
  198.  
  199. print(f"Počet pozic je {N}")
  200.  
  201. # Přidání kontroly pro mat, remízu a výchozí hodnotu
  202. F = 0
  203. for i in range(1, N + 1):
  204.     current_fen = POZ[i]
  205.     board = CustomBoard(current_fen)
  206.     simplified_current_fen = simplify_fen_string(current_fen)
  207.  
  208.     if simplified_current_fen not in AR:
  209.         AR[simplified_current_fen] = {'used': 0, 'to_end': 0}
  210.  
  211.     if board.is_checkmate():
  212.         AR[simplified_current_fen]['to_end'] = -1000
  213.         F += 1
  214.     elif board.is_stalemate() or board.is_insufficient_material() or board.is_seventyfive_moves() or board.is_fivefold_repetition():
  215.         AR[simplified_current_fen]['to_end'] = 0
  216.     else:
  217.         AR[simplified_current_fen]['to_end'] = 0
  218.  
  219. print(f"Počet pozic v matu je {F}")
  220.  
  221. uroven = 0
  222. while F > 0:
  223.     uroven += 1
  224.     level_start_time = time.time()
  225.     print(f"Výpočet v úrovni {uroven}")
  226.    
  227.     F = 0
  228.     current_level_positions = 0
  229.     for i in range(1, N + 1):
  230.         current_fen = POZ[i]
  231.         board = CustomBoard(current_fen)
  232.         simplified_current_fen = simplify_fen_string(current_fen)
  233.         if AR[simplified_current_fen]['to_end'] == 0:
  234.             hod = -2000
  235.             for move in board.legal_moves:
  236.                 # Check if the move is a promotion
  237.                 if move.promotion:
  238.                     move.promotion = chess.QUEEN  # Set promotion to queen only
  239.  
  240.                 board.push(move)
  241.                 POZ2 = board.fen()
  242.                 simplified_POZ2 = simplify_fen_string(POZ2)
  243.                 if simplified_POZ2 not in AR:
  244.                     AR[simplified_POZ2] = {'used': None, 'to_end': 0}
  245.  
  246.                 hod2 = -AR[simplified_POZ2]['to_end']
  247.                 if hod2 > hod:
  248.                     hod = hod2
  249.                 board.pop()  # Vrátíme tah zpět
  250.             if hod == 1001 - uroven:
  251.                 AR[simplified_current_fen]['to_end'] = 1000 - uroven
  252.                 F += 1
  253.                 current_level_positions += 1
  254.             if hod == -1001 + uroven:
  255.                 AR[simplified_current_fen]['to_end'] = -1000 + uroven
  256.                 F += 1
  257.                 current_level_positions += 1
  258.     level_end_time = time.time()
  259.     total_elapsed_time = level_end_time - start_time
  260.     level_elapsed_time = level_end_time - level_start_time
  261.     print(f"Nalezeno {current_level_positions} pozic v úrovni {uroven}")
  262.     print_elapsed_time(total_elapsed_time, level_elapsed_time)
  263.  
  264. print(f"Nalezeno {F} pozic celkem")
  265.  
  266. # Výpis všech pozic s to_end == 17
  267. print("Pozice s to_end == 17:")
  268. for fen, data in AR.items():
  269.     if data['to_end'] == 17:
  270.         print(f"{fen} -> to_end: {data['to_end']}")
  271.  
  272. print("*****")
  273.  
  274. print("Pozice s to_end == -20:")
  275. for fen, data in AR.items():
  276.     if data['to_end'] == -20:
  277.         print(f"{fen} -> to_end: {data['to_end']}")
  278.  
  279. current_fen = POZ[1]
  280. board = CustomBoard(current_fen)
  281. simplified_current_fen = simplify_fen_string(current_fen)
  282. hod = AR[simplified_current_fen]['to_end']
  283. print(f"Hodnocení počáteční pozice je {hod}")
  284.  
  285. # Závěrečný kód pro procházení nejlepších tahů
  286. current_fen = start_fen
  287. simplified_current_fen = simplify_fen_string(current_fen)
  288.  
  289. optimal_moves = []
  290. while AR[simplified_current_fen]['to_end'] > -1000:
  291.     board = CustomBoard(current_fen)
  292.     simplified_current_fen = simplify_fen_string(current_fen)
  293.     hod = -2000
  294.     for move in board.legal_moves:
  295.         # Check if the move is a promotion
  296.         if move.promotion:
  297.             move.promotion = chess.QUEEN  # Set promotion to queen only
  298.  
  299.         board.push(move)
  300.         POZ2 = board.fen()
  301.         simplified_POZ2 = simplify_fen_string(POZ2)
  302.         hod2 = -AR[simplified_POZ2]['to_end']
  303.         if hod2 > hod:
  304.             hod = hod2
  305.             best_fen = simplified_POZ2
  306.         board.pop()  # Vrátíme tah zpět
  307.  
  308.     optimal_moves.append(best_fen)
  309.     current_fen = best_fen
  310.     simplified_current_fen = simplify_fen_string(current_fen)
  311.  
  312. # Tisk šachovnic v opačném pořadí
  313. for fen in reversed(optimal_moves):
  314.     print_board(fen)
  315.     print("\n")
  316.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement