public static void Set_Movablelist() { //移動可能範囲の初期化 movablelist = new List <int[]>(); //移動可能範囲を取得 movablelist = Mapclass.Dfs(BattleVal.mapdata, BattleVal.selectX, BattleVal.selectY, BattleVal.selectedUnit.status.step, BattleVal.selectedUnit.status.jump); }
//敵がターゲットを見つける関数 public static int[] SearchTraget(Unitdata enemy) { //戻り値 int[] target = new int[2]; target[0] = -1; target[1] = -1; //考える範囲 int range = enemy.routin.sightrange; if (range == 0) { range = enemy.status.step * 2; //defaultならばstepの2倍 } //rangeでDfsを呼び出す List <int[]> searchlist = Mapclass.Dfs(BattleVal.mapdata, enemy.x, enemy.y, range, enemy.status.jump); //Dfsは自身を含まないため、加える searchlist.Add(new int[] { enemy.x, enemy.y }); //発見したtargetのリスト HashSet <int[]> targetlist = new HashSet <int[]>(); //searchlistをまわす foreach (int[] coord in searchlist) { //攻撃可能マスを取得 //List<int[]> attacklist = Mapclass.AttackDfs(BattleVal.mapdata, coord[0], coord[1], // CharaAttack.attackrange[enemy.jobid], CharaAttack.AttackMaxRange(enemy.jobid)); List <int[]> attacklist = enemy.attackrange.Attackablelist(BattleVal.mapdata, coord[0], coord[1]); //攻撃範囲を探索 foreach (int[] attackcoord in attacklist) { //そこに誰かいれば if (BattleVal.id2index.ContainsKey( string.Format("{0},{1}", attackcoord[0], attackcoord[1]))) { //それが敵ではないならターゲットに追加 if (BattleVal.id2index[string.Format("{0},{1}", attackcoord[0], attackcoord[1])].team != enemy.team) { targetlist.Add(attackcoord); } } } } //ターゲットがいない場合 if (targetlist.Count == 0) { return(new int[] { enemy.x, enemy.y }); //自身の座標を返却 } //AIタイプに基づいてtargetlistからターゲットを決める //ターゲットループ double maxeval = 0.0; foreach (int[] targetcoord in targetlist) { Unitdata unit = BattleVal.id2index[string.Format("{0},{1}", targetcoord[0], targetcoord[1])]; double evaluation = enemy.routin.EvaluationTarget(enemy, unit); //評価値が最大なら、ターゲットに。 if ((target[0] == -1 && target[1] == -1) || evaluation > maxeval) { maxeval = evaluation; target = targetcoord; } } return(target); }
//攻撃対象に向けて移動する先を決める public static int[] DecideDestination(Unitdata enemy, int[] target) { int[] destination = new int[2]; //命を大事にする傾向で、HPが1/8を切っていたら逃げる if (enemy.hp <= enemy.status.maxhp / 8 && enemy.routin.Cherish_life) { //自身とターゲットにの間の変位ベクトルの反転を求める int[] v = new int[] { enemy.x - target[0], enemy.y - target[1] }; //vのx,yの整数比を求め、疑規格化 for (int i = 2; i <= (int)Mathf.Min(v[0], v[1]);) { if (v[0] % i == 0 && v[1] % i == 0) { v[0] /= i; v[1] /= i; } else { i++; } } target = new int[] { enemy.x + v[0] * enemy.status.step, enemy.y + v[1] * enemy.status.step }; if (target[0] >= Mapclass.mapxnum) { target[0] = Mapclass.mapxnum - 1; } if (target[0] < 0) { target[0] = 0; } if (target[1] >= Mapclass.mapynum) { target[1] = Mapclass.mapynum - 1; } if (target[1] < 0) { target[1] = 0; } } //歩数が十分大きいとして、行動可能範囲を探索 List <int[]> movablelist = Mapclass.Dfs(BattleVal.mapdata, enemy.x, enemy.y, enemy.status.step, enemy.status.jump); //Dfsは自身の位置を含めないため、追加 movablelist.Add(new int[] { enemy.x, enemy.y }); int mindist = -1; //移動可能範囲の中で、ターゲットに攻撃できる位置に向かう //もしくはターゲットに最も近いマンハッタン距離の位置に向かう foreach (int[] a in movablelist) { //攻撃可能マスを取得 //List<int[]> attacklist = Mapclass.AttackDfs(BattleVal.mapdata, coord[0], coord[1], // CharaAttack.attackrange[enemy.jobid], CharaAttack.AttackMaxRange(enemy.jobid)); List <int[]> attacklist = enemy.attackrange.Attackablelist(BattleVal.mapdata, a[0], a[1]); bool brakeflag = false; //攻撃範囲を探索 foreach (int[] attackcoord in attacklist) { //そこにターゲットがいる if (attackcoord[0] == target[0] && attackcoord[1] == target[1]) { destination = a; brakeflag = true; break; } } if (brakeflag) { break; } int tempdist = Mapclass.Calc_Dist(target, a); if (mindist == -1 || tempdist < mindist) { mindist = tempdist; destination = a; } } return(destination); }