|
沙发

楼主 |
发表于 2020-9-5 19:09:19
|
只看该作者
如何形成路径集(2.2)(代码概述)
一、analyze_targets- void ai_default::analyze_targets(std::vector<attack_analysis>& res)
复制代码 analyze_targets分析出所有攻击路径,res存放这个分析结果。它的执行逻辑
1.1:清空相关缓存
缓存包括us缓存(unit_stats_cache)、城内部队缓存(reside_cache)。- unit_stats_cache().clear();
- for (std::map<unit*, std::pair<map_location, unit*>* >::iterator itor = reside_cache_.begin(); itor != reside_cache_.end(); ++ itor) {
- delete itor->second;
- }
- reside_cache_.clear();
复制代码 1.2:生成本AI势力中依然能实施攻击单位的可移动到信息(脚印信息、端到端信息)- ......
- calculate_possible_moves2(unit_locs, possible_moves2, srcdst2, dstsrc2, false, false, &get_avoid());
- ......
复制代码 1.3:枚举地图上所有敌对单位,针对每个单位分析可攻击路径- for (unit_map::const_iterator j = units_begin(); j != units_.end(); ++j) {
- const map_location& candidate_loc = j->get_location();
- if (current_team().is_enemy(j->second.side()) {
- // 此单位是本AI势力敌对单位
- attack_analysis analysis;
- analysis.target = candidate_loc;
- ......
- do_attack_analysis(candidate_loc, ..., res, analysis);
- }
- }
复制代码 二、do_attack_analysis- void aspect_attacks::do_attack_analysis(const map_location& loc, const move_map& srcdst, const move_map& dstsrc, const move_map& fullmove_srcdst, const move_map& fullmove_dstsrc, const move_map& enemy_srcdst, const move_map& enemy_dstsrc, const map_location* tiles, bool* used_locations, std::vector<map_location>& units, std::vector<attack_analysis>& result, attack_analysis& cur_analysis) const
复制代码 do_attack_analysis,分析出本阵营单位在某个敌对单位上所有可能的攻击路径。注:这是函数是个递归函数,不考虑递归时,它的每一次执行或在原有路径上新加一切拍形成新的路径,或产生第一节拍形成的新的路径。
A:为什么要有cur_analysis参数?
Q:有些攻击路径不只一个节拍,让此次分析基于它形成多节拍路径。不考虑递归调用,一次do_attack_analysis只是形成一个节拍。例如,给的cur_analysis是空的,那么此次do_attack_anlysis形成是单节拍路径,如果是N节拍,那么此次将形成N+1节拍路径。
注:对路径来说,多一个节拍就意味着又是一条新的路径,因此不考虑递归调用下,一次do_attack_analysis也是形成了一个新路径。
函数主要逻辑- for (size_t i = 0; i != units.size(); ++i) {
- const map_location current_unit = units[i];
- unit_map::iterator unit_itor = units_find(current_unit);
- ......
- int best_rating = 0;
- int cur_position = -1;
- // 以下for循环是为了找出current_unit去攻击loc时,在loc邻靠6个格子中,站哪个格子上时能达到最大攻击输出。
- for (int j = 0; j != 6 ; ++j) {
- if (used_locations[j]) {
- continue;
- }
- // 计算单位是否有缓慢、背刺、地形等输入量度算出初级优益度:rating
- rating = ....
- if (cur_position >= 0 && rating < best_rating) {
- continue;
- }
- // 计算出current_unit在j格子处最优值
- cur_position = j;
- best_rating = rating;
- }
- if (cur_postion != -1) {
- // cur_postion != -1, 表示存在个值得考虑的攻击输出
- // 这是为再次运行do_attack_analysis做准备。下次运行时已方单位必须少考虑当前这个单位
- units.erase(units.begin() + i);
- // 形成一个攻击路径拍子
- cur_analysis.movements.push_pack(std::pair<map_location, map_location>(current_unit, tiles[cur_position]));
- cur_analysis.analyze(......);
- // 形成了一条攻击路径,把这路径汇入路径集
- result.push_back(cur_analysis);
- // 这是为再次运行do_attack_analysis做准备。下次运行时loc旁边的这个cur_postion位置当被占位了,即再有单位要考虑攻击时不能移动到这里
- used_locations[cur_position] = true;
- // 再次执行do_attack_analysis,对loc格子进行在当前基础上再深入一层搜索攻击路径
- do_attack_analysis(loc, ..., titles, used_locations, units, result, cur_analysis);
- // 复原回该层的现场
- used_locations[cur_positions] = false;
- cur_analysis.movements.pop_back();
- units.insert(units.begin() + i, current_unit);
- }
- }
复制代码 |
|