Advertisement
max2201111

lepsi 23 pozic porad hraje jako b

Jul 3rd, 2024
632
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 21.18 KB | Science | 0 0
  1. import sys
  2. print("Python verze:", sys.version)
  3. print("Skript se spouští...")
  4.  
  5. import chess
  6. import time
  7. from functools import lru_cache
  8. import traceback
  9. from typing import Iterator
  10. from chess import Move, BB_ALL, Bitboard, scan_reversed
  11.  
  12. # Definice nových figurek
  13. AMAZON = 7
  14. CYRIL = 8
  15. EVA = 9
  16.  
  17. # Nová funkce attacks_mask
  18. def new_attacks_mask(self, piece_type, square, occupied):
  19.     print("new_attacks_mask")
  20.     bb_square = chess.BB_SQUARES[square]
  21.  
  22.     if piece_type == chess.PAWN:
  23.         color = bool(bb_square & self.occupied_co[chess.WHITE])
  24.         return chess.BB_PAWN_ATTACKS[color][square]
  25.     elif piece_type == chess.KNIGHT:
  26.         return chess.BB_KNIGHT_ATTACKS[square]
  27.     elif piece_type == chess.KING:
  28.         return chess.BB_KING_ATTACKS[square]
  29.     else:
  30.         attacks = 0
  31.         if piece_type == chess.BISHOP or piece_type == chess.QUEEN:
  32.             attacks = chess.BB_DIAG_ATTACKS[square][chess.BB_DIAG_MASKS[square] & occupied]
  33.         if piece_type == chess.ROOK or piece_type == chess.QUEEN:
  34.             attacks |= (chess.BB_RANK_ATTACKS[square][chess.BB_RANK_MASKS[square] & occupied] |
  35.                         chess.BB_FILE_ATTACKS[square][chess.BB_FILE_MASKS[square] & occupied])
  36.         if piece_type == AMAZON:
  37.             attacks = (chess.BB_KNIGHT_ATTACKS[square] |
  38.                        chess.BB_DIAG_ATTACKS[square][chess.BB_DIAG_MASKS[square] & occupied] |
  39.                        chess.BB_RANK_ATTACKS[square][chess.BB_RANK_MASKS[square] & occupied] |
  40.                        chess.BB_FILE_ATTACKS[square][chess.BB_FILE_MASKS[square] & occupied])
  41.         elif piece_type == CYRIL:
  42.             attacks = (chess.BB_KNIGHT_ATTACKS[square] |
  43.                        chess.BB_RANK_ATTACKS[square][chess.BB_RANK_MASKS[square] & occupied] |
  44.                        chess.BB_FILE_ATTACKS[square][chess.BB_FILE_MASKS[square] & occupied])
  45.         elif piece_type == EVA:
  46.             attacks = (chess.BB_KNIGHT_ATTACKS[square] |
  47.                        chess.BB_DIAG_ATTACKS[square][chess.BB_DIAG_MASKS[square] & occupied])
  48.         return attacks
  49.  
  50. # Přiřazení nové funkce
  51. chess.BaseBoard.attacks_mask = new_attacks_mask
  52.  
  53. class CustomBoard(chess.Board):
  54.     def __init__(self, fen=None):
  55.         print("__init__")
  56.         super().__init__(fen)  # Použijeme fen přímo
  57.         self._custom_piece_map = {}
  58.         if fen:
  59.             self._custom_piece_map = self._parse_custom_fen(fen)
  60.         else:
  61.             self._custom_piece_map = self._create_custom_piece_map()
  62.        
  63.         # Inicializace bitboardů pro nové figury
  64.         self.amazons = chess.BB_EMPTY
  65.         self.cyrils = chess.BB_EMPTY
  66.         self.evas = chess.BB_EMPTY
  67.         for square, piece in self._custom_piece_map.items():
  68.             bb = chess.BB_SQUARES[square]
  69.             if piece.piece_type == AMAZON:
  70.                 self.amazons |= bb
  71.             elif piece.piece_type == CYRIL:
  72.                 self.cyrils |= bb
  73.             elif piece.piece_type == EVA:
  74.                 self.evas |= bb
  75.         self.occupied_co[chess.WHITE] |= self.amazons | self.cyrils | self.evas
  76.         self.occupied_co[chess.BLACK] |= self.amazons | self.cyrils | self.evas
  77.         self.occupied |= self.amazons | self.cyrils | self.evas
  78.  
  79.     def set_fen(self, fen):
  80.         self._custom_piece_map = self._parse_custom_fen(fen)
  81.         super().set_fen(fen)
  82.  
  83.     def reset(self):
  84.         super().reset()
  85.         self._custom_piece_map = self._create_custom_piece_map()
  86.  
  87.     def set_piece_at(self, square, piece, promoted=False):
  88.         super().set_piece_at(square, piece, promoted)
  89.         if piece is None:
  90.             self._custom_piece_map.pop(square, None)
  91.         else:
  92.             self._custom_piece_map[square] = piece
  93.  
  94.     def _remove_piece_at(self, square):
  95.         piece = super()._remove_piece_at(square)
  96.         self._custom_piece_map.pop(square, None)
  97.         return piece
  98.  
  99.     def _parse_custom_fen(self, fen):
  100.         print("_parse_custom_fen")
  101.         piece_map = {}
  102.         board_part = fen.split()[0]
  103.         square = 0
  104.         for char in board_part:
  105.             if char.isdigit():
  106.                 square += int(char)
  107.             elif char == '/':
  108.                 continue
  109.             else:
  110.                 color = chess.WHITE if char.isupper() else chess.BLACK
  111.                 piece_type = {
  112.                     'A': AMAZON,
  113.                     'C': CYRIL,
  114.                     'E': EVA,
  115.                     'P': chess.PAWN,
  116.                     'N': chess.KNIGHT,
  117.                     'B': chess.BISHOP,
  118.                     'R': chess.ROOK,
  119.                     'Q': chess.QUEEN,
  120.                     'K': chess.KING
  121.                 }.get(char.upper(), None)
  122.                 if piece_type:
  123.                     piece = chess.Piece(piece_type, color)
  124.                     piece_map[square] = piece
  125.                 square += 1
  126.         return piece_map
  127.  
  128.     def piece_symbol(self, piece):
  129.         print("piece_symbol")
  130.         if piece is None:
  131.             return "."
  132.         if piece.piece_type == AMAZON:
  133.             return "A" if piece.color == chess.WHITE else "a"
  134.         if piece.piece_type == CYRIL:
  135.             return "C" if piece.color == chess.WHITE else "c"
  136.         if piece.piece_type == EVA:
  137.             return "E" if piece.color == chess.WHITE else "e"
  138.         return chess.PIECE_SYMBOLS[piece.piece_type].upper() if piece.color == chess.WHITE else chess.PIECE_SYMBOLS[piece.piece_type]
  139.  
  140.     def board_fen(self):
  141.         print("board_fen")
  142.         empty_squares = 0
  143.         fen = []
  144.  
  145.         for square in chess.SQUARES_180:
  146.             piece = self._custom_piece_map.get(square)
  147.             if piece:
  148.                 if empty_squares:
  149.                     fen.append(str(empty_squares))
  150.                     empty_squares = 0
  151.                 fen.append(self.piece_symbol(piece))
  152.             else:
  153.                 empty_squares += 1
  154.             if chess.square_file(square) == 7:
  155.                 if empty_squares:
  156.                     fen.append(str(empty_squares))
  157.                     empty_squares = 0
  158.                 if square != chess.H1:
  159.                     fen.append('/')
  160.  
  161.         return ''.join(fen)
  162.  
  163.     def _create_custom_piece_map(self):
  164.         print("_create_custom_piece_map")
  165.         piece_map = {}
  166.         for square, piece in self.piece_map().items():
  167.             piece_map[square] = piece
  168.         return piece_map
  169.  
  170.     def to_string(self):
  171.         print("to_string")
  172.         builder = []
  173.         for square in chess.SQUARES_180:
  174.             piece = self._custom_piece_map.get(square)
  175.             symbol = self.piece_symbol(piece)
  176.             builder.append(symbol)
  177.             if chess.square_file(square) == 7:
  178.                 if square != chess.H1:
  179.                     builder.append("\n")
  180.         return "".join(builder)
  181.  
  182.     def generate_pseudo_legal_moves(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboard = BB_ALL) -> Iterator[chess.Move]:
  183.         print("generate_pseudo_legal_moves začíná")
  184.         our_pieces = self.occupied_co[self.turn]
  185.         print(f"Na tahu je: {'Bílý' if self.turn == chess.WHITE else 'Černý'}")
  186.         print(f"Počet našich figur: {bin(our_pieces).count('1')}")
  187.  
  188.         # Generate piece moves.
  189.         non_pawns = our_pieces & ~self.pawns & from_mask
  190.         print(f"Počet figur kromě pěšců: {bin(non_pawns).count('1')}")
  191.         for from_square in scan_reversed(non_pawns):
  192.             piece_type = self.piece_type_at(from_square)
  193.             print(f"Generuji tahy pro figuru {piece_type} na poli {chess.SQUARE_NAMES[from_square]}")
  194.             if piece_type is None:
  195.                 print(f"WARNING: Neznámá figura na poli {chess.SQUARE_NAMES[from_square]}")
  196.                 continue
  197.             moves = self.attacks_mask(piece_type, from_square, self.occupied) & ~our_pieces & to_mask
  198.             move_count = 0
  199.             for to_square in scan_reversed(moves):
  200.                 move_count += 1
  201.                 yield Move(from_square, to_square)
  202.             print(f"Vygenerováno {move_count} tahů pro tuto figuru")
  203.  
  204.         # Generate castling moves.
  205.         if from_mask & self.kings:
  206.             print("Generuji rošády")
  207.             castling_moves = list(self.generate_castling_moves(from_mask, to_mask))
  208.             print(f"Vygenerováno {len(castling_moves)} rošád")
  209.             yield from castling_moves
  210.  
  211.         # The remaining moves are all pawn moves.
  212.         pawns = self.pawns & self.occupied_co[self.turn] & from_mask
  213.         print(f"Počet pěšců: {bin(pawns).count('1')}")
  214.         if not pawns:
  215.             print("Žádní pěšci k tahu")
  216.             return
  217.  
  218.         # Generate pawn moves.
  219.         print("Generuji tahy pěšců")
  220.         pawn_moves = list(self.generate_pseudo_legal_pawn_moves(pawns, to_mask))
  221.         print(f"Vygenerováno {len(pawn_moves)} tahů pěšců")
  222.         yield from pawn_moves
  223.  
  224.         # Generate pawn captures.
  225.         print("Generuji braní pěšců")
  226.         capturers = pawns
  227.         capture_count = 0
  228.         for from_square in scan_reversed(capturers):
  229.             targets = (
  230.                 chess.BB_PAWN_ATTACKS[self.turn][from_square] &
  231.                 self.occupied_co[not self.turn] & to_mask)
  232.  
  233.             for to_square in scan_reversed(targets):
  234.                 capture_count += 1
  235.                 if chess.square_rank(to_square) in [0, 7]:
  236.                     yield Move(from_square, to_square, chess.QUEEN)
  237.                     yield Move(from_square, to_square, chess.ROOK)
  238.                     yield Move(from_square, to_square, chess.BISHOP)
  239.                     yield Move(from_square, to_square, chess.KNIGHT)
  240.                 else:
  241.                     yield Move(from_square, to_square)
  242.         print(f"Vygenerováno {capture_count} braní pěšců")
  243.  
  244.         print("generate_pseudo_legal_moves končí")
  245.  
  246.     def is_check(self):
  247.         print("is_check")
  248.         king_square = self.king(self.turn)
  249.         if king_square is None:
  250.             return False
  251.  
  252.         if super().is_check():
  253.             return True
  254.  
  255.         opponent_color = not self.turn
  256.         for square, piece in self._custom_piece_map.items():
  257.             if piece.color == opponent_color:
  258.                 if piece.piece_type in [AMAZON, CYRIL, EVA]:
  259.                     if self._is_attacked_by_new_piece(king_square, square, piece.piece_type):
  260.                         return True
  261.  
  262.         return False
  263.  
  264.     def _is_attacked_by_new_piece(self, target_square, attacker_square, piece_type):
  265.         print("_is_attacked_by_new_piece")
  266.         if piece_type == AMAZON:
  267.             return (self.attacks_knight(attacker_square) | self.attacks_bishop(attacker_square) | self.attacks_rook(attacker_square)) & chess.BB_SQUARES[target_square]
  268.         elif piece_type == CYRIL:
  269.             return (self.attacks_knight(attacker_square) | self.attacks_rook(attacker_square)) & chess.BB_SQUARES[target_square]
  270.         elif piece_type == EVA:
  271.             return (self.attacks_queen(attacker_square) | self.attacks_knight(attacker_square)) & chess.BB_SQUARES[target_square]
  272.         return False
  273.  
  274.     def attacks_knight(self, square):
  275.         return self.attacks_mask(chess.KNIGHT, square, self.occupied)
  276.  
  277.     def attacks_bishop(self, square):
  278.         return self.attacks_mask(chess.BISHOP, square, self.occupied)
  279.  
  280.     def attacks_rook(self, square):
  281.         return self.attacks_mask(chess.ROOK, square, self.occupied)
  282.  
  283.     def attacks_queen(self, square):
  284.         return self.attacks_bishop(square) | self.attacks_rook(square)
  285.  
  286.     def piece_type_at(self, square):
  287.         piece = self._custom_piece_map.get(square)
  288.         if piece:
  289.             return piece.piece_type
  290.         return super().piece_type_at(square)
  291.  
  292.     def is_legal(self, move):
  293.         print(f"Kontrola legality tahu: {move}")
  294.         if not super().is_legal(move):
  295.             return False
  296.        
  297.         from_square = move.from_square
  298.         to_square = move.to_square
  299.         piece = self.piece_at(from_square)
  300.        
  301.         if piece is None:
  302.             return False
  303.        
  304.         if piece.piece_type in [AMAZON, CYRIL, EVA]:
  305.             # Pro nové figurky kontrolujeme, zda je cílové pole v dosahu jejich tahů
  306.             if piece.piece_type == AMAZON:
  307.                 legal_moves = (self.attacks_mask(chess.KNIGHT, from_square, self.occupied) |
  308.                                self.attacks_mask(chess.BISHOP, from_square, self.occupied) |
  309.                                self.attacks_mask(chess.ROOK, from_square, self.occupied))
  310.             elif piece.piece_type == CYRIL:
  311.                 legal_moves = (self.attacks_mask(chess.KNIGHT, from_square, self.occupied) |
  312.                                self.attacks_mask(chess.ROOK, from_square, self.occupied))
  313.             elif piece.piece_type == EVA:
  314.                 legal_moves = (self.attacks_mask(chess.KNIGHT, from_square, self.occupied) |
  315.                                self.attacks_mask(chess.QUEEN, from_square, self.occupied))
  316.            
  317.             if not (legal_moves & chess.BB_SQUARES[to_square]):
  318.                 return False
  319.        
  320.         # Kontrola, zda tah nevystavuje vlastního krále šachu
  321.         self.push(move)
  322.         legal = not self.is_check()
  323.         self.pop()
  324.        
  325.         return legal
  326.  
  327.     @property
  328.     def legal_moves(self):
  329.         print("legal_moves")
  330.         return [move for move in self.generate_pseudo_legal_moves() if self.is_legal(move)]
  331.  
  332. @lru_cache(maxsize=None)
  333. def simplify_fen_string(fen):
  334.     print("simplify_fen_string")
  335.     parts = fen.split(' ')
  336.     simplified_fen = ' '.join(parts[:4] + ["0", "1"])
  337.     return simplified_fen
  338.  
  339. def print_board(fen):
  340.     print("print_board")
  341.     board = CustomBoard(fen)
  342.     print(board.to_string())
  343.     print()  # Add an empty line after the board
  344.  
  345. def format_time(seconds):
  346.     print("format_time")
  347.     hours, remainder = divmod(seconds, 3600)
  348.     minutes, seconds = divmod(remainder, 60)
  349.     return f"{int(hours):02d}h {int(minutes):02d}m {int(seconds):02d}s"
  350.  
  351. def analyze_positions(start_fen, min_depth=5):
  352.     print("analyze_positions začíná")
  353.     print("Initializing analysis...")
  354.     POZ = {1: start_fen}
  355.     AR = {simplify_fen_string(start_fen): {'depth': 0, 'value': None}}
  356.     N = 1
  357.  
  358.     start_time = time.time()
  359.     total_time = 0
  360.  
  361.     print("Generování pozic...")
  362.     while True:
  363.         new_positions = False
  364.         for i in range(1, N + 1):
  365.             current_fen = POZ[i]
  366.             board = CustomBoard(current_fen)
  367.             simplified_fen = simplify_fen_string(current_fen)
  368.            
  369.             if AR[simplified_fen]['depth'] == 0:
  370.                 AR[simplified_fen]['depth'] = 1
  371.                 legal_moves = list(board.legal_moves)
  372.                 print(f"Pozice {i}: {simplified_fen}, Počet legálních tahů: {len(legal_moves)}")
  373.                 for move in legal_moves:
  374.                     board.push(move)
  375.                     new_fen = board.fen()
  376.                     simplified_new_fen = simplify_fen_string(new_fen)
  377.                     if simplified_new_fen not in AR:
  378.                         N += 1
  379.                         POZ[N] = new_fen
  380.                         AR[simplified_new_fen] = {'depth': 0, 'value': None}
  381.                         new_positions = True
  382.                     board.pop()
  383.        
  384.         if not new_positions:
  385.             break
  386.        
  387.     print(f"Celkový počet pozic: {N}")
  388.  
  389.     # Inicializace koncových pozic
  390.     terminal_positions = 0
  391.     for i in range(1, N + 1):
  392.         current_fen = POZ[i]
  393.         board = CustomBoard(current_fen)
  394.         simplified_fen = simplify_fen_string(current_fen)
  395.  
  396.         if board.is_checkmate():
  397.             AR[simplified_fen]['value'] = -1000 if board.turn == chess.WHITE else 1000
  398.             AR[simplified_fen]['depth'] = min_depth
  399.             terminal_positions += 1
  400.         elif board.is_stalemate() or board.is_insufficient_material() or board.is_seventyfive_moves() or board.is_fivefold_repetition():
  401.             AR[simplified_fen]['value'] = 0
  402.             AR[simplified_fen]['depth'] = min_depth
  403.             terminal_positions += 1
  404.  
  405.     print(f"Počet koncových pozic: {terminal_positions}")
  406.  
  407.     max_depth = 0
  408.     while max_depth < min_depth:
  409.         max_depth += 1
  410.         level_start_time = time.time()
  411.         print(f"Výpočet v hloubce {max_depth}")
  412.        
  413.         changes = False
  414.         positions_evaluated = 0
  415.         for i in range(1, N + 1):
  416.             current_fen = POZ[i]
  417.             board = CustomBoard(current_fen)
  418.             simplified_fen = simplify_fen_string(current_fen)
  419.             if AR[simplified_fen]['depth'] < max_depth and AR[simplified_fen]['value'] is None:
  420.                 positions_evaluated += 1
  421.                 best_value = -2000 if board.turn == chess.WHITE else 2000
  422.                 all_moves_evaluated = True
  423.                 legal_moves = list(board.legal_moves)
  424.                 print(f"Pozice {i}: {simplified_fen}, Počet legálních tahů: {len(legal_moves)}")
  425.                 for move in legal_moves:
  426.                     board.push(move)
  427.                     next_fen = board.fen()
  428.                     simplified_next_fen = simplify_fen_string(next_fen)
  429.                     if simplified_next_fen not in AR:
  430.                         print(f"Warning: Position not found in AR: {simplified_next_fen}")
  431.                         all_moves_evaluated = False
  432.                         break
  433.                     next_value = AR[simplified_next_fen]['value']
  434.                     if next_value is None:
  435.                         all_moves_evaluated = False
  436.                         break
  437.                     if board.turn == chess.WHITE:
  438.                         best_value = max(best_value, -next_value)
  439.                     else:
  440.                         best_value = min(best_value, -next_value)
  441.                     board.pop()
  442.                
  443.                 if all_moves_evaluated:
  444.                     AR[simplified_fen]['value'] = best_value
  445.                     AR[simplified_fen]['depth'] = max_depth
  446.                     changes = True
  447.  
  448.         level_end_time = time.time()
  449.         level_elapsed_time = level_end_time - level_start_time
  450.         total_time += level_elapsed_time
  451.        
  452.         formatted_total_time = format_time(total_time)
  453.         formatted_level_time = format_time(level_elapsed_time)
  454.        
  455.         print(f"Hloubka {max_depth} dokončena")
  456.         print(f"Pozice vyhodnoceny: {positions_evaluated}")
  457.         print(f"Změny provedeny: {'Ano' if changes else 'Ne'}")
  458.         print(f"Čas: {formatted_total_time} / {formatted_level_time}")
  459.  
  460.     print(f"Analýza dokončena do hloubky {max_depth}")
  461.     print(f"Celkový čas: {format_time(total_time)}")
  462.  
  463.     current_fen = start_fen
  464.     optimal_moves = []
  465.     while True:
  466.         board = CustomBoard(current_fen)
  467.         simplified_fen = simplify_fen_string(current_fen)
  468.         if simplified_fen not in AR:
  469.             print(f"Warning: Position not found in AR: {simplified_fen}")
  470.             break
  471.         current_value = AR[simplified_fen]['value']
  472.        
  473.         if current_value in [-1000, 0, 1000] or current_value is None:
  474.             break
  475.        
  476.         best_move = None
  477.         for move in board.legal_moves:
  478.             board.push(move)
  479.             next_fen = board.fen()
  480.             simplified_next_fen = simplify_fen_string(next_fen)
  481.             if simplified_next_fen not in AR:
  482.                 print(f"Warning: Position not found in AR: {simplified_next_fen}")
  483.                 continue
  484.             next_value = AR[simplified_next_fen]['value']
  485.             if next_value is not None and next_value == -current_value:
  486.                 best_move = move
  487.                 break
  488.             board.pop()
  489.        
  490.         if best_move is None:
  491.             break
  492.        
  493.         optimal_moves.append((current_fen, best_move))
  494.         board.push(best_move)
  495.         current_fen = board.fen()
  496.  
  497.     print("\nOptimální tahy:")
  498.     for fen, move in optimal_moves:
  499.         board = CustomBoard(fen)
  500.         print(f"{board.fullmove_number}. {'Bílý' if board.turn == chess.WHITE else 'Černý'}: {move}")
  501.         print_board(fen)
  502.         print()
  503.  
  504.     print("Konečná pozice:")
  505.     print_board(current_fen)
  506.  
  507.     print("analyze_positions končí")
  508.  
  509. if __name__ == "__main__":
  510.     print("Program začíná")
  511.     start_fen = "1a6/3k4/8/8/8/8/8/6K1 b - - 0 1"
  512.     print("Starting analysis...")
  513.     print("Initial position:")
  514.     print_board(start_fen)
  515.    
  516.     try:
  517.         print("Creating initial board...")
  518.         initial_board = CustomBoard(start_fen)
  519.         print("Initial board created successfully.")
  520.        
  521.         print("Piece map:")
  522.         for square, piece in initial_board._custom_piece_map.items():
  523.             print(f"Square {chess.SQUARE_NAMES[square]}: {initial_board.piece_symbol(piece)}")
  524.        
  525.         print("Generating legal moves for initial position...")
  526.         legal_moves = list(initial_board.legal_moves)
  527.         print(f"Number of legal moves: {len(legal_moves)}")
  528.         for move in legal_moves:
  529.             print(f"Move: {move}")
  530.        
  531.         print("Starting position analysis...")
  532.         analyze_positions(start_fen, min_depth=5)
  533.     except Exception as e:
  534.         print(f"An error occurred: {str(e)}")
  535.         traceback.print_exc()
  536.    
  537.     print("Program končí")
  538.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement