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

如何从缩进文件生成Unity C#二叉决策树实现NPC数据驱动AI

从嵌套缩进规则生成二叉决策树序列化字符串(Python实现)

我们需要将C4.5算法生成的嵌套缩进式决策规则,转换为可反序列化为Unity C#二叉决策树的字符串格式。要求二叉树左子节点对应负分支(条件不满足),右子节点对应正分支(条件满足),序列化格式用逗号分隔节点,决策节点后紧跟两个分支节点,叶子节点后用#表示空节点。

输入的缩进规则示例:

HP is > 0: 
    SeesEnemy is False: 
        HearEnemy is False:
            Idle
        HearEnemy is True:
            Seeking
    SeesEnemy is True:
        EnemyInRange is False:
            Chasing
        EnemyInRange is True:
            Attacking
HP is <= 0:
    Dead

期望输出的序列化字符串:

HP > 0?,Dead,#,#,SeesEnemy?,HearEnemy?,Idle,#,#,Seeking,#,#,EnemyInRange?,Chasing,#,#,Attacking,#,#

实现思路

  1. 预处理每行数据:拆分每行的缩进层级、条件/动作内容,以及分支方向(False对应左分支,True对应右分支)。
  2. 递归构建序列:
    • 从根节点开始,先处理当前决策节点,然后递归处理左分支(负条件),再递归处理右分支(正条件)。
    • 遇到叶子节点时,输出动作名并追加两个#。
    • 通过缩进层级判断节点的父子关系:缩进层级增加时进入子节点,层级减少时回溯到父节点。

Python 实现代码

def parse_indent_rules(rules_text):
    # 预处理每行,过滤空行,提取缩进层级和内容
    lines = []
    for line in rules_text.strip().split('\n'):
        stripped = line.strip()
        if not stripped:
            continue
        # 计算缩进层级(假设用4空格缩进,可根据实际调整)
        indent_level = (len(line) - len(line.lstrip())) // 4
        lines.append((indent_level, stripped))
    
    # 递归生成序列化序列的辅助函数
    def build_sequence(index, current_level):
        if index >= len(lines):
            return [], index
        
        indent_level, content = lines[index]
        # 当前层级不匹配,返回空序列和当前索引
        if indent_level != current_level:
            return [], index
        
        index += 1
        
        # 判断是决策节点还是叶子节点
        if ':' in content:
            # 决策节点:拆分条件和分支方向(如果有)
            condition_part = content.split(':')[0].strip()
            # 转换条件格式,比如 "HP is > 0" 转为 "HP > 0?"
            if "is " in condition_part:
                condition = condition_part.replace("is ", "") + "?"
            else:
                condition = condition_part + "?"
            
            # 先处理左分支(False分支)
            left_seq, index = build_sequence(index, current_level + 1)
            # 再处理右分支(True分支)
            right_seq, index = build_sequence(index, current_level + 1)
            
            return [condition] + left_seq + right_seq, index
        else:
            # 叶子节点:返回动作名 + 两个#
            return [content, '#', '#'], index
    
    # 从根节点开始构建
    sequence, _ = build_sequence(0, 0)
    return ','.join(sequence)

# 测试输入
rules_input = """HP is > 0: 
    SeesEnemy is False: 
        HearEnemy is False:
            Idle
        HearEnemy is True:
            Seeking
    SeesEnemy is True:
        EnemyInRange is False:
            Chasing
        EnemyInRange is True:
            Attacking
HP is <= 0:
    Dead"""

# 生成序列化字符串
result = parse_indent_rules(rules_input)
print(result)

代码说明

  • 缩进处理:假设缩进为4空格,若实际使用tab缩进,可修改indent_level的计算方式(比如用line.count('\t'))。
  • 条件转换:将规则中的X is Y格式转为X Y?的决策节点格式,匹配目标序列化要求。
  • 递归逻辑:通过层级匹配自动处理父子节点关系,左分支优先处理负条件,右分支随后处理正条件,叶子节点自动追加#占位。

运行代码后,输出结果与期望完全一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 01:20:41