Advertisement
max2201111

very good optimal but 9 instead of 11

Mar 3rd, 2024
1,278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.03 KB | Science | 0 0
  1. import chess
  2.  
  3. def simplify_fen(fen):
  4.     """Simplifies a FEN string by keeping only the position, turn, castling availability, and en passant target square."""
  5.     return ' '.join(fen.split(' ')[:4])
  6.  
  7. def add_descendants_iteratively(A, fen_to_node_id):
  8.     queue = [(1, 0)]
  9.     while queue:
  10.         node_id, depth = queue.pop(0)
  11.         board = chess.Board(A[node_id]['fen'] + " 0 1")
  12.         for move in board.legal_moves:
  13.             if move.promotion:
  14.                 move = chess.Move(move.from_square, move.to_square, promotion=chess.QUEEN)
  15.             board.push(move)
  16.             simplified_fen = simplify_fen(board.fen())
  17.             if simplified_fen not in fen_to_node_id:
  18.                 new_node_id = len(A) + 1
  19.                 A[new_node_id] = {
  20.                     'fen': simplified_fen,
  21.                     'moves_to_mate': None,
  22.                     'parent': node_id,
  23.                     'color': chess.WHITE if simplified_fen.split()[1] == 'w' else chess.BLACK,
  24.                     'result': None,
  25.                     'processed': False,
  26.                     'sequence': [],
  27.                     'children': [],
  28.                     'to_end': None,
  29.                 }
  30.                 fen_to_node_id[simplified_fen] = new_node_id
  31.                 A[node_id]['children'].append(new_node_id)
  32.                 queue.append((new_node_id, depth + 1))
  33.             board.pop()
  34.  
  35. def initialize_game_tree(initial_fen):
  36.     simplified_fen = simplify_fen(initial_fen)
  37.     A = {1: {'fen': simplified_fen, 'moves_to_mate': None, 'parent': None,
  38.              'color': chess.WHITE if initial_fen.split()[1] == 'w' else chess.BLACK,
  39.              'result': None, 'processed': False, 'sequence': [], 'children': [], 'to_end': None}}
  40.     fen_to_node_id = {simplified_fen: 1}
  41.     return A, fen_to_node_id
  42.  
  43. def update_game_outcomes(A):
  44.     for key, node in A.items():
  45.         board = chess.Board(node['fen'] + " 0 1")
  46.         if board.is_game_over():
  47.             outcome = board.outcome()
  48.             node['processed'] = True
  49.             if outcome.termination == chess.Termination.CHECKMATE:
  50.                 node['result'] = 1 if outcome.winner == chess.WHITE else -1
  51.                 node['moves_to_mate'] = 0
  52.             else:
  53.                 node['result'] = 0
  54.                 node['moves_to_mate'] = None
  55.             node['to_end'] = 0
  56.  
  57.  
  58. def update_parent_preferences(node_id, A):
  59.     node = A[node_id]
  60.     # Return the current values if the node has already been processed
  61.     if node['processed']:
  62.         return node['to_end'], node['moves_to_mate'], node['result']
  63.  
  64.     best_child_id = None
  65.     # Initialize best_result with an appropriate value based on the color to play
  66.     best_result = float('-inf') if node['color'] else float('inf')
  67.     best_to_end = None
  68.  
  69.     for child_id in node['children']:
  70.         child_to_end, child_moves_to_mate, child_result = update_parent_preferences(child_id, A)
  71.        
  72.         # Ensure comparisons are valid by checking for None
  73.         if child_result is None:
  74.             continue  # Skip this child because it has no result, indicating it's not a terminal node or not evaluated yet
  75.  
  76.         # Handle the logic for updating the best choice based on the color to play
  77.         if node['color']:  # If it's White's turn to play
  78.             if child_result > best_result or (child_result == best_result and (best_to_end is None or (child_to_end is not None and child_to_end < best_to_end))):
  79.                 best_child_id = child_id
  80.                 best_result = child_result
  81.                 best_to_end = child_to_end
  82.         else:  # If it's Black's turn to play
  83.             if child_result < best_result or (child_result == best_result and (best_to_end is None or (child_to_end is not None and child_to_end > best_to_end))):
  84.                 best_child_id = child_id
  85.                 best_result = child_result
  86.                 best_to_end = child_to_end
  87.  
  88.     # Update the current node based on the best child node found
  89.     if best_child_id is not None:
  90.         node['sequence'] = [best_child_id]
  91.         node['result'] = best_result
  92.         node['to_end'] = 1 + (best_to_end if best_to_end is not None else 0)
  93.         node['moves_to_mate'] = None if node['result'] == 0 else 1 + (best_to_end if best_to_end is not None else 0)
  94.     else:
  95.         node['to_end'] = None
  96.         node['moves_to_mate'] = None
  97.  
  98.     node['processed'] = True
  99.     return node['to_end'], node['moves_to_mate'], node['result']
  100.  
  101.  
  102. # Note: This function assumes the presence of an evaluate_board function or similar logic
  103. # that sets the initial 'result' for leaf nodes where the game is over.
  104.  
  105.  
  106.  
  107.  
  108. def print_sequence_from_root(A):
  109.     current_node_id = 1
  110.     while True:
  111.         node = A[current_node_id]
  112.         board = chess.Board(node['fen'] + " 0 1")
  113.         print(f"Node ID: {current_node_id}, Moves to Mate: {node['moves_to_mate']}, Result: {node['result']}")
  114.         print(board, "\n")
  115.        
  116.         if not node['sequence']:
  117.             break
  118.         current_node_id = node['sequence'][0]
  119.  
  120. def main():
  121.     initial_fen = "7Q/8/8/6k1/2K5/8/8/8 w - - 0 1"
  122.     A, fen_to_node_id = initialize_game_tree(initial_fen)
  123.     add_descendants_iteratively(A, fen_to_node_id)
  124.     update_game_outcomes(A)
  125.     update_parent_preferences(1, A)
  126.     print("Final Output:")
  127.     print(A[1],"1*\n")
  128.     print(A[15967],"15967*\n")
  129.     print(A[31639],"31639*\n")
  130.     print(A[31640],"31640\n")
  131.     print(A[31641],"31641\n")
  132.     print(A[3743],"3743*\n")
  133.     print(A[1190],"1190*\n")
  134.     print(A[101],"101*\n")
  135.     print(A[17],"17*\n")
  136.     print(A[70638],"70638*\n")
  137.     print(A[106380],"106380*\n")
  138.     print(A[165316],"165316*\n")
  139.    
  140.     print_sequence_from_root(A)
  141.  
  142. #    for key in [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]:
  143.     for key in range(1,1000000):
  144.         if A[key]['to_end'] != None: # and A[key]['to_end'] > 9:
  145.             print(f"{key}:: {A[key]['to_end']} {A[key]}\n{chess.Board(A[key]['fen'])}<\n")
  146.  
  147.        
  148. if __name__ == "__main__":
  149.     main()
  150.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement