Advertisement
max2201111

good but is 2 but should be 4

Mar 20th, 2024
549
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.38 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:
  46.             # Node has a direct outcome (win, loss, or draw)
  47.             moves_to_mate = 0 if 'moves_to_mate' in node and node['result'] in [-1, 1] else None
  48.             return node['result'], [node_id], moves_to_mate
  49.  
  50.         best_result = None  # Track the best outcome (initially undefined)
  51.         best_path = []  # Best path leading to this outcome
  52.         best_moves_to_mate = float('inf')  # Use infinity as a comparison basis for finding the minimum
  53.  
  54.         for child_id in node['children']:
  55.             child_result, child_path, child_moves_to_mate = recurse(child_id)
  56.  
  57.             # Skip draws or paths not leading to a decisive outcome
  58.             if child_result == 0 or child_moves_to_mate is None:
  59.                 continue
  60.  
  61.             # Identify and select the best outcome for the current player
  62.             if best_result is None or (child_result == -1 and node['color'] == chess.WHITE and child_moves_to_mate < best_moves_to_mate):
  63.                 # For White, a result of -1 (Black win) with fewer moves is worse, so it's avoided unless it's the only outcome
  64.                 best_result, best_path, best_moves_to_mate = child_result, child_path, child_moves_to_mate
  65.             elif child_result == 1 and node['color'] == chess.BLACK and child_moves_to_mate < best_moves_to_mate:
  66.                 # For Black, similar logic applies but reversed
  67.                 best_result, best_path, best_moves_to_mate = child_result, child_path, child_moves_to_mate
  68.  
  69.         # If a winning path was found, update the node
  70.         if best_result in [-1, 1]:
  71.             node['result'] = best_result
  72.             node['moves_to_mate'] = best_moves_to_mate + 1  # Adjust for the current move
  73.         else:
  74.             # No winning path found, consider it a draw or maintain undefined result
  75.             node['result'] = 0 if best_result is None else best_result
  76.             node['moves_to_mate'] = None
  77.  
  78.         return node['result'], [node_id] + best_path, node.get('moves_to_mate')
  79.  
  80.     _, path, _ = recurse(1)  # Starting from the root of the game tree
  81.     return path
  82.  
  83.  
  84.  
  85. def print_path(game_tree, path):
  86.     """Prints the board positions along the path."""
  87.     for node_id in path:
  88.         node = game_tree[node_id]
  89.         board = chess.Board(node['fen'] + " 0 1")
  90.         moves_to_mate = "N/A" if node.get('moves_to_mate') is None else node.get('moves_to_mate')
  91.         print(f"Node ID: {node_id}, Result: {node.get('result', 'N/A')}, Moves to Mate: {moves_to_mate}")
  92.         print(board,node,"<<\n")
  93.         print("---")
  94.  
  95. def main():
  96.     initial_fen = "8/8/8/3k4/8/8/2K2Q2/8 w - - 0 1"  # Example FEN
  97.     initial_fen = "8/8/8/3k4/8/2K5/5q2/8 w - - 0 1"
  98.     initial_fen = "8/8/8/3k4/1K6/8/5q2/8 b - - 0 1"
  99.     initial_fen = "5K2/q7/6k1/8/8/8/8/8 w - - 0 1"
  100.   #  initial_fen = "6K1/q7/6k1/8/8/8/8/8 b - - 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