Advertisement
max2201111

quite good moves_to_mate 14 but is 10 otherwise well

Mar 16th, 2024
496
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.09 KB | Science | 0 0
  1. import chess
  2.  
  3. def simplify_fen(fen):
  4.     """Simplifies a FEN string to include only position, turn, castling availability, and en passant target."""
  5.     return ' '.join(fen.split(' ')[:4])
  6.  
  7. def initialize_game_tree(initial_fen):
  8.     """Initializes the game tree with the root node based on the initial FEN."""
  9.     simplified_fen = simplify_fen(initial_fen)
  10.     game_tree = {1: {'fen': simplified_fen, 'parent': None, 'color': chess.WHITE if 'w' in initial_fen else chess.BLACK, 'children': [], 'moves_to_mate': None}}
  11.     fen_to_node_id = {simplified_fen: 1}
  12.     return game_tree, fen_to_node_id
  13.  
  14. def add_descendants_iteratively(game_tree, fen_to_node_id):
  15.     """Expands the game tree by iteratively adding legal move descendants of each game state."""
  16.     queue = [(1, 0)]
  17.     while queue:
  18.         node_id, _ = queue.pop(0)
  19.         board = chess.Board(game_tree[node_id]['fen'] + " 0 1")
  20.         for move in board.legal_moves:
  21.             board.push(move)
  22.             simplified_fen = simplify_fen(board.fen())
  23.             if simplified_fen not in fen_to_node_id:
  24.                 new_node_id = len(game_tree) + 1
  25.                 game_tree[new_node_id] = {'fen': simplified_fen, 'parent': node_id, 'color': chess.WHITE if board.turn else chess.BLACK, 'children': [], 'moves_to_mate': None}
  26.                 fen_to_node_id[simplified_fen] = new_node_id
  27.                 game_tree[node_id]['children'].append(new_node_id)
  28.                 queue.append((new_node_id, 0))
  29.             board.pop()
  30.  
  31. def update_game_outcomes(game_tree):
  32.     """Updates game outcomes focusing only on checkmates."""
  33.     for node_id, node in game_tree.items():
  34.         board = chess.Board(node['fen'] + " 0 1")
  35.         if board.is_checkmate():
  36.             node['result'] = 1 if board.turn == chess.BLACK else -1  # Black's turn but checkmate means White wins, and vice versa
  37.             node['moves_to_mate'] = 0  # Checkmate is immediate, no more moves required.
  38.         elif board.is_game_over():
  39.             node['result'] = 0  # For draws or stalemates, we consider the result as 0 (this will be ignored in propagation)
  40.  
  41.  
  42. def update_parent_preferences(game_tree):
  43.     def recurse(node_id):
  44.         node = game_tree[node_id]
  45.         if 'result' in node:  # Check if the node has a direct outcome
  46.             return node['result'], [node_id], 0 if 'moves_to_mate' in node else None
  47.  
  48.         best_result = 0  # Assume draw as the default outcome
  49.         best_path = []
  50.         best_moves_to_mate = None
  51.  
  52.         for child_id in node['children']:
  53.             child_result, child_path, child_moves_to_mate = recurse(child_id)
  54.  
  55.             if child_result == 0 or child_moves_to_mate is None:  # Skip draws or paths not leading to checkmate
  56.                 continue
  57.  
  58.             # Ensure we have a valid best_moves_to_mate for comparison
  59.             if best_moves_to_mate is None:
  60.                 best_moves_to_mate = child_moves_to_mate
  61.                 best_result, best_path = child_result, child_path
  62.             else:
  63.                 # Compare only if child_moves_to_mate is not None and update accordingly
  64.                 if node['color'] == chess.WHITE and child_result == 1:
  65.                     if child_moves_to_mate < best_moves_to_mate:
  66.                         best_result, best_path, best_moves_to_mate = child_result, child_path, child_moves_to_mate
  67.                 elif node['color'] == chess.BLACK and child_result == -1:
  68.                     if child_moves_to_mate > best_moves_to_mate:
  69.                         best_result, best_path, best_moves_to_mate = child_result, child_path, child_moves_to_mate
  70.  
  71.         if best_moves_to_mate is not None:
  72.             node['result'] = best_result
  73.             node['moves_to_mate'] = 1 + best_moves_to_mate
  74.         else:
  75.             node['result'] = best_result  # could still be 0 if no child paths lead to a win
  76.             node['moves_to_mate'] = None
  77.  
  78.         return node['result'], [node_id] + best_path, node.get('moves_to_mate')
  79.  
  80.     result, path, moves_to_mate = recurse(1)  # Start the recursion from the root node.
  81.     return path
  82.  
  83.  
  84. # Make sure to replace or integrate this function into your main execution logic and re-run your analysis.
  85.  
  86.  
  87.  
  88. def print_path(game_tree, path):
  89.     """Prints the board positions along the path."""
  90.     for node_id in path:
  91.         node = game_tree[node_id]
  92.         board = chess.Board(node['fen'] + " 0 1")
  93.         moves_to_mate = "N/A" if node.get('moves_to_mate') is None else node.get('moves_to_mate')
  94.         print(f"Node ID: {node_id}, Result: {node.get('result', 'N/A')}, Moves to Mate: {moves_to_mate}")
  95.         print(board,node,"<<\n")
  96.         print("---")
  97.  
  98. def main():
  99.     initial_fen = "8/8/8/3k4/8/8/2K2Q2/8 w - - 0 1"  # Example FEN
  100.     initial_fen = "8/8/8/3k4/8/2K5/5q2/8 w - - 0 1"
  101.  
  102.     game_tree, fen_to_node_id = initialize_game_tree(initial_fen)
  103.     add_descendants_iteratively(game_tree, fen_to_node_id)
  104.     update_game_outcomes(game_tree)
  105.     path = update_parent_preferences(game_tree)
  106.     print(game_tree[1])
  107.     print("Path to the outcome:")
  108.     print_path(game_tree, path)
  109.  
  110. if __name__ == "__main__":
  111.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement