|
沙发

楼主 |
发表于 2020-9-5 18:56:41
|
只看该作者
find_routes概述
find_routes根据单位所在格子和可用移动力计算出单位的可到达位置。
当在游戏中单击鼠标左键选中一个单位,这时地图上显示该单位可到达位置。find_routes就用于计算这些个位置。下图就是鼠标单击(33,12)处时显示的可到达位置,总计有35个(不包括(32,11)和(32,12)这两个站了敌方单位的格子)。
find_routes计算这些个位置时采用A*搜索算法。既然使用了A*算法则需要明确几个问题:
满足什么样条件的结点才能放入OPEN:如果A点是第一次遇到,只要该点不站敌方单位或有移动力移到该点则可放入;如果A点是已经访问过,则此次展开要能比过去更“优”才能放入。
估值函数:到达A点剩余移动力比到达B点剩余移动力多,则认为到达A点价值更高。
已经展开但没有访问的结点集的变量表示:pq
已访问的结点集:这个没有确切定义,nodes很大部分完成这个功能。
以上图为例叙述搜索过程。
第一次
初始状态:
OPEN: (33,12)
CLOSE:
正访问结点:(33,12)
进入启发式搜索。具体来说就是判断欲访问结点(33,12)周围六个节点能不能展开,及形成该节点状态。
(32,11):站着个敌方单位,不能展开。(图中也变成可移动框,那是接下的show_attack_options加入的)
(32,12):站着个敌方单位,不能展开。
(33,13):能展开,但由于处在(32,12)的ZOC内,剩余移动力0。该点状态:{C(33,13), P(33,12), 0}。
(34,12):能展开。该点状态:{C(34,12), P(33,12), 6}。
(34,11):能展开。该点状态:{C(34,11), P(33,12), 6}。
(33,11):能展开。该点状态:{C(33,11), P(33,12), 6}。
OPEN: (33,13), (34,12), (34,11), (33,11)
对OPEN中结点进行排序,剩余移动力最大的排在前面。
结末状态:
(34,12), (34,11), (33,11), (33,13)
CLOSE: (33,12)
第二次
正访问结点:(34,12)
进入启发式搜索。
(33,12):不能展开。该结点已访问过,而且已访问过的剩余移动力7比到(34,12)都大。
(33,13):不能展开。该结点已访问过,且此次并不比已存在“优”。
(34,13):能展开。该点状态:{C(34,13), P(34,12), 3}。(移动山地花费3点移动力)
(35,13):能展开。该点状态:{C(35,13), P(34,12), 4}。
(35,12):能展开。该点状态:{C(35,12), P(34,12), 5}。
(34,11):不能展开。该结点已访问过,且此次并不比已存在“优”。
结末状态:(OPEN已被排序)
OPEN: (34,11), (33,11), (35,12), (35,13), (34,13), (33,11)
CLOSE:
第三次
第N次也是前面一样流程,在此次详述下for中的四个if判断。
正访问结点:(34,11),它展开出的第一个结点:(33,11),(33,11)已经被访问过。
第一个if:(next_visited && !(n < next)),起点到(34,11)不优于起点到(33,11)。如果到(34,11)要花费移动力不会比到(33,11)少,那可以肯定没必要再寻(34,11)到(33,11)这条路了。
第二个if:(t.movement_left < move_cost || t.turns_left < 0)。t是(33,12)-->(34,11)剩余移动力(注:没到(33,11)),(33,12)单位在(34,11)时已没再有移动力到达(33,11),那么这条路径自然不能成立。
第三个if:(next_visited && !(t < next)):t是(33,12)-->(34,11)-->(33,11),起始经过这条路径到达(33,11)不优于已存的起点到(33,11),那这条路径也不必找了。
第四个if:(next_visited && !(t < next))。这个第三个if是一样判断,但到这时t经过了单位考虑,一旦t位在敌方zoc内,t的剩余移动力归零。以上正是这种情况,(31,11)站着个敌方单位,所以(34,11)到(33,11)后,移动力就归零。——由于个if,!(t < netx)成立,continue。===》在node处依旧保存着curr=(33,11),prev=(33,12), left_movement=0。 |
|