Advertisement
max2201111

divny vystup s 1 pozici KOD

Jul 3rd, 2024
601
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 15.22 KB | Science | 0 0
  1. import chess
  2. import time
  3. from functools import lru_cache
  4. import traceback
  5. from typing import Iterator
  6. from chess import Move, BB_ALL, Bitboard, scan_reversed
  7.  
  8. # Definice nových figurek
  9. AMAZON = 7
  10. CYRIL = 8
  11. EVA = 9
  12.  
  13. # Nová funkce attacks_mask
  14. def new_attacks_mask(self, piece_type, square, occupied):
  15.     print("new_attacks_mask")
  16.     bb_square = chess.BB_SQUARES[square]
  17.  
  18.     if piece_type == chess.PAWN:
  19.         color = bool(bb_square & self.occupied_co[chess.WHITE])
  20.         return chess.BB_PAWN_ATTACKS[color][square]
  21.     elif piece_type == chess.KNIGHT:
  22.         return chess.BB_KNIGHT_ATTACKS[square]
  23.     elif piece_type == chess.KING:
  24.         return chess.BB_KING_ATTACKS[square]
  25.     else:
  26.         attacks = 0
  27.         if piece_type == chess.BISHOP or piece_type == chess.QUEEN:
  28.             attacks = chess.BB_DIAG_ATTACKS[square][chess.BB_DIAG_MASKS[square] & occupied]
  29.         if piece_type == chess.ROOK or piece_type == chess.QUEEN:
  30.             attacks |= (chess.BB_RANK_ATTACKS[square][chess.BB_RANK_MASKS[square] & occupied] |
  31.                         chess.BB_FILE_ATTACKS[square][chess.BB_FILE_MASKS[square] & occupied])
  32.         if piece_type == AMAZON:
  33.             attacks = (chess.BB_KNIGHT_ATTACKS[square] |
  34.                        chess.BB_DIAG_ATTACKS[square][chess.BB_DIAG_MASKS[square] & occupied])
  35.         elif piece_type == CYRIL:
  36.             attacks = (chess.BB_KNIGHT_ATTACKS[square] |
  37.                        chess.BB_RANK_ATTACKS[square][chess.BB_RANK_MASKS[square] & occupied] |
  38.                        chess.BB_FILE_ATTACKS[square][chess.BB_FILE_MASKS[square] & occupied])
  39.         elif piece_type == EVA:
  40.             attacks = (chess.BB_KNIGHT_ATTACKS[square] |
  41.                        chess.BB_DIAG_ATTACKS[square][chess.BB_DIAG_MASKS[square] & occupied])
  42.         return attacks
  43.  
  44. # Přiřazení nové funkce
  45. chess.BaseBoard.attacks_mask = new_attacks_mask
  46.  
  47. class CustomBoard(chess.Board):
  48.     def __init__(self, fen=None):
  49.         print("__init__")
  50.         super().__init__(fen)
  51.         self._custom_piece_map = self._parse_custom_fen(fen) if fen else self._custom_piece_map()
  52.  
  53.     def _parse_custom_fen(self, fen):
  54.         print("_parse_custom_fen")
  55.         piece_map = {}
  56.         square = 0
  57.         for char in fen.split()[0]:
  58.             if char.isdigit():
  59.                 square += int(char)
  60.             elif char == '/':
  61.                 continue
  62.             else:
  63.                 color = chess.WHITE if char.isupper() else chess.BLACK
  64.                 piece_type = {
  65.                     'A': AMAZON,
  66.                     'C': CYRIL,
  67.                     'E': EVA,
  68.                     'P': chess.PAWN,
  69.                     'N': chess.KNIGHT,
  70.                     'B': chess.BISHOP,
  71.                     'R': chess.ROOK,
  72.                     'Q': chess.QUEEN,
  73.                     'K': chess.KING
  74.                 }.get(char.upper(), None)
  75.                 if piece_type:
  76.                     piece = chess.Piece(piece_type, color)
  77.                     piece_map[square] = piece
  78.                 square += 1
  79.         return piece_map
  80.  
  81.     def piece_symbol(self, piece):
  82.         print("piece_symbol")
  83.         if piece is None:
  84.             return "."
  85.         if piece.piece_type == AMAZON:
  86.             return "A" if piece.color == chess.WHITE else "a"
  87.         if piece.piece_type == CYRIL:
  88.             return "C" if piece.color == chess.WHITE else "c"
  89.         if piece.piece_type == EVA:
  90.             return "E" if piece.color == chess.WHITE else "e"
  91.         return chess.PIECE_SYMBOLS[piece.piece_type].upper() if piece.color == chess.WHITE else chess.PIECE_SYMBOLS[piece.piece_type]
  92.  
  93.     def board_fen(self):
  94.         print("board_fen")
  95.         empty_squares = 0
  96.         fen = []
  97.  
  98.         for square in chess.SQUARES_180:
  99.             piece = self._custom_piece_map.get(square)
  100.             if piece:
  101.                 if empty_squares:
  102.                     fen.append(str(empty_squares))
  103.                     empty_squares = 0
  104.                 fen.append(self.piece_symbol(piece))
  105.             else:
  106.                 empty_squares += 1
  107.             if chess.square_file(square) == 7:
  108.                 if empty_squares:
  109.                     fen.append(str(empty_squares))
  110.                     empty_squares = 0
  111.                 if square != chess.H1:
  112.                     fen.append('/')
  113.  
  114.         return ''.join(fen)
  115.  
  116.     def _custom_piece_map(self):
  117.         print("_custom_piece_map")
  118.         piece_map = {}
  119.         for square, piece in self.piece_map().items():
  120.             piece_map[square] = piece
  121.         return piece_map
  122.  
  123.     def to_string(self):
  124.         print("to_string")
  125.         builder = []
  126.         for square in chess.SQUARES_180:
  127.             piece = self._custom_piece_map.get(square)
  128.             symbol = self.piece_symbol(piece)
  129.             builder.append(symbol)
  130.             if chess.square_file(square) == 7:
  131.                 if square != chess.H1:
  132.                     builder.append("\n")
  133.         return "".join(builder)
  134.  
  135.     def generate_pseudo_legal_moves(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboard = BB_ALL) -> Iterator[chess.Move]:
  136.         print("generate_pseudo_legal_moves")
  137.         our_pieces = self.occupied_co[self.turn]
  138.  
  139.         # Generate piece moves.
  140.         non_pawns = our_pieces & ~self.pawns & from_mask
  141.         for from_square in scan_reversed(non_pawns):
  142.             piece_type = self.piece_type_at(from_square)
  143.             moves = self.attacks_mask(piece_type, from_square, self.occupied) & ~our_pieces & to_mask
  144.             for to_square in scan_reversed(moves):
  145.                 yield Move(from_square, to_square)
  146.  
  147.         # Generate castling moves.
  148.         if from_mask & self.kings:
  149.             yield from self.generate_castling_moves(from_mask, to_mask)
  150.  
  151.         # The remaining moves are all pawn moves.
  152.         pawns = self.pawns & self.occupied_co[self.turn] & from_mask
  153.         if not pawns:
  154.             return
  155.  
  156.         # Generate pawn moves.
  157.         yield from self.generate_pseudo_legal_pawn_moves(pawns, to_mask)
  158.  
  159.         # Generate pawn captures.
  160.         capturers = pawns
  161.         for from_square in scan_reversed(capturers):
  162.             targets = (
  163.                 chess.BB_PAWN_ATTACKS[self.turn][from_square] &
  164.                 self.occupied_co[not self.turn] & to_mask)
  165.  
  166.             for to_square in scan_reversed(targets):
  167.                 if chess.square_rank(to_square) in [0, 7]:
  168.                     yield Move(from_square, to_square, chess.QUEEN)
  169.                     yield Move(from_square, to_square, chess.ROOK)
  170.                     yield Move(from_square, to_square, chess.BISHOP)
  171.                     yield Move(from_square, to_square, chess.KNIGHT)
  172.                 else:
  173.                     yield Move(from_square, to_square)
  174.  
  175.     def is_check(self):
  176.         print("is_check")
  177.         king_square = self.king(self.turn)
  178.         if king_square is None:
  179.             return False
  180.  
  181.         if super().is_check():
  182.             return True
  183.  
  184.         opponent_color = not self.turn
  185.         for square, piece in self._custom_piece_map.items():
  186.             if piece.color == opponent_color:
  187.                 if piece.piece_type in [AMAZON, CYRIL, EVA]:
  188.                     if self._is_attacked_by_new_piece(king_square, square, piece.piece_type):
  189.                         return True
  190.  
  191.         return False
  192.  
  193.     def _is_attacked_by_new_piece(self, target_square, attacker_square, piece_type):
  194.         print("_is_attacked_by_new_piece")
  195.         if piece_type == AMAZON:
  196.             return (self.attacks_knight(attacker_square) | self.attacks_bishop(attacker_square)) & chess.BB_SQUARES[target_square]
  197.         elif piece_type == CYRIL:
  198.             return (self.attacks_knight(attacker_square) | self.attacks_rook(attacker_square)) & chess.BB_SQUARES[target_square]
  199.         elif piece_type == EVA:
  200.             return (self.attacks_queen(attacker_square) | self.attacks_knight(attacker_square)) & chess.BB_SQUARES[target_square]
  201.         return False
  202.  
  203.     def attacks_knight(self, square):
  204.         return self.attacks_mask(chess.KNIGHT, square, self.occupied)
  205.  
  206.     def attacks_bishop(self, square):
  207.         return self.attacks_mask(chess.BISHOP, square, self.occupied)
  208.  
  209.     def attacks_rook(self, square):
  210.         return self.attacks_mask(chess.ROOK, square, self.occupied)
  211.  
  212.     def attacks_queen(self, square):
  213.         return self.attacks_bishop(square) | self.attacks_rook(square)
  214.  
  215.     @property
  216.     def legal_moves(self):
  217.         print("legal_moves")
  218.         return [move for move in self.generate_pseudo_legal_moves() if self.is_legal(move)]
  219.  
  220. @lru_cache(maxsize=None)
  221. def simplify_fen_string(fen):
  222.     print("simplify_fen_string")
  223.     parts = fen.split(' ')
  224.     simplified_fen = ' '.join(parts[:4] + ["0", "1"])
  225.     return simplified_fen
  226.  
  227. def print_board(fen):
  228.     print("print_board")
  229.     board = CustomBoard(fen)
  230.     print(board.to_string())
  231.     print()  # Add an empty line after the board
  232.  
  233. def format_time(seconds):
  234.     print("format_time")
  235.     hours, remainder = divmod(seconds, 3600)
  236.     minutes, seconds = divmod(remainder, 60)
  237.     return f"{int(hours):02d}h {int(minutes):02d}m {int(seconds):02d}s"
  238.  
  239. def analyze_positions(start_fen):
  240.     print("analyze_positions")
  241.     print("Initializing analysis...")
  242.     POZ = {1: start_fen}
  243.     AR = {simplify_fen_string(start_fen): {'used': 0, 'to_end': None}}
  244.     N = 1
  245.     M = 0
  246.  
  247.     start_time = time.time()
  248.     total_time = 0
  249.  
  250.     print("Generování pozic...")
  251.     while M < N:
  252.         M += 1
  253.         current_fen = POZ[M]
  254.         board = CustomBoard(current_fen)
  255.  
  256.         legal_moves = list(board.legal_moves)
  257.  
  258.         if AR[simplify_fen_string(current_fen)]['used'] == 0:
  259.             AR[simplify_fen_string(current_fen)]['used'] = 1
  260.             for move in legal_moves:
  261.                 board.push(move)
  262.                 POZ2 = board.fen()
  263.                 simplified_POZ2 = simplify_fen_string(POZ2)
  264.                 if simplified_POZ2 not in AR:
  265.                     N += 1
  266.                     POZ[N] = POZ2
  267.                     AR[simplified_POZ2] = {'used': 0, 'to_end': None}
  268.                 board.pop()
  269.  
  270.         if M % 100 == 0:  # Průběžný výpis každých 100 pozic
  271.             print(f"Zpracováno {M} pozic, celkem {N} pozic")
  272.             print(f"Čas: {format_time(time.time() - start_time)}")
  273.  
  274.     print(f"Počet pozic je {N}")
  275.  
  276.     F = 0
  277.     for i in range(1, N + 1):
  278.         current_fen = POZ[i]
  279.         board = CustomBoard(current_fen)
  280.         simplified_fen = simplify_fen_string(current_fen)
  281.  
  282.         if board.is_checkmate():
  283.             AR[simplified_fen]['to_end'] = -1000 if board.turn == chess.WHITE else 1000
  284.             F += 1
  285.         elif board.is_stalemate() or board.is_insufficient_material() or board.is_seventyfive_moves() or board.is_fivefold_repetition():
  286.             AR[simplified_fen]['to_end'] = 0
  287.         else:
  288.             AR[simplified_fen]['to_end'] = 0
  289.  
  290.     print(f"Počet pozic v matu je {F}")
  291.  
  292.     uroven = 0
  293.     while F > 0:
  294.         uroven += 1
  295.         level_start_time = time.time()
  296.         print(f"Výpočet v úrovni {uroven}")
  297.        
  298.         F = 0
  299.         current_level_positions = 0
  300.         for i in range(1, N + 1):
  301.             current_fen = POZ[i]
  302.             board = CustomBoard(current_fen)
  303.             simplified_fen = simplify_fen_string(current_fen)
  304.             if AR[simplified_fen]['to_end'] == 0:
  305.                 hod = -2000 if board.turn == chess.WHITE else 2000
  306.                 for move in board.legal_moves:
  307.                     board.push(move)
  308.                     POZ2 = board.fen()
  309.                     simplified_POZ2 = simplify_fen_string(POZ2)
  310.                     hod2 = -AR[simplified_POZ2]['to_end']
  311.                     if board.turn == chess.WHITE:
  312.                         if hod2 > hod:
  313.                             hod = hod2
  314.                     else:
  315.                         if hod2 < hod:
  316.                             hod = hod2
  317.                     board.pop()
  318.                 if (board.turn == chess.WHITE and hod == 1001 - uroven) or (board.turn == chess.BLACK and hod == -1001 + uroven):
  319.                     AR[simplified_fen]['to_end'] = 1000 - uroven if board.turn == chess.WHITE else -1000 + uroven
  320.                     F += 1
  321.                     current_level_positions += 1
  322.        
  323.         level_end_time = time.time()
  324.         level_elapsed_time = level_end_time - level_start_time
  325.         total_time += level_elapsed_time
  326.        
  327.         formatted_total_time = format_time(total_time)
  328.         formatted_level_time = format_time(level_elapsed_time)
  329.        
  330.         print(f"Nalezeno {current_level_positions} pozic v úrovni {uroven}")
  331.         print(f"Čas: {formatted_total_time} / {formatted_level_time}")
  332.  
  333.     print(f"Nalezeno {F} pozic celkem")
  334.     print(f"Celkový čas: {format_time(total_time)}")
  335.  
  336.     current_fen = POZ[1]
  337.     hod = AR[simplify_fen_string(current_fen)]['to_end']
  338.     print(f"Hodnocení počáteční pozice je {hod}")
  339.  
  340.     # Procházení nejlepších tahů
  341.     current_fen = start_fen
  342.  
  343.     optimal_moves = []
  344.     while AR[simplify_fen_string(current_fen)]['to_end'] is not None and AR[simplify_fen_string(current_fen)]['to_end'] != 1000 and AR[simplify_fen_string(current_fen)]['to_end'] != -1000:
  345.         board = CustomBoard(current_fen)
  346.         hod = -2000 if board.turn == chess.WHITE else 2000
  347.         best_move = None
  348.         for move in board.legal_moves:
  349.             board.push(move)
  350.             POZ2 = board.fen()
  351.             simplified_POZ2 = simplify_fen_string(POZ2)
  352.             if AR[simplified_POZ2]['to_end'] is not None:
  353.                 hod2 = -AR[simplified_POZ2]['to_end']
  354.                 if (board.turn == chess.WHITE and hod2 > hod) or (board.turn == chess.BLACK and hod2 < hod):
  355.                     hod = hod2
  356.                     best_move = move
  357.             board.pop()
  358.  
  359.         if best_move is None:
  360.             break
  361.  
  362.         board.push(best_move)
  363.         optimal_moves.append((current_fen, best_move))
  364.         current_fen = board.fen()
  365.  
  366.     # Tisk optimálních tahů
  367.     print("\nOptimální tahy:")
  368.     for fen, move in optimal_moves:
  369.         board = CustomBoard(fen)
  370.         print(f"{board.fullmove_number}. {'Bílý' if board.turn == chess.WHITE else 'Černý'}: {move}")
  371.         print_board(fen)
  372.         print("\n")
  373.  
  374.     print("Konečná pozice:")
  375.     print_board(current_fen)
  376.  
  377. if __name__ == "__main__":
  378.     start_fen = "1a6/3k4/8/8/8/8/8/6K1 b - - 0 1"
  379.     print("Starting analysis...")
  380.     print("Initial position:")
  381.     print_board(start_fen)
  382.    
  383.     try:
  384.         print("Creating initial board...")
  385.         initial_board = CustomBoard(start_fen)
  386.         print("Initial board created successfully.")
  387.        
  388.         print("Piece map:")
  389.         for square, piece in initial_board._custom_piece_map.items():
  390.             print(f"Square {chess.SQUARE_NAMES[square]}: {initial_board.piece_symbol(piece)}")
  391.        
  392.         print("Generating legal moves for initial position...")
  393.         legal_moves = list(initial_board.legal_moves)
  394.         print(f"Number of legal moves: {len(legal_moves)}")
  395.         for move in legal_moves:
  396.             print(f"Move: {move}")
  397.        
  398.         print("Starting position analysis...")
  399.         analyze_positions(start_fen)
  400.     except Exception as e:
  401.         print(f"An error occurred: {str(e)}")
  402.         traceback.print_exc()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement