You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无第三方库实现国际象棋对局树结构及分支识别咨询

构建国际象棋多局对局树结构的实现方案

一、核心类的正确设计

先明确Node和Branch的职责边界,避免逻辑混淆:

  • Node:代表对局中的一个状态节点,存储回合数和当前执棋方,同时维护所有从该节点出发的分支选项。
  • Branch:代表从某个节点出发的一步具体走法,存储走法字符串(比如e4、Nf3),并指向该走法后的下一个Node。

代码示例:

class Node:
    def __init__(self, turn_number, player):
        self.turn_number = turn_number  # 根节点设为0,代表开局前状态
        self.player = player  # 用'W'代表白方,'B'代表黑方
        self.branches = []  # 存储当前节点的所有分支(Branch对象)

class Branch:
    def __init__(self, move, next_node):
        self.move = move  # 具体走法,如"e4"
        self.next_node = next_node  # 该走法对应的下一个Node

二、树的构建与节点/分支添加逻辑

构建树的核心是复用已有路径,仅在差异点创建新分支,流程如下:

  1. 初始化根节点:回合数0,执棋方设为None
  2. 遍历每一局的走法序列,逐个处理每一步走法:
    • 从当前节点(初始为根节点)开始
    • 检查当前节点的branches中是否存在对应走法的Branch
    • 若存在:直接跳转到该Branch的next_node,继续处理下一步
    • 若不存在:创建新的Node(回合数+1,执棋方切换),创建新的Branch绑定走法和新Node,将Branch加入当前节点的branches列表,再跳转到新Node

实现代码(添加单局/多局对局)

def add_game_to_tree(root_node, game_moves):
    current_node = root_node
    current_player = 'W'  # 国际象棋默认白方先走
    for idx, move in enumerate(game_moves):
        # 检查当前节点是否已有该走法的分支
        existing_branch = next((b for b in current_node.branches if b.move == move), None)
        if existing_branch:
            # 复用已有路径
            current_node = existing_branch.next_node
        else:
            # 创建新节点:回合数为idx+1,执棋方切换
            next_turn = idx + 1
            next_player = 'B' if current_player == 'W' else 'W'
            new_node = Node(next_turn, next_player)
            new_branch = Branch(move, new_node)
            current_node.branches.append(new_branch)
            current_node = new_node
        # 切换下一轮执棋方
        current_player = 'B' if current_player == 'W' else 'W'

# 示例:添加两局对局
root = Node(0, None)
# 第一局:e4 e5 Nf3 Nc6
game1 = ["e4", "e5", "Nf3", "Nc6"]
# 第二局:e4 c5 Nf3 Nc6(第二步产生分支)
game2 = ["e4", "c5", "Nf3", "Nc6"]
add_game_to_tree(root, game1)
add_game_to_tree(root, game2)

三、识别对局分支点

分支点的本质是存在多个可选走法的Node,有两种识别方式:

  1. 遍历树结构,找出所有len(node.branches) > 1的Node,这些节点就是分支点(从这里开始出现了不同走法)
  2. 在添加对局的过程中实时检测:当处理某一步走法时,当前节点没有对应分支,说明当前节点是一个新的分支点(因为已有其他对局从该节点走了不同的路)

分支点检测代码

def find_branch_points(root_node):
    branch_points = []
    stack = [root_node]
    while stack:
        node = stack.pop()
        if len(node.branches) > 1:
            branch_points.append({
                "turn_number": node.turn_number,
                "player": node.player,
                "available_moves": [b.move for b in node.branches]
            })
        # 遍历所有子节点
        for branch in node.branches:
            stack.append(branch.next_node)
    return branch_points

# 检测示例中的分支点
points = find_branch_points(root)
for p in points:
    print(f"分支点:回合{p['turn_number']},执棋方{p['player']},可选走法:{p['available_moves']}")

输出结果会显示回合1、执棋方B的节点是分支点,可选走法为e5和c5,符合两局对局的差异点。

四、树的遍历与展示

可以用递归或迭代方式遍历树,展示所有对局路径:

def print_tree(node, path=""):
    if node.turn_number == 0:
        print("开局")
    else:
        print(f"回合{node.turn_number} {node.player}: {path}")
    for branch in node.branches:
        new_path = path + " " + branch.move if path else branch.move
        print_tree(branch.next_node, new_path)

# 打印整个树
print_tree(root)

内容的提问来源于stack exchange,提问作者marfin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 19:02:36