当前位置: 首页 > article >正文

庙算兵棋推演AI开发初探(5-数据处理)

碎碎念:这最近几个月过得那叫一个难受,研究生开题没过、需求评审会在4月和6月开了2次、7月紧接着软件设计评审会,加班干得都是文档的事情,还有开会前的会务和乱七八糟的琐事,我们干的还被规定弄的束手束脚,领导还在“动态的增加任务”,逼得我和领导发了个火……把人当承载任务的工具和垫脚石,不考虑员工的自身发展、创造性和工作时间,我是怎么还能待到现在的。

——2024.7.28以上

开题终于在12月过了,刚过去的这周又全周无休准备出差的东西,今天终于有时间在开题后搞一搞了——2025.1.6

关于庙算的东西网上实在太少,再深入的话我可能先去找找sc2(星际2)的相关内容了。后来我建了个QQ庙算智能体开发研讨群聊——962415181,欢迎同好加入。


0.实现神经网络驱动的智能体的步骤

以下是模仿学习的步骤(分拣、提取、构建神经网络+行为预测

1_filter

从源视数据中筛选出符合标准的对局复盘(replay)

2_extract

从筛选过的复盘数据中提取样本(sample)

切碎的细节特征(features)

——这部分是用numpy把各种特征组合成矩阵,方便神经网络来学习

3_neuralnetwork

设计的单算子行为克隆网络

设计的多算子分层监督学习网络

1.复盘格式版本问题

首先,庙算平台在2024年更新过一次,从python3.8改成3.10了,存储的复盘文件从一个json变成了一帧一个json然后打成压缩包的形式了(更方便找数据了,但我也需要重新写解析的代码了……)

写了一个拆分版本、一个json版本相互转化的代码:


def replay_merge(input_dir, output_file):    
    """
    用于新版1800+个分文件合并回旧文件
    """
    merged_data = []

    for file_name in sorted(os.listdir(input_dir)):
        if file_name.endswith('.json'):
            file_path = os.path.join(input_dir, file_name)
            with open(file_path, 'r', encoding='utf-8') as f:
                data = json.load(f)
                merged_data.append(data)

    with open(output_file, 'w', encoding='utf-8') as f:
        json.dump(merged_data, f, ensure_ascii=False, indent=4)
        # json.dump(merged_data, f, ensure_ascii=False) # 一行json不缩进
    print(f"Created {output_file}")


def replay_split(source_file, output_dir=None):
    """
    用于旧版一行json文件转化为新版1800+个分文件
    """
    with open(source_file, 'r', encoding='gbk') as f:
        content = f.read()

    json_data = json.loads(content)

    #直接输出到源目录
    if output_dir is None:
        # 新建一个文件夹路径
        new_dir = os.path.join(os.path.dirname(source_file), 'replay_split')    
        # 创建新文件夹
        os.makedirs(new_dir, exist_ok=True)
        output_dir = new_dir

    # 检查 json_data 是否是列表
    if isinstance(json_data, list):
        for i, item in enumerate(json_data):
            new_file_name = f"{output_dir}/element_{i}.json"
            with open(new_file_name, 'w', encoding='utf-8') as new_file:
                json.dump(item, new_file, ensure_ascii=False, indent=4)
                # json.dump(item, new_file, ensure_ascii=False) # 一行json不缩进
            print(f"Created {new_file_name}")
    else:
        print("json_data is not a list")

2.复盘json查看方法

在每次的离线推演后,都有数据压缩包在log文件夹中被保存(新版把每一帧的数据当作独立的json数据文件了,也还可以)

为了我的RLHF(RLHF (RL with Human Feedback))来模拟人决策风格的想法,我需要处理实时的人类操作和交互数据。

比如我打开了上面的某条数据,是“一行”的json,我用vscode打开,可以右键“格式化文档”,左侧也可以找一个json扩展来方便使用。【格式化文档后,记得点一下插件上的“刷新”来重新匹配所在行】

格式化后的效果

目前我用qt绘制了兵棋的棋盘(已经搁置,用不上了),通过linux虚拟机运行庙算引擎与我的外部qt进行udp通信来进行交互。

3.复盘json代码解析

这部分一般需要通过json.load(file)函数,然后用['xxx']来获取

4.特征提取(特征化为编码区分,以便输入神经网络)

一般使用 one-hot 编码对特征进行编码,再放到神经网络中

神经网络的输入是有形状要求的

……(这部分回头补上)


最后是附录,从官网文档整理得到,加了与demoAI的agnet里行为枚举的中英对照

吐槽:官网文档里竟然还有括号没补全的小错误!!!我给补上了。

附录:行为指令json解释

"""
兵棋以json串来作为执行命令的载体,action的type来解释实际使用的是什么动作
https://wargame.ia.ac.cn/docs/reference/actions/
"""




actions = \
{
    "机动,Move": {
        "actor": "int 动作发出者席位",
        "obj_id": "算子ID int",
        "type": 1,
        "move_path": "机动路径 list(int)"
    },
    "打击,Shoot": {
        "actor": "int 动作发出者席位",
        "obj_id": "攻击算子ID int",
        "type": 2,
        "target_obj_id": "目标算子ID",
        "weapon_id": "武器ID int"
    },
    "上车,GetOn": {
        "actor": "int 动作发出者席位",
        "obj_id": "乘员算子ID int",
        "type": 3,
        "target_obj_id": "车辆算子ID"
    },
    "下车,GetOff": {
        "actor": "int 动作发出者席位",
        "obj_id": "车辆算子ID int",
        "type": 4,
        "target_obj_id": "乘员算子ID"
    },
    "夺控,Occupy": {
        "actor": "int 动作发出者席位",
        "obj_id": "算子ID int",
        "type": 5
    },
    "切换状态,ChangeState": {
        "actor": "int 动作发出者席位",
        "obj_id": "算子ID int",
        "type": 6,
        "target_state": "目标状态 0-正常机动 1-行军 2-一级冲锋 3-二级冲锋, 4-掩蔽 5-半速"
    },
    "移除压制,RemoveKeep": {
        "actor": "int 动作发出者席位",
        "obj_id": "算子ID int",
        "type": 7
    },
    "间瞄射击,JMPlan": {
        "actor": "int 动作发出者席位",
        "obj_id": "攻击算子ID int",
        "type": 8,
        "jm_pos": "目标位置",
        "weapon_id": "武器ID int"
    },
    "引导射击,GuideShoot": {
        "actor": "int 动作发出者席位",
        "obj_id": "引导算子ID int",
        "type": 9,
        "target_obj_id": "目标算子ID",
        "weapon_id": "武器ID int",
        "guided_obj_id": "射击算子ID"
    },
    "停止机动,StopMove": {
        "actor": "int 动作发出者席位",
        "obj_id": "算子ID int",
        "type": 10
    },
    "武器锁定,WeaponLock": {
        "actor": "int 动作发出者席位",
        "obj_id": "算子ID int",
        "type": 11
    },
    "武器展开,WeaponUnFold": {
        "actor": "int 动作发出者席位",
        "obj_id": "算子ID int",
        "type": 12
    },
    "取消间瞄计划,CancelJMPlan": {
        "actor": "int 动作发出者席位",
        "obj_id": "算子ID int",
        "type": 13
    },
    "配置编组信息(营长专属动作)": {
        "actor": "int 动作发出者席位",
        "type": 100,
        "info": {
            "int 席位数": {
                "operators": [
                    "int 算子id",
                    "int 算子id"
                ]
            }
        }
    },
    "进攻任务(营长专属下达)": {
        "actor": "int 动作发出者席位",
        "type": 207,
        "seat": "命令接收人id",
        "hex": "任务目标位置",
        "start_time": "起始时间",
        "end_time": "结束时间",
        "unit_ids": "执行任务的单位ID列表",
        "route": "执行此任务的途径点列表"
    },
    "防御任务(营长专属下达)": {
        "actor": "int 动作发出者席位",
        "type": 208,
        "seat": "命令接收人id",
        "hex": "任务目标位置",
        "start_time": "起始时间",
        "end_time": "结束时间",
        "unit_ids": "执行任务的单位ID列表",
        "route": "执行此任务的途径点列表"
    },
    "侦察任务(营长专属下达)": {
        "actor": "int 动作发出者席位",
        "type": 209,
        "seat": "命令接收人id",
        "hex": "任务目标位置",
        "radius": "侦察半径",
        "start_time": "起始时间",
        "end_time": "结束时间",
        "unit_ids": "执行任务的单位ID列表",
        "route": "执行此任务的途径点列表"
    },
    "集结任务(营长专属下达)": {
        "actor": "int 动作发出者席位",
        "type": 210,
        "seat": "命令接收人id",
        "hex": "任务目标位置",
        "start_time": "起始时间",
        "end_time": "结束时间",
        "unit_ids": "执行任务的单位ID列表",
        "route": "执行此任务的途径点列表"
    },
    "删除作战任务(营长专属动作)": {
        "actor": "int 动作发出者席位",
        "type": 202,
        "msg_id": "int 要删除的作战指令的id"
    },
    "部署上车": {
        "actor": "int 动作发出者席位",
        "obj_id": "乘员算子ID int",
        "type": 303,
        "target_obj_id": "车辆算子ID"
    },
    "部署下车": {
        "actor": "int 动作发出者席位",
        "obj_id": "车辆算子ID int",
        "type": 304,
        "target_obj_id": "乘员算子ID"
    },
    "解聚,Fork": {
        "actor": "int 动作发出者",
        "obj_id": "算子ID int",
        "type": 14
    },
    "聚合,Union": {
        "actor": "int 动作发出者",
        "obj_id": "算子ID int",
        "target_obj_id": "算子ID int",
        "type": 15
    },
    "部署解聚(赛前部署动作)": {
        "actor": "int 动作发出者",
        "obj_id": "算子ID int",
        "type": 314
    },
    "部署聚合(赛前部署动作)": {
        "actor": "int 动作发出者",
        "obj_id": "算子ID int",
        "target_obj_id": "算子ID int",
        "type": 315
    },
    "改变高程,ChangeAltitude": {
        "actor": "int 动作发出者",
        "obj_id": "算子ID int",
        "type": 16,
        "target_altitude": "目标高程,20超低空,200低空 500高空"
    },
    "部署改变高程(赛前部署动作)": {
        "actor": "int 动作发出者",
        "obj_id": "算子ID int",
        "type": 316,
        "target_altitude": "目标高程,20超低空,200低空 500高空"
    },
    "开启校射雷达,ActivateRadar": {
        "actor": "int 动作发出者",
        "obj_id": "算子ID int",
        "type": 17
    },
    "进入工事,EnterFort": {
        "actor": "int 动作发出者",
        "obj_id": "算子ID int",
        "type": 18,
        "target_obj_id": "工事算子ID"
    },
    "退出工事,ExitFort": {
        "actor": "int 动作发出者",
        "obj_id": "算子ID int",
        "type": 19,
        "target_obj_id": "工事算子ID"
    },
    "布雷,LayMine": {
        "actor": "int 动作发出者",
        "obj_id": "布雷车算子ID int",
        "type": 20,
        "target_pos": "布雷坐标 int"
    },
    "导演击杀算子(导演动作)": {
        "actor": "int",
        "type": 401,
        "target_obj_id": "击杀算子id"
    },
    "导演布雷(导演动作)": {
        "actor": "int",
        "type": 402,
        "target_pos": "布雷坐标"
    },
    "导演建造路障(导演动作)": {
        "actor": "int",
        "type": 403,
        "target_pos": "路障坐标"
    },
    "导演增加算子(导演动作)": {
        "actor": "int",
        "type": 404,
        "sub_type": "算子sub_type",
        "color": "0红, 1蓝",
        "hex": "空降位置"
    },
    "结束部署(赛前部署动作)": {
        "actor": "int,动作发出者",
        "type": 333
    },
    "发送聊天信息": {
        "actor": "int 动作发出者",
        "type": 204,
        "to_all": "0-发给队友,1-发给全部",
        "msg_body": "custoum strings, up to 100 characters in Chinese and 50 words in English"
    },
    "发送辅助渲染信息":
    {
        "actor": "int 动作发出者",
        "type": 205,
        "msg_body": {
        "hexs": ["六角格坐标"], 
        "graphic_type": "渲染模式,见下文",
        "word": "渲染字符",
        "color": "颜色,hex各式,#ffffff",
        "description": "对于此命令的其他描述,字符串"
        }  
    }

}

附录:观测状态json解释

"""
态势信息json格式
整理来源 https://wargame.ia.ac.cn/docs/reference/observations/
"""


observation =\
{
    "actions": # 上一步接收到的动作
    [
        {
            "cur_step": "int, 当前步长",
            "message": "dict, 动作信息",
            "error": {
                "code": "int, 错误码 int",
                "message": "str, 错误原因"
            }
        }
    ],
    "cities":  # 各个夺控点的信息
    [
        {
            "coord": "int, 坐标",
            "value": "int, 分值",
            "flag": "int, 阵营 0-红 1-蓝",
            "name": "str, 名称 str"
        }
    ],
    "communication": # 通信相关信息
    [
        # 进攻任务信息
        {
            "actor": "int 动作发出者席位",
            "type": 207,
            "seat": "命令接收人id",
            "hex": "任务目标位置",
            "start_time": "起始时间",
            "end_time": "结束时间",
            "unit_ids": "执行任务的单位ID列表",
            "route": "执行此任务的途径点列表"
        },
        # 防御任务
        {
            "actor": "int 动作发出者席位",
            "type": 208,
            "seat": "命令接收人id",
            "hex": "任务目标位置",
            "start_time": "起始时间",
            "end_time": "结束时间",
            "unit_ids": "执行任务的单位ID列表",
            "route": "执行此任务的途径点列表"
        },
        # 侦察任务
        {
            "actor": "int 动作发出者席位",
            "type": 209,
            "seat": "命令接收人id",
            "hex": "任务目标位置",
            "radius": "侦察半径",
            "start_time": "起始时间",
            "end_time": "结束时间",
            "unit_ids": "执行任务的单位ID列表",
            "route": "执行此任务的途径点列表"
        },
        # 集结任务
        {
            "actor": "int 动作发出者席位",
            "type": 210,
            "seat": "命令接收人id",
            "hex": "任务目标位置",
            "start_time": "起始时间",
            "end_time": "结束时间",
            "unit_ids": "执行任务的单位ID列表",
            "route": "执行此任务的途径点列表"
        },
        # 聊天信息
        {
            "actor": "int, 本方营长的席位id",
            "type": "int, 204",
            "receive_step": "int, 接收时的步数",
            "to_all": "int, 0-对队友发出,1-对所有人发出",
            "msg_body": "str",
            "msg_id": "int, 此消息的id"
        },
        # 渲染信息
        {
            "actor": "int 动作放出者",
            "type": "int, 205",
            "msg_id": "int, 此消息的id",
            "receive_step": "int, 接收时的步数",
            "to_all": "int, 0-对队友发出,1-对所有人发出",
            "msg_body": {
                "hexs": "list[int], 要渲染的六角格坐标",
                "graphic_type": "str, 渲染类型",
                "word": "str, 渲染字符",
                "color": "str, 颜色",
                "description": "str, 对于此命令的其他描述"
            }
        }
    ],
    "jm_points":  # 间瞄点信息
    [
        {
            "obj_id": "int, 攻击算子ID",
            "weapon_id": "int, 攻击武器ID",
            "pos": "int, 位置",
            "status": "int, 当前状态 0-正在飞行 1-正在爆炸 2-无效",
            "fly_time": "int, 已飞行时间",
            "boom_time": "int, 已爆炸时间"
        }
    ],
    "judge_info":  # 裁决信息
    [
  # 直瞄射击类型
  {
            "att_level": "int, 攻击等级  ",
            "att_obj_blood": "int, 攻击算子血量",
            "att_obj_id": "int, 攻击算子ID",
            "attack_color": "int, 攻击算子颜色",
            "attack_sub_type": "int, 攻击算子类型",
            "cur_step": "int, 当前步长",
            "damage": "int, 最终战损",
            "distance": "int, 距离",
            "ele_diff": "int, 高差等级",
            "ori_damage": "int, 原始战损",
            "random1": "int, 随机数1",
            "random2": "int, 随机数2",
            "random2_rect": "int, 随机数2修正值",
            "rect_damage": "int, 战损修正值",
            "target_color": "int, 目标颜色",
            "target_obj_id": "int, 目标id",
            "target_sub_type": "int, 目标类型",
            "type": "str, 直瞄射击",
            "wp_id": "int, 武器ID int"
        },
  # 间瞄射击类型
  {
            "align_status": "int, 较射类型 0-无较射 1-格内较射 2-目标较射",
            "att_obj_blood": "int, 攻击算子血量",
            "att_obj_id": "int, 攻击算子ID",
            "attack_color": "int, 攻击算子颜色",
            "attack_sub_type": "int, 攻击算子类型",
            "cur_step": "int, 当前步长",
            "damage": "int, 最终战损",
            "distance": "int, 距离",
            "ori_damage": "int, 原始战损",
            "ori_random2": "int, ",
            "offset": "bool, 偏移 bool",
            "random1": "int, 随机数1",
            "random2": "int, 随机数2",
            "random2_rect": "int, 随机数2修正值",
            "rect_damage": "int, 战损修正值",
            "target_color": "int, 目标颜色",
            "target_obj_id": "int, 目标id",
            "target_sub_type": "int, 目标类型",
            "type": "str, 间瞄射击",
            "wp_id": "int, 武器ID"
        },
  # 引导射击类型
    {
            "att_level": "int, 攻击等级",
            "att_obj_blood": "int, 攻击算子血量",
            "att_obj_id": "int, 攻击算子ID",
            "attack_color": "int, 攻击算子颜色",
            "attack_sub_type": "int, 攻击算子类型",
            "cur_step": "int, 当前步长",
            "damage": "int, 最终战损",
            "distance": "int, 距离",
            "ele_diff": "int, 高差等级",
            "guide_obj_id": "int, 引导算子ID",
            "ori_damage": "int, 原始战损",
            "random1": "int, 随机数1",
            "random2": "int, 随机数2",
            "random2_rect": "int, 随机数2修正值",
            "rect_damage": "int, 战损修正值",
            "target_color": "int, 目标颜色",
            "target_obj_id": "int, 目标id",
            "target_sub_type": "int, 目标类型",
            "type": "str, 引导射击",
            "wp_id": "int, 武器ID",
        },
  # 雷场射击类型
  {
            "target_obj_id": "int, 目标算子id",
            "target_color": "int, 目标颜色",
            "target_type": "int, 目标类型",
            "target_armor": "int, 目标护甲",
            "original_damage_random_number": "int, 原始战损随机数",
            "calibration_random_number": "int, 修正随机数",
            "calibration_value": "int, 修正值",
            "final_damage": "int, 最终战损",
            "cur_step": "int, 当前步数",
            "minefield_id": "int, 雷场id",
            "minefield_hex": "int, 雷场位置",
            "minefield_color": "int, 雷场颜色",
            "type": "str, 雷场裁决"
        }
    ],
    "landmarks": # 地标信息,雷场,路障
    {
        "roadblocks": "list[int], 六角格坐标",
        "minefields": [
            {
                "id": "int, 雷场id",
                "name": "str, 雷场",
                "hex": "int, 位置",
                "color": "int, 颜色",
                "creator": "int/None, 雷场创造者,None-想定自带雷场,int-算子创造雷场",
                "roads": [
                    {
                        "id": "int, 通路id",
                        "creator": "int, 通路制造者,int-制造通路的算子id",
                        "direction": "int, 通路方向,0~5,0是正右侧,按逆时针递进",
                        "color": "int, 通路颜色",
                        "hex": "int, 通路位置"
                    }
                ]
            }
        ]
    },
    "operators":  # 算子信息
    [
        # "算子信息":
        {
            "obj_id": "int, 算子ID",
            "color": "int, 算子阵营 0-红 1-蓝",
            "type": "int, 算子类型 1-步兵 2-车辆 3-飞机 4-工事 5-战略支援算子",
            "name": "str, 名称",
            "sub_type": "int, 细分类型 坦克 0/  战车1 / 人员2 / 炮兵3 / 无人战车4 / 无人机5 / 直升机6 / 巡飞弹7 / 运输直升机8 / 侦察型战车9 / 炮兵校射雷达车10 / 人员战斗工事11 / 车辆工事12 / 布雷车13 / 扫雷车14 / 防空高炮15 / 便携防空导弹排16 / 车载防空导弹车17 / 皮卡车18 / 天基侦察算子19 / 人员隐蔽工事20",
            "basic_speed": "int, 基础速度 int km/h",
            "armor": "int, 装甲类型 int 0-无装甲 1-轻型装甲 2-中型装甲 3-重型装甲 4-复合装甲",
            "A1": "int, 是否有行进间射击能力",
            "stack": "int, 是否堆叠",
            "carry_weapon_ids": "list[int] 携带武器ID",
            "remain_bullet_nums": "dict[int, int] 剩余弹药数 dict{弹药类型 int 0-非导弹, 100-重型导弹, 101-中型导弹, 102-小型导弹: 剩余弹药数 int}",
            "remain_bullet_nums_bk": "dict[int, int] 敌对阵营看到的弹药数",
            "guide_ability": "int, 是否有引导射击能力",
            "value": "int, 分值",
            "valid_passenger_types": "list[int], 可承载类型,代表可以装在的乘员sub_type",
            "max_passenger_nums": "dict[int, int], 最大承载数",
            "loading_capacity": "int, 车辆单位最大承载算子车班数",
            "observe_distance": "list[int], 观察距离, 一维列表,代表此算子可以观察到各个sub_type算子的最大观察距离",
            "move_state": "int, 机动状态 0-正常机动 1-行军 2-一级冲锋 3-二级冲锋 4-掩蔽 5-半速",
            "cur_hex": "int, 四位当前坐标",
            "cur_pos": "float, 当前格到下一格的百分比进度",
            "speed": "int, 当前机动速度 格/s >0: 移动中, =0: 暂停或停止 int",
            "move_to_stop_remain_time": "int, 机动转停止剩余时间 >0表示",
            "can_to_move": "int, 是否可机动标志位.只在停止转换过程中用来判断是否可以继续机动.强制停止不能继续机动,正常停止可以继续机动. 0-否 1-是",
            "flag_force_stop": "int, 是否被强制停止机动 0-否 1-是",
            "stop": "int, 是否静止 0-否, 1-是",
            "move_path": "list[int], 计划机动路径, 首个元素代表下一目标格",
            "blood": "int, 当前血量",
            "max_blood": "int, 最大血量",
            "tire": "int, 疲劳等级 0-不疲劳 1-一级疲劳 2-二级疲劳",
            "tire_accumulate_time": "int, 疲劳累积时间",
            "keep": "int, 是否被压制",
            "keep_remain_time": "int, 压制剩余时间",
            "on_board": "int, 是否在车上",
            "car": "int, 所属车辆ID",
            "launcher": "int, 算子下车/发射后,记录所属发射器",
            "passenger_ids": "list[int],乘客列表",
            "launch_ids": "list[int],记录车辆发射单元列表",
            "lose_control": "int, 算子是否失去控制(指无人车失去指挥)",
            "alive_remain_time": "int, 巡飞弹剩余存活时间",
            "get_on_remain_time": "float, 上车剩余时间",
            "get_on_partner_id": "list[int], 车辆算子ID(本算子为上车算子) 或 待上车算子(本算子为车辆算子)",
            "get_off_remain_time": "int,下车剩余时间",
            "get_off_partner_id": "list[int], 车辆算子ID(本算子为待下车算子) 或 车上算子ID(本算子为车辆算子ID)",
            "change_state_remain_time": "int, 切换状态剩余时间",
            "target_state": "int, 状态转换过程中记录目标状态 int 0-正常机动 1-行军 2-一级冲锋 3-二级冲锋 4-掩蔽",
            "weapon_cool_time": "int, 武器剩余冷却时间",
            "weapon_unfold_time": "int, 武器锁定状态表示展开剩余时间, 武器展开状态下表示锁定剩余时间",
            "weapon_unfold_state": "int, 武器状态 0-锁定 1-展开",
            "see_enemy_bop_ids": "list[int], 观察敌方算子列表",
            "owner": "int/str, 当前拥有此算子的玩家席位id",
            "close_combat": "int, 当前算子是否在同格交战中",
            "stationary_count": "int, 算子距离上次改变坐标的时间步长",
            "forking": "int, 是否在解聚",
            "forking_remain_time": "int, 解聚剩余时长",
            "unioning": "int, 算子是否在聚合",
            "unioning_remain_time": "int, 聚合剩余时间",
            "unioning_partner": "int, 聚合对象算子id",
            "unioining_role": "int, 1-聚合发起者,2-聚合被动者",
            "altitude": "int, 算子当前高度",
            "changing_altitude": "int, 是否在改变高度",
            "changing_altitude_remain_time": "int, 改变高度剩余时间",
            "target_altitude": "int, 目标高程",
            "activating_radar": "int, 是否在开启炮兵校射雷达",
            "activating_radar_remain_time": "int, 开启雷达剩余时间",
            "radar_activated": "int, 雷达是否开启",
            "in_fort": "int, 是否在工事中",
            "fort": "int, 工事id",
            "entering_fort": "int, 是否在进入工事",
            "entering_fort_remain_time": "int, 进入工事剩余时间",
            "entering_fort_partner": "list[int], 进入工事动作对象",
            "exiting_fort": "int, 是否在离开工事",
            "exiting_fort_remain_time": "int, 离开工事剩余时间",
            "exiting_fort_partner": "list[int], 离开工事动作对象",
            "fort_passengers": "list[int]工事中的算子",
            "laying_mine": "int, 是否在布雷中",
            "laying_mine_remain_time": "int, 布雷剩余时间",
            "remaining_mine_count": "int, 剩余可布雷场数",
            "laying_mine_target_pos": "int, 当前布雷目标点",
            "observalbe_distance": "int, 此算子可被观察的基础距离"
        },
        # "敌方阵营的不可见信息或部分可见的信息": 
        {
            "remain_bullet_nums": "剩余弹药数 dict{弹药类型 int 0-非导弹, 100-重型导弹, 101-中型导弹, 102-小型导弹: 剩余弹药数 int}",
            "move_to_stop_remain_time": "机动转停止剩余时间 >0表示",
            "can_to_move": "是否可机动标志位.只在停止转换过程中用来判断是否可以继续机动.强制停止不能继续机动,正常停止可以继续机动. 0-否 1-是",
            "move_path": "计划机动路径 [int] 首个元素代表下一目标格,只能观察到敌方机动的下一格,不能观察到全部路径",
            "tire_accumulate_time": "疲劳状态剩余时间 int",
            "keep_remain_time": "压制状态剩余时间 int",
            "launcher": "算子下车/发射后,记录所属发射器 int",
            "passenger_ids": "乘客列表 [int]",
            "launch_ids": "记录车辆发射单元列表 [int]",
            "alive_remain_time": "巡飞弹剩余存活时间",
            "get_on_remain_time": "上车剩余时间 float",
            "get_off_remain_time": "下车剩余时间 float",
            "weapon_unfold_time": "武器锁定状态表示展开剩余时间, 武器展开状态下表示锁定剩余时间 float",
            "see_enemy_bop_ids": "观察敌方算子列表 list(int)",
            "C2": "普通弹药数",
            "C3": "剩余导弹数",
            "target_state": "状态转换过程中记录目标状态 int 0-正常机动 1-行军 2-一级冲锋 3-二级冲锋 4-掩蔽",
        },
        # "敌方间瞄点信息": 
        {
            "obj_id": "攻击算子ID int",
            "weapon_id": "攻击武器ID int",
            "fly_time": "剩余飞行时间 float",
            "boom_time": "剩余爆炸时间 float"
        }
    ],
    "passengers": [], # 乘员信息
    "role_and_grouping_info": # 玩家信息和编组信息
    {
        #席位0
    0: {
            "faction": "int 红为0,蓝为1",
            "role": "int 分队为0,群队为1",
            "operators": "list[int],拥有的算子id",
            "user_id": "int",
            "user_name": "str"
        },
        #席位1
    1: {
            "faction": "int, 红为0,蓝为1",
            "role": "int, 分队为0,群队为1",
            "operators": "list[int], 拥有的算子id",
            "user_id": "int",
            "user_name": "str"
        },
        2: {
            "faction": "int, 红为0,蓝为1",
            "role": "int, 分队为0,群队为1",
            "operators": "list[int], 拥有的算子id",
            "user_id": "int",
            "user_name": "str"
        }
    },
    "scenario_id": 0, # 想定ID
    "scores":  # 分数
    {
        "blue_attack": "int, 蓝方攻击得分",
        "blue_occupy": "int, 蓝方夺控分",
        "blue_remain": "int, 蓝方剩余得分",
        "blue_reamin_max": "int, 蓝方最大剩余得分",
        "blue_total": "int, 蓝方总分",
        "blue_win": "int, 蓝方净胜分",
        "red_attack": "int, 红方战斗得分",
        "red_occupy": "int, 红方夺控分",
        "red_remain": "int, 红方剩余算子分",
        "red_reamin_max": "int, 红方最大剩余得分",
        "red_total": "int, 红方总分",
        "red_win": "int, 红方净胜分"
    },
    "terrain_id": 0, # 地图id
    "time":  # 时间信息
    {
        "cur_step": "int, 当前步长",
        "tick": "int, 每次step会前进多少帧",
        "max_time": "int, 最大帧数",
        "max_step": "int, 最大步数,等于max_time/tick",
        "stage": "int, 当前处于的阶段,0-环境配置阶段,1-部署阶段,2-正常推进阶段"
    },
    "valid_actions": # 当前态势下的可做动作信息
    {
        "算子ID": {
            "1-机动": "null",
            "2-射击": [
                {
                    "target_obj_id": "目标ID int",
                    "weapon_id": "武器ID int",
                    "attack_level": "攻击等级 int"
                }
            ],
            "3-上车": [
                {
                    "target_obj_id": "车辆ID int"
                }
            ],
            "4-下车": [
                {
                    "target_obj_id": "乘客ID int"
                }
            ],
            "5-夺控": "null",
            "6-切换状态": [
                {
                    "target_state": "目标状态 0-正常机动 1-行军 2-一级冲锋 3-二级冲锋 4-掩蔽"
                }
            ],
            "7-移除压制": "null",
            "8-间瞄": [
                {
                    "weapon_id": "武器ID"
                }
            ],
            "9-引导射击": [
                {
                    "guided_obj_id": "被引导算子ID int",
                    "target_obj_id": "目标算子ID",
                    "weapon_id": "武器ID int",
                    "attack_level": "攻击等级 int"
                }
            ],
            "10-停止机动": "null",
            "11-武器锁定": "null",
            "12-武器展开": "null",
            "13-取消间瞄计划": "null",
            "14-解聚": "null",
            "15-聚合": [
                {
                    "target_obj_id": "聚合对象ID int"
                }
            ],
            "16-改变高程": [
                {
                    "target_altitude": "目标高程 int"
                }
            ],
            "17-开启炮兵校射雷达": "null",
            "18-进入工事": [
                {
                    "target_obj_id": "工事ID int"
                }
            ],
            "19-退出工事": [
                {
                    "target_obj_id": "工事ID int"
                }
            ],
            "20-布雷": "null",
        },
        "如果是绿方态势中,会有绿方专属的valid_actions": {
            "401-导演击杀算子": "null",
            "402-导演布雷": "null",
            "403-导演建造路障": "null",
            "404-导演增加算子": "null"
        }
    }
}


http://www.kler.cn/a/555542.html

相关文章:

  • 阿里云子账号管理ECS权限配置全指南
  • Canvas进阶-2、可视化应用
  • C# 中关于补位的写法 PadLeft,PadRight 函数
  • 猎板PCB百科——键盘PCB
  • cesium(vue)一些面试问题(包含Three.js)
  • el-tree选中数据重组成树
  • 【Python爬虫(24)】Redis:Python爬虫的秘密武器
  • AI 编程助手 cursor的系统提示词 prompt
  • 基于大数据的工业废水处理解决方案分享
  • Python迭代器知多少
  • 网络运维学习笔记 014网工初级(HCIA-Datacom与CCNA-EI)ACL访问控制列表
  • DeepSeek大模型下半场:开源、普惠与生态重构的技术革命
  • redis的缓存击穿,雪崩,穿透
  • git空文件夹不能提交问题
  • acm培训 part 7
  • VBA脚本将DeepSeek嵌入Word中教程
  • 【C++】实现一个JSON解析器
  • 【小游戏】C++控制台版本俄罗斯轮盘赌
  • JavaEE-SpringBoot快速入门
  • QT QLabel加载图片等比全屏自适应屏幕大小显示