我正在使用 ChatGPT4 为下面所述的问题创建国际象棋代码, 但大多数情况下,我没有获得任何超出“深度 0 到深度 19”的搜索位置数量的结果。问题绝对是内存方面可以管理的。简短的描述是这样的:我的 ASCII 板上有很少的几块,D=3,4 或 5。我想写一个代码 它将所有可到达的位置放入字典中,称之为 A。现在我想为 A 中的每个键分配一个(小)自然数,0 表示黑色或白色的将死,以及第二个参数父级,所以我应该结束像这样的东西:[initial_fen,None,None]。 这里第一个 None 表示移动次数尚未确定。 第二个 None 意味着initial_fen 字符串的父项不存在(并且在其余的计算中不会存在,这是一个独特的例外,A 中的所有其他键都将有一个父项)然后,向上一点,我想为 A 中的所有键分配 1,这样有问题的玩家对具有标签的其他玩家有一个唯一的合法移动,即第二个条目,等于 0。然后,继续向上,我想应用 any() 和 all() 递归到所有其他位置的逻辑,最终产生initial_fen 的标签,以及 导致将死或平局的路径,理论上对双方来说都是尽可能最佳的。有人能发现其中的错误吗?
import chess
def simplify_fen(fen):
parts = fen.split(' ')
return ' '.join(parts[:4])
def evaluate_position(board):
if board.is_checkmate():
return 1 if board.turn else -1 # 1 for White win, -1 for Black win
elif board.is_stalemate() or board.is_insufficient_material():
return 0 # Draw
return None # Game not ended
def assign_labels_and_parents(reachable_positions, board, depth):
for fen in reachable_positions:
board.set_fen(fen)
result = evaluate_position(board)
if result is not None:
reachable_positions[fen]['label'] = result
elif depth > 0:
child_positions = generate_reachable_positions(board, depth - 1)
if board.turn: # White's turn, use 'any' logic
reachable_positions[fen]['label'] = any(
child_positions[child_fen]['label'] == 1 for child_fen in child_positions)
else: # Black's turn, use 'all' logic
reachable_positions[fen]['label'] = all(
child_positions[child_fen]['label'] == -1 for child_fen in child_positions)
def generate_reachable_positions(board, depth):
reachable_positions = {}
for move in board.legal_moves:
board.push(move)
fen = board.fen()
reachable_positions[fen] = {'label': None, 'parent': board.fen() if board.move_stack else None}
board.pop()
assign_labels_and_parents(reachable_positions, board, depth)
return reachable_positions
def main():
initial_fen = "startpos" # Replace with your specific starting position
initial_fen = "8/8/8/8/8/7Q/3K4/k7 w - - 0 1"
board = chess.Board(fen=initial_fen)
depth = 5 # Modify as needed
reachable_positions = generate_reachable_positions(board, depth)
# Display the results
for fen, data in reachable_positions.items():
print(fen, data)
if __name__ == "__main__":
main()
但是我明白了
7Q/8/8/8/8/8/3K4/k7 b - - 1 1 {'label': False, 'parent': '7Q/8/8/8/8/8/3K4/k7 b - - 1 1'}
2Q5/8/8/8/8/8/3K4/k7 b - - 1 1 {'label': False, 'parent': '2Q5/8/8/8/8/8/3K4/k7 b - - 1 1'}
8/7Q/8/8/8/8/3K4/k7 b - - 1 1 {'label': False, 'parent': '8/7Q/8/8/8/8/3K4/k7 b - - 1 1'}
8/3Q4/8/8/8/8/3K4/k7 b - - 1 1 {'label': False, 'parent': '8/3Q4/8/8/8/8/3K4/k7 b - - 1 1'}
8/8/7Q/8/8/8/3K4/k7 b - - 1 1 {'label': False, 'parent': '8/8/7Q/8/8/8/3K4/k7 b - - 1 1'}
8/8/4Q3/8/8/8/3K4/k7 b - - 1 1 {'label': False, 'parent': '8/8/4Q3/8/8/8/3K4/k7 b - - 1 1'}
8/8/8/7Q/8/8/3K4/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/7Q/8/8/3K4/k7 b - - 1 1'}
8/8/8/5Q2/8/8/3K4/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/5Q2/8/8/3K4/k7 b - - 1 1'}
8/8/8/8/7Q/8/3K4/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/8/7Q/8/3K4/k7 b - - 1 1'}
8/8/8/8/6Q1/8/3K4/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/8/6Q1/8/3K4/k7 b - - 1 1'}
8/8/8/8/8/6Q1/3K4/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/6Q1/3K4/k7 b - - 1 1'}
8/8/8/8/8/5Q2/3K4/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/5Q2/3K4/k7 b - - 1 1'}
8/8/8/8/8/4Q3/3K4/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/4Q3/3K4/k7 b - - 1 1'}
8/8/8/8/8/3Q4/3K4/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/3Q4/3K4/k7 b - - 1 1'}
8/8/8/8/8/2Q5/3K4/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/2Q5/3K4/k7 b - - 1 1'}
8/8/8/8/8/1Q6/3K4/k7 b - - 1 1 {'label': 0, 'parent': '8/8/8/8/8/1Q6/3K4/k7 b - - 1 1'}
8/8/8/8/8/Q7/3K4/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/Q7/3K4/k7 b - - 1 1'}
8/8/8/8/8/8/3K3Q/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/8/3K3Q/k7 b - - 1 1'}
8/8/8/8/8/8/3K2Q1/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/8/3K2Q1/k7 b - - 1 1'}
8/8/8/8/8/8/3K4/k6Q b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/8/3K4/k6Q b - - 1 1'}
8/8/8/8/8/8/3K4/k4Q2 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/8/3K4/k4Q2 b - - 1 1'}
8/8/8/8/8/4K2Q/8/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/4K2Q/8/k7 b - - 1 1'}
8/8/8/8/8/3K3Q/8/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/3K3Q/8/k7 b - - 1 1'}
8/8/8/8/8/2K4Q/8/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/2K4Q/8/k7 b - - 1 1'}
8/8/8/8/8/7Q/4K3/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/7Q/4K3/k7 b - - 1 1'}
8/8/8/8/8/7Q/2K5/k7 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/7Q/2K5/k7 b - - 1 1'}
8/8/8/8/8/7Q/8/k3K3 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/7Q/8/k3K3 b - - 1 1'}
8/8/8/8/8/7Q/8/k2K4 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/7Q/8/k2K4 b - - 1 1'}
8/8/8/8/8/7Q/8/k1K5 b - - 1 1 {'label': False, 'parent': '8/8/8/8/8/7Q/8/k1K5 b - - 1 1'}
好的,但这只是部分答案,因为我不使用或不认识该编程语言,而且我无法确定我的语法是否正确,更不用说测试它了。这些改变可能会纠正一些错误:
def generate_reachable_positions(board, depth):
reachable_positions = {}
parent = board.fen()
for move in board.legal_moves:
board.push(move)
fen = board.fen()
reachable_positions[fen] = {'label': None, 'parent': parent if board.move_stack else None}
board.pop()
assign_labels_and_parents(reachable_positions, board, depth)
return reachable_positions
在进行每次移动之前保存父节点的 FEN 表示应该会导致表自一致。
这应该会导致父节点在其每个子节点中正确显示。然后你需要看看它如何执行黑棋(它应该更喜欢延迟交配时间最长的动作)。
我强烈建议您对棋子受阻的仓位进行一些手动测试,并且出于测试目的,非常很少有合法的动作。在解决更广泛的问题之前,您需要能够在心里检查它是否正常工作。您还需要验证它至少可以正常运行 3 或 4 层,然后才值得让它运行完成。即使对于 3^N 或 4^N 的情况,手动计算移动树也会在第 3 层达到 27 或 64 个终端节点。对于高于 ~5 的分支因子,手动检查功能是很困难的。
最终我认为您会希望该表由位置的快速散列索引,并且每个父级仅存储获胜或最大延迟损失移动(从终端节点返回)并可能移动到获胜/失败/平局。对于更困难的问题,您当前的数据结构将太大且缓慢。