Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import chess
- def simplify_fen(fen):
- """Simplifies a FEN string by keeping only the position, turn, castling availability, and en passant target square."""
- return ' '.join(fen.split(' ')[:4])
- def add_descendants_iteratively(A, fen_to_node_id):
- queue = [(1, 0)]
- while queue:
- node_id, depth = queue.pop(0)
- board = chess.Board(A[node_id]['fen'] + " 0 1")
- for move in board.legal_moves:
- if move.promotion:
- move = chess.Move(move.from_square, move.to_square, promotion=chess.QUEEN)
- board.push(move)
- simplified_fen = simplify_fen(board.fen())
- if simplified_fen not in fen_to_node_id:
- new_node_id = len(A) + 1
- A[new_node_id] = {
- 'fen': simplified_fen,
- 'moves_to_mate': None,
- 'parent': node_id,
- 'color': chess.WHITE if simplified_fen.split()[1] == 'w' else chess.BLACK,
- 'result': None,
- 'processed': False,
- 'sequence': [],
- 'children': [],
- 'to_end': None,
- }
- fen_to_node_id[simplified_fen] = new_node_id
- A[node_id]['children'].append(new_node_id)
- queue.append((new_node_id, depth + 1))
- board.pop()
- def initialize_game_tree(initial_fen):
- simplified_fen = simplify_fen(initial_fen)
- A = {1: {'fen': simplified_fen, 'moves_to_mate': None, 'parent': None,
- 'color': chess.WHITE if initial_fen.split()[1] == 'w' else chess.BLACK,
- 'result': None, 'processed': False, 'sequence': [], 'children': [], 'to_end': None}}
- fen_to_node_id = {simplified_fen: 1}
- return A, fen_to_node_id
- def update_game_outcomes(A):
- for key, node in A.items():
- board = chess.Board(node['fen'] + " 0 1")
- if board.is_game_over():
- outcome = board.outcome()
- node['processed'] = True
- if outcome.termination == chess.Termination.CHECKMATE:
- node['result'] = 1 if outcome.winner == chess.WHITE else -1
- node['moves_to_mate'] = 0
- else:
- node['result'] = 0
- node['moves_to_mate'] = None
- node['to_end'] = 0
- def update_parent_preferences(node_id, A):
- node = A[node_id]
- # Return the current values if the node has already been processed
- if node['processed']:
- return node['to_end'], node['moves_to_mate'], node['result']
- best_child_id = None
- # Initialize best_result with an appropriate value based on the color to play
- best_result = float('-inf') if node['color'] else float('inf')
- best_to_end = None
- for child_id in node['children']:
- child_to_end, child_moves_to_mate, child_result = update_parent_preferences(child_id, A)
- # Ensure comparisons are valid by checking for None
- if child_result is None:
- continue # Skip this child because it has no result, indicating it's not a terminal node or not evaluated yet
- # Handle the logic for updating the best choice based on the color to play
- if node['color']: # If it's White's turn to play
- 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))):
- best_child_id = child_id
- best_result = child_result
- best_to_end = child_to_end
- else: # If it's Black's turn to play
- 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))):
- best_child_id = child_id
- best_result = child_result
- best_to_end = child_to_end
- # Update the current node based on the best child node found
- if best_child_id is not None:
- node['sequence'] = [best_child_id]
- node['result'] = best_result
- node['to_end'] = 1 + (best_to_end if best_to_end is not None else 0)
- node['moves_to_mate'] = None if node['result'] == 0 else 1 + (best_to_end if best_to_end is not None else 0)
- else:
- node['to_end'] = None
- node['moves_to_mate'] = None
- node['processed'] = True
- return node['to_end'], node['moves_to_mate'], node['result']
- # Note: This function assumes the presence of an evaluate_board function or similar logic
- # that sets the initial 'result' for leaf nodes where the game is over.
- def print_sequence_from_root(A):
- current_node_id = 1
- while True:
- node = A[current_node_id]
- board = chess.Board(node['fen'] + " 0 1")
- print(f"Node ID: {current_node_id}, Moves to Mate: {node['moves_to_mate']}, Result: {node['result']}")
- print(board, "\n")
- if not node['sequence']:
- break
- current_node_id = node['sequence'][0]
- def main():
- initial_fen = "7Q/8/8/6k1/2K5/8/8/8 w - - 0 1"
- A, fen_to_node_id = initialize_game_tree(initial_fen)
- add_descendants_iteratively(A, fen_to_node_id)
- update_game_outcomes(A)
- update_parent_preferences(1, A)
- print("Final Output:")
- print(A[1],"1*\n")
- print(A[15967],"15967*\n")
- print(A[31639],"31639*\n")
- print(A[31640],"31640\n")
- print(A[31641],"31641\n")
- print(A[3743],"3743*\n")
- print(A[1190],"1190*\n")
- print(A[101],"101*\n")
- print(A[17],"17*\n")
- print(A[70638],"70638*\n")
- print(A[106380],"106380*\n")
- print(A[165316],"165316*\n")
- print_sequence_from_root(A)
- # 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]:
- for key in range(1,1000000):
- if A[key]['to_end'] != None: # and A[key]['to_end'] > 9:
- print(f"{key}:: {A[key]['to_end']} {A[key]}\n{chess.Board(A[key]['fen'])}<\n")
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement