输出回放数据,在显示中发现一动不动,发现stage字段一直是1部署阶段……
解决方法:
- 代码层面需要有type=333的行为告诉引擎部署完毕。
- pip卸载重装兵棋引擎
这个我每次关机后都得重新来一遍,很讨厌(经过试验,此举会重新复制一个.engine_config到python包的目录)
- 删除某文件
确定发出了部署命令还没效果,看看你的用户根目录(root或者用户名)下有没有.engine_config这个隐藏文件,你现在是什么用户就在什么下。
可以用这个命令行在自己的用户目录找……但是找到的删了就跑不起来了
find . -type f -name ".engine_config"
把每个算子看成独立的对象,在执行的时候就是遍历(还有筛选出有效行为的”行为掩码“),所以在进行强化学习的时候也可以进行分别的训练。
这就是demo中常用的模式:遍历有效行为空间->过滤出可控算子的可控动作->定制化输出
(说实话我一开始很不习惯这样,我熟悉的是魔兽编辑器的trigger触发器那一套)
def step(self, observation: dict):
# 智能体本轮要输出的所有行为
total_actions = []
# 获取可控算子列表
self.controllable_ops = observation["role_and_grouping_info"][self.seat]["operators"]
# 生成动作
for obj_id, valid_actions in observation["valid_actions"].items(): # valid_actions is also a dict
# 过滤是自己可控的算子
if obj_id not in self.controllable_ops:
continue
# 遍历所有可用行为(这一帧的有效行为空间)
for (action_type) in self.priority:
if action_type not in valid_actions:
continue
# 开始安排 兵力obj_id 的 行为类型action_type 的 行为action
action = .......
if action:
total_actions.append(action)
# 一个单位每轮只能有一个行为
break
return total_actions
还有一点就是作为指令的json常常不是简单的值,比如移动还需要给出路径经过点的列表,这个就需要自己写函数进行适配了。
放出my_gen_move()函数的实现涉及的函数,移动的算是自由度最大的一个行为了,一个"move_path": route就需要前面几个函数的参与。
def get_move_type(self, bop):
"""Get appropriate move type for a bop."""
bop_type = bop["type"]
if bop_type == BopType.Vehicle:
if bop["move_state"] == MoveType.March:
move_type = MoveType.March
else:
move_type = MoveType.Maneuver
elif bop_type == BopType.Infantry:
move_type = MoveType.Walk
else:
move_type = MoveType.Fly
return move_type
def gen_move_route(self, begin, end, mode):
if (
not self.is_valid(begin)
or not self.is_valid(end)
or not 0 <= mode < len(self.cost)
or begin == end
):
return []
frontier = [(0, random.random(), begin)]
cost_so_far = {begin: 0}
came_from = {begin: None}
def a_star_search():
while frontier:
_, _, cur = heapq.heappop(frontier)
if cur == end:
break
row, col = divmod(cur, 100)
for neigh, edge_cost in self.cost[mode][row][col].items():
neigh_cost = cost_so_far[cur] + edge_cost
if neigh not in cost_so_far or neigh_cost < cost_so_far[neigh]:
cost_so_far[neigh] = neigh_cost
came_from[neigh] = cur
heuristic = self.get_distance(neigh, end)
heapq.heappush(frontier, (neigh_cost + heuristic, random.random(), neigh))
def reconstruct_path():
path = []
if end in came_from:
cur = end
while cur != begin:
path.append(cur)
cur = came_from[cur]
path.reverse()
return path
a_star_search()
return reconstruct_path()
def my_gen_move(self, obj_id, destination):
bop = self.get_bop(obj_id)
if bop and bop["cur_hex"] != destination:
move_type = self.get_move_type(bop)
route = self.map.gen_move_route(bop["cur_hex"], destination, move_type)
return {
"actor": self.seat,
"obj_id": obj_id,
"type": ActionType.Move,
"move_path": route,
}
解释demo的意思
行为类型-“函数指针(一种比喻)”-随机选择可用行为类型直接执行到函数上面。
def my_gen_move(self, obj_id, destination):
...
return action
def setup(self, setup_info):
self.priority = {
...
ActionType.Move: self.gen_move,
...
} # 通过优先级来决定执行顺序的类型,这是demo的安排
def step(self, observation: dict):
...
# 从有效动作类型中,直接priority获取"函数指针",也就是某个函数
gen_action = self.priority[action_type]
# 通过"函数指针self.priority"获取函数接口,传入形参
action = gen_action(obj_id, valid_actions[action_type])
...
这里列举上传AI的基于的环境,按照这个来应该没问题
平台安装需求
python==3.10
numpy==1.26.2
pandas==1.5.3
ray==2.9.0
scikit-learn==1.0.2
scipy==1.10.1
tensorflow==2.11.0
torch==2.0.1
功能函数:获取某位置的某方向邻格
def get_move_destination(cur_pos, move_dir):
"""
按方向取邻接格子,正右是1,顺时针旋转
"""
move_destination = 0
cur_row, cur_col = cur_pos // 100, cur_pos % 100
next_row = cur_row
next_col = cur_col
# 判断当前行是奇数行还是偶数行
if cur_row % 2 == 1: # odd
flag_Odd_Even = 1
else: # even
flag_Odd_Even = 0
# 六边形格子
if move_dir == 1: # 正右
next_col += 1
elif move_dir == 2: # 右下(奇数双加)
if flag_Odd_Even == 1:
next_col += 1
next_row += 1
elif move_dir == 3: # 左下(偶数行加行减列)
if flag_Odd_Even == 0:
next_col -= 1
next_row += 1
elif move_dir == 4: # 正左
next_col -= 1
elif move_dir == 5: # 左上(偶数行双减)
if flag_Odd_Even == 0:
next_col -= 1
next_row -= 1
elif move_dir == 6: # 右上(奇数行加列)
if flag_Odd_Even == 1:
next_col += 1
next_row -= 1
move_destination = 100 * next_row + next_col
return move_destination
for i in range(1, 7):
print(f"Direction {i}: {get_move_destination(203, i)}")
……