Advertisement
max2201111

very well done FEN BW MTM == 5 OK

Mar 6th, 2024
723
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.84 KB | Science | 0 0
  1. import chess
  2.  
  3. def simplify_fen(fen):
  4.     """Simplifies a FEN string to only include position, turn, castling availability, and en passant target."""
  5.     return ' '.join(fen.split(' ')[:4])
  6.  
  7. def add_descendants_iteratively(game_tree, fen_to_node_id):
  8.     """Expands the game tree by iteratively adding legal move descendants of each game state."""
  9.     queue = [(1, 0)]
  10.     while queue:
  11.         node_id, _ = queue.pop(0)
  12.         board = chess.Board(game_tree[node_id]['fen'] + " 0 1")
  13.         for move in board.legal_moves:
  14.             move = chess.Move(move.from_square, move.to_square, promotion=chess.QUEEN) if move.promotion else move
  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(game_tree) + 1
  19.                 game_tree[new_node_id] = {
  20.                     'fen': simplified_fen,
  21.                     'moves_to_mate': None,
  22.                     'parent': node_id,
  23.                     'color': chess.WHITE if board.turn 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.                 game_tree[node_id]['children'].append(new_node_id)
  32.                 queue.append((new_node_id, 0))
  33.             board.pop()
  34.  
  35. def initialize_game_tree(initial_fen):
  36.     """Initializes the game tree with the root node based on the initial FEN."""
  37.     simplified_fen = simplify_fen(initial_fen)
  38.     game_tree = {1: {'fen': simplified_fen, 'moves_to_mate': None, 'parent': None,
  39.                      'color': chess.WHITE if 'w' in initial_fen else chess.BLACK,
  40.                      'result': None, 'processed': False, 'sequence': [], 'children': [], 'to_end': None}}
  41.     fen_to_node_id = {simplified_fen: 1}
  42.     return game_tree, fen_to_node_id
  43.  
  44. def update_game_outcomes(game_tree):
  45.     """Updates game outcomes based on the current board state for each node."""
  46.     for node in game_tree.values():
  47.         board = chess.Board(node['fen'] + " 0 1")
  48.         if board.is_game_over():
  49.             outcome = board.outcome()
  50.             node['processed'] = True
  51.             node['result'] = 1 if outcome and outcome.winner == chess.WHITE else -1 if outcome and outcome.winner == chess.BLACK else 0
  52.             node['moves_to_mate'] = 0 if node['result'] != 0 else None
  53.             node['to_end'] = 0
  54.  
  55.  
  56. def update_parent_preferences(node_id, game_tree, stronger):
  57.     node = game_tree[node_id]
  58.     if node['processed']:
  59.         return node['to_end'], node['moves_to_mate'], node['result']
  60.  
  61.     is_maximizing = node['color'] == stronger
  62.     desired_result = 1 if stronger == chess.WHITE else -1
  63.    
  64.     # Initialize best_path_length based on whether we are maximizing or minimizing
  65.     best_path_length = None  # We start with None to be agnostic about the direction of comparison initially
  66.     best_child_id = None
  67.     best_result = None
  68.  
  69.     for child_id in node['children']:
  70.         _, child_moves_to_mate, child_result = update_parent_preferences(child_id, game_tree, stronger)
  71.         if child_moves_to_mate is None:
  72.             continue
  73.  
  74.         # Decide when to update based on maximizing or minimizing player logic
  75.         if is_maximizing:
  76.             # For maximizing, we look for a smaller number than currently best (shortest path to checkmate)
  77.             if best_path_length is None or (child_moves_to_mate < best_path_length):
  78.                 best_path_length, best_child_id, best_result = child_moves_to_mate, child_id, child_result
  79.         else:
  80.             # For minimizing, we look for a larger number than currently best (longest path to avoid checkmate)
  81.             if best_path_length is None or (child_moves_to_mate > best_path_length):
  82.                 best_path_length, best_child_id, best_result = child_moves_to_mate, child_id, child_result
  83.  
  84.     if best_child_id is not None:
  85.         node['sequence'] = [best_child_id]
  86.         node['result'] = best_result
  87.         node['to_end'] = best_path_length + 1 if best_path_length is not None else None
  88.         node['moves_to_mate'] = best_path_length + 1 if best_result == desired_result else None
  89.     else:
  90.         node['to_end'], node['moves_to_mate'], node['sequence'] = None, None, []
  91.  
  92.     node['processed'] = True
  93.     return node['to_end'], node['moves_to_mate'], node['result']
  94.  
  95.  
  96. def print_sequence_from_root(A):
  97.     current_node_id = 1
  98.     A[1]['sequence'] = [29]
  99.  #   A[1]['sequence'] = [13]
  100.  
  101.     while True:
  102.         node = A[current_node_id]
  103.         board = chess.Board(node['fen'] + " 0 1")
  104.         print(f"Node ID: {current_node_id}, Moves to Mate: {node['moves_to_mate']}, Result: {node['result']}")
  105.         print(board, "\n", node['fen'],"\n\n")
  106.        
  107.         if not node['sequence']:
  108.             break
  109.         current_node_id = node['sequence'][0]
  110.  
  111.  
  112. def main():
  113.     initial_fen = "7Q/8/8/6k1/2K5/8/8/8 w - - 0 1"
  114.     initial_fen = "8/5k1Q/3K4/8/8/8/8/8 b - - 0 1"
  115.     initial_fen = "8/2k5/8/5Q2/8/8/2K5/8 w - - 0 1"
  116.  
  117.     initial_fen = "2k5/8/5Q2/3K4/8/8/8/8 w - - 0 1"
  118.  
  119.     game_tree, fen_to_node_id = initialize_game_tree(initial_fen)
  120.     add_descendants_iteratively(game_tree, fen_to_node_id)
  121.     update_game_outcomes(game_tree)
  122.     update_parent_preferences(1, game_tree, chess.WHITE)
  123.     print("Final Output:")
  124.     print(game_tree[1])
  125.     print(game_tree[2])
  126.     print(game_tree[3])
  127.     print(game_tree[4])
  128.  
  129.     print_sequence_from_root(game_tree)
  130.    
  131.     for key in range(1,20000):
  132.         if game_tree[key]['to_end'] != None: # and A[key]['to_end'] > 9:
  133.             print(f"{key}:: {game_tree[key]['to_end']} {game_tree[key]}\n{chess.Board(game_tree[key]['fen'])}<\n")
  134.  
  135.    
  136.    
  137. if __name__ == "__main__":
  138.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement