Advertisement
max2201111

ok az na vystup

Jul 1st, 2025
304
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.75 KB | Science | 0 0
  1. import chess
  2. import math
  3. import time
  4. from copy import deepcopy
  5.  
  6. def knight_moves():
  7.     return [(2, 1), (1, 2), (-1, 2), (-2, 1),
  8.             (-2, -1), (-1, -2), (1, -2), (2, -1)]
  9.  
  10. def rook_moves():
  11.     return [(i, 0) for i in range(-7, 8) if i != 0] + [(0, i) for i in range(-7, 8) if i != 0]
  12.  
  13. def bishop_moves():
  14.     return [(i, i) for i in range(-7, 8) if i != 0] + [(i, -i) for i in range(-7, 8) if i != 0]
  15.  
  16. def queen_moves():
  17.     return rook_moves() + bishop_moves()
  18.  
  19. def amazon_moves():
  20.     return queen_moves() + knight_moves()
  21.  
  22. def cyril_moves():
  23.     return rook_moves() + knight_moves()
  24.  
  25. def eve_moves():
  26.     return bishop_moves() + knight_moves()
  27.  
  28. def print_board(board):
  29.     """Vypíše šachovnici v čitelném ASCII formátu"""
  30.     print("  a b c d e f g h")
  31.     for i in range(8):
  32.         print(f"{8-i} ", end="")
  33.         for j in range(8):
  34.             print(f"{board[i][j]} ", end="")
  35.         print(f"{8-i}")
  36.     print("  a b c d e f g h")
  37.     print()
  38.  
  39. def generate_moves(board, piece, row, col):
  40.     size = 8
  41.     moves = []
  42.     directions = []
  43.     if piece == 'A':
  44.         directions = amazon_moves()
  45.     elif piece == 'C':
  46.         directions = cyril_moves()
  47.     elif piece == 'E':
  48.         directions = eve_moves()
  49.     for dx, dy in directions:
  50.         x, y = row + dx, col + dy
  51.         if 0 <= x < size and 0 <= y < size and board[x][y] == '.':
  52.             moves.append((x, y))
  53.     return moves
  54.  
  55. def board_to_fen(board):
  56.     fen = []
  57.     for row in board:
  58.         empty = 0
  59.         fen_row = ""
  60.         for cell in row:
  61.             if cell == '.':
  62.                 empty += 1
  63.             else:
  64.                 if empty > 0:
  65.                     fen_row += str(empty)
  66.                     empty = 0
  67.                 fen_row += cell
  68.         if empty > 0:
  69.             fen_row += str(empty)
  70.         fen.append(fen_row)
  71.     return "/".join(fen) + " w - - 0 1"
  72.  
  73. def create_successors(index, state, all_states, seen_fens):
  74.     board = state['board']
  75.     new_states = []
  76.     new_outputs = []  # sem si připravíme řetězce pro výpis na jednom řádku
  77.  
  78.     for i in range(8):
  79.         for j in range(8):
  80.             piece = board[i][j]
  81.             if piece in ['A', 'C', 'E']:
  82.                 moves = generate_moves(board, piece, i, j)
  83.                 for x, y in moves:
  84.                     new_board = deepcopy(board)
  85.                     new_board[x][y] = piece
  86.                     new_board[i][j] = '.'
  87.                     fen = board_to_fen(new_board)
  88.                     if fen not in seen_fens:
  89.                         seen_fens.add(fen)
  90.                         new_state = {
  91.                             'radek': len(all_states),
  92.                             'N': [],
  93.                             'P': [index],
  94.                             'FEN': fen,
  95.                             'board': new_board,
  96.                             'to_mate': None,
  97.                             'to_end': None
  98.                         }
  99.                         all_states.append(new_state)
  100.                         new_states.append(new_state['radek'])
  101.                         new_outputs.append(f"{new_state['radek']}({state['radek']})")
  102.                     else:
  103.                         for s in all_states:
  104.                             if s['FEN'] == fen:
  105.                                 if index not in s['P']:
  106.                                     s['P'].append(index)
  107.                                 new_states.append(s['radek'])
  108.  
  109.     # Výpis na jediném řádku
  110.     if new_outputs:
  111.         max_radek = max(new_states)
  112.         print(f"\rdepth={state['radek']} max={max_radek} : {' '.join(new_outputs)}", end='', flush=True)
  113.  
  114.     return new_states
  115.  
  116. def create_initial_board():
  117.     board = [['.' for _ in range(8)] for _ in range(8)]
  118.     board[0][0] = 'A'
  119.    # board[7][7] = 'C'
  120.    # board[3][3] = 'E'
  121.     board[4][4] = 'K'  # White king
  122.     board[0][7] = 'k'  # Black king
  123.     return board
  124.  
  125. def main():
  126.     board = create_initial_board()
  127.     start_fen = board_to_fen(board)
  128.     L = []
  129.     seen_fens = set()
  130.     seen_fens.add(start_fen)
  131.     L.append({
  132.         'radek': 0,
  133.         'N': [],
  134.         'P': [],
  135.         'FEN': start_fen,
  136.         'board': board,
  137.         'to_mate': None,
  138.         'to_end': None
  139.     })
  140.  
  141.     print("Počáteční pozice:")
  142.     print_board(board)
  143.     print(f"Start FEN: {start_fen}")
  144.     print("Generuji následníky...")
  145.    
  146.     i = 0
  147.     while i < len(L):
  148.         L[i]['N'] = create_successors(i, L[i], L, seen_fens)
  149.         i += 1
  150.     print(f"\nVygenerováno {len(L)} stavů.")
  151.  
  152.     print("Hledám koncové stavy...")
  153.     end_states_found = 0
  154.     for state in L:
  155.         fen = state['FEN']
  156.         try:
  157.             board = chess.Board(fen)
  158.             if board.is_checkmate():
  159.                 state['to_mate'] = 0
  160.                 state['to_end'] = 0
  161.                 end_states_found += 1
  162.                 print(f"Mat nalezen ve stavu L[{state['radek']}]")
  163.             elif board.is_stalemate() or board.is_insufficient_material() or board.is_seventyfive_moves():
  164.                 state['to_mate'] = math.inf
  165.                 state['to_end'] = 0
  166.                 end_states_found += 1
  167.         except Exception as e:
  168.             print(f"Neplatný FEN: {fen} -> {e}")
  169.             # Neplatný FEN neoznačujeme jako mat
  170.             continue
  171.    
  172.     print(f"Nalezeno {end_states_found} koncových stavů.")
  173.  
  174.     print("Propaguji hodnoty...")
  175.     start_time = time.time()
  176.     round_num = 0
  177.     max_rounds = 1000  # Ochrana proti nekonečné smyčce
  178.    
  179.     while any(s['to_end'] is None for s in L) and round_num < max_rounds:
  180.         round_num += 1
  181.         changed = False
  182.        
  183.         for state in L:
  184.             if state['to_end'] is None and state['N']:  # Jen pokud má následníky
  185.                 # Získej hodnoty následníků
  186.                 succ_mate_vals = []
  187.                 succ_end_vals = []
  188.                
  189.                 for succ_idx in state['N']:
  190.                     succ = L[succ_idx]
  191.                     if succ['to_mate'] is not None:
  192.                         succ_mate_vals.append(succ['to_mate'])
  193.                     if succ['to_end'] is not None:
  194.                         succ_end_vals.append(succ['to_end'])
  195.                
  196.                 # Propaguj to_mate (hledáme minimum - chceme najít nejkratší cestu k matu)
  197.                 if succ_mate_vals:
  198.                     new_mate_val = 1 + min(succ_mate_vals)
  199.                     if state['to_mate'] != new_mate_val:
  200.                         state['to_mate'] = new_mate_val
  201.                         changed = True
  202.                
  203.                 # Propaguj to_end
  204.                 if succ_end_vals:
  205.                     new_end_val = 1 + min(succ_end_vals)
  206.                     if state['to_end'] != new_end_val:
  207.                         state['to_end'] = new_end_val
  208.                         changed = True
  209.        
  210.         elapsed = int(time.time() - start_time)
  211.         hh, rem = divmod(elapsed, 3600)
  212.         mm, ss = divmod(rem, 60)
  213.         states_with_mate = sum(1 for s in L if s['to_mate'] is not None)
  214.         print(f"Průchod {round_num}: čas {hh:02d}h{mm:02d}m{ss:02d}s, změněno: {changed}, stavů s to_mate: {states_with_mate}/{len(L)}")
  215.        
  216.         if not changed:
  217.             print("Žádné další změny - ukončuji propagaci")
  218.             break
  219.    
  220.     # Zkontroluj výsledek pro L[0]
  221.     print(f"\nVýsledky pro počáteční stav L[0]:")
  222.     print(f"to_mate: {L[0]['to_mate']}")
  223.     print(f"to_end: {L[0]['to_end']}")
  224.     print(f"Počet následníků: {len(L[0]['N'])}")
  225.  
  226.     print("\n--- Hledání cesty k matu ---")
  227.    
  228.     def find_path_to_mate():
  229.         """Najde optimální cestu od L[0] k matu pomocí alternování min/max"""
  230.         path = []
  231.         current_index = 0
  232.         move_number = 0
  233.        
  234.         while True:
  235.             current_state = L[current_index]
  236.             path.append(current_index)
  237.            
  238.             print(f"\nTah {move_number}: L[{current_index}]")
  239.             print(f"to_mate: {current_state['to_mate']}, to_end: {current_state['to_end']}")
  240.             print_board(current_state['board'])
  241.            
  242.             # Kontrola, zda jsme dosáhli matu
  243.             if current_state['to_mate'] == 0:
  244.                 print("Mat dosažen!")
  245.                 break
  246.                
  247.             # Najdi následníky
  248.             successors = current_state['N']
  249.             if not successors:
  250.                 print("Žádní následníci - konec hry")
  251.                 break
  252.                
  253.             # Alternování min/max podle parity tahu
  254.             if move_number % 2 == 0:  # Sudý tah - hledáme minimum (bílý hraje optimálně)
  255.                 best_successor = None
  256.                 best_value = float('inf')
  257.                 for succ_idx in successors:
  258.                     succ_state = L[succ_idx]
  259.                     if succ_state['to_mate'] is not None and succ_state['to_mate'] < best_value:
  260.                         best_value = succ_state['to_mate']
  261.                         best_successor = succ_idx
  262.                 print(f"Bílý hledá minimum -> vybírá L[{best_successor}] s to_mate={best_value}")
  263.             else:  # Lichý tah - hledáme maximum (černý brání)
  264.                 best_successor = None
  265.                 best_value = -1
  266.                 for succ_idx in successors:
  267.                     succ_state = L[succ_idx]
  268.                     if succ_state['to_mate'] is not None and succ_state['to_mate'] > best_value:
  269.                         best_value = succ_state['to_mate']
  270.                         best_successor = succ_idx
  271.                 print(f"Černý hledá maximum -> vybírá L[{best_successor}] s to_mate={best_value}")
  272.            
  273.             if best_successor is None:
  274.                 print("Nelze najít další tah")
  275.                 break
  276.                
  277.             current_index = best_successor
  278.             move_number += 1
  279.            
  280.             # Ochrana proti nekonečné smyčce
  281.             if move_number > 50:
  282.                 print("Příliš mnoho tahů - přerušeno")
  283.                 break
  284.        
  285.         return path
  286.    
  287.     # Spusť hledání cesty
  288.     if L[0]['to_mate'] is not None and L[0]['to_mate'] != math.inf:
  289.         print(f"L[0] má to_mate = {L[0]['to_mate']}, hledám cestu k matu...")
  290.         path = find_path_to_mate()
  291.         print(f"\nCelá cesta: {' -> '.join(map(str, path))}")
  292.     else:
  293.         print(f"L[0] nemá cestu k matu (to_mate = {L[0]['to_mate']})")
  294.    
  295.     print("\n--- Výstup ---")
  296.     if len(L) > 0:
  297.         print(f"L[0] board:")
  298.         print_board(L[0]['board'])
  299.         print(f"L[0] = {L[0]}")
  300.     else:
  301.         print(f"List L má {len(L)} stavů. Poslední stav:")
  302.         print_board(L[-1]['board'])
  303.         print(f"{L[-1]}")
  304.  
  305. if __name__ == "__main__":
  306.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement