// 从多个攻击目标中,挑选一个最优先 public static void FindPriorTarget(Warrior warrior, Warrior[] targets, Action <Warrior> onSelTarget) { if (targets.Length == 0) { onSelTarget(null); return; } else if (targets.Length == 1) { onSelTarget(targets[0]); return; } // 对目标进行评分 var priorityScore = new Dictionary <Warrior, int>(); foreach (var t in targets) { GetTargetPriorityScore(warrior, t, (score) => priorityScore[t] = score); } // 防御最低的目标额外 2 分 Warrior lowestDefenceOne = null; foreach (var t in targets) { if (lowestDefenceOne == null || lowestDefenceOne.GetEstimatedDefence(warrior.AttackingType) > t.GetEstimatedDefence(warrior.AttackingType)) { lowestDefenceOne = t; } } priorityScore[lowestDefenceOne] += 2; // 攻击最低的目标额外 1 分 Warrior lowestAttackOne = null; foreach (var t in targets) { if (lowestAttackOne == null || lowestAttackOne.BasicAttackValue > t.BasicAttackValue) { lowestAttackOne = t; } } priorityScore[lowestAttackOne] += 1; targets.SwiftSort((a, b) => priorityScore[b] - priorityScore[a]); onSelTarget(targets[0]); }
// 寻找最近的队友 public static Warrior FindTheNearestTeammate(Warrior warrior) { Warrior nearestTeammate = null; var map = warrior.Map; warrior.GetPosInMap(out int fx, out int fy); var nearestX = 0; var nearestY = 0; map.ForeachObjs <Warrior>((tx, ty, target) => { if (warrior.Team != target.Team || warrior == target) // 过滤掉敌人和自己 { return; } if (// 选距离最近的 (nearestTeammate == null || MU.ManhattanDist(fx, fy, tx, ty) < MU.ManhattanDist(fx, fy, nearestX, nearestY)) // 距离相同选 HP 高的 || (MU.ManhattanDist(fx, fy, tx, ty) == MU.ManhattanDist(fx, fy, nearestX, nearestY) && nearestTeammate.HP < target.HP) // 距离,HP 相同选防御高的 || (MU.ManhattanDist(fx, fy, tx, ty) == MU.ManhattanDist(fx, fy, nearestX, nearestY) && nearestTeammate.HP == target.HP && nearestTeammate.GetEstimatedDefence() < target.GetEstimatedDefence()) // 距离,HP,防御相同选攻击高的 || (MU.ManhattanDist(fx, fy, tx, ty) == MU.ManhattanDist(fx, fy, nearestX, nearestY) && nearestTeammate.HP == target.HP && nearestTeammate.GetEstimatedDefence() == target.GetEstimatedDefence() && (nearestTeammate.BasicAttackValue < target.BasicAttackValue))) { nearestX = tx; nearestY = ty; nearestTeammate = target; } }); return(nearestTeammate); }
// 寻找血量最少的目标 public static Warrior FindTheWeakestTarget(Warrior warrior) { Warrior weakestTarget = null; var map = warrior.Map; map.ForeachObjs <Warrior>((tx, ty, target) => { if (warrior.Team == target.Team) // 过滤掉队友 { return; } if ((weakestTarget == null || weakestTarget.HP > target.HP) || // 选血量少的 (weakestTarget.HP == target.HP && weakestTarget.ES > target.ES) || // 血量相同选护盾少的 (weakestTarget.HP == target.HP && weakestTarget.ES == target.ES && (weakestTarget.GetEstimatedDefence(warrior.AttackingType) > target.GetEstimatedDefence(warrior.AttackingType)))) // 血量护盾相同选防低的 { weakestTarget = target; } }); return(weakestTarget); }
// 近战攻击者站位逻辑 public static void CheckoutPosition4CloseAttacking(Warrior attacker, Warrior target, Action <int, int> onStandPos) { var standPos2Targets = GetPosListWithTargetReachable(attacker, target); Warrior lowestDefenceOne = null; // 防御最低的目 Warrior lowestAttackOne = null; // 攻击最低的目标 // 对这些位置进行评分 var pos2Score = new Dictionary <KeyValuePair <int, int>, int>(); foreach (var pos in standPos2Targets.Keys) { var x = pos.Key; var y = pos.Value; var score = 0; foreach (var t in standPos2Targets[pos]) { // 无反击能力,2 分 if (t.CanAttackBack(attacker)) { score += 2; } // 能击杀的,3 分 var damage = 0; attacker.Battle.SimulateAttackingDamage(attacker, t, null, null, (d) => damage = d); if (damage >= target.HP + target.ES) { score += 10; } // 保留防御最低的目标 if (lowestDefenceOne == null || lowestDefenceOne.GetEstimatedDefence(attacker.AttackingType) > t.GetEstimatedDefence(attacker.AttackingType)) { lowestDefenceOne = t; } // 保留攻击最低的目标 if (lowestAttackOne == null || lowestAttackOne.BasicAttackValue > t.BasicAttackValue) { lowestAttackOne = t; } } pos2Score[pos] = score; } foreach (var pos in standPos2Targets.Keys) { // 能攻击到防御最低的目标,额外 2 分 if (standPos2Targets[pos].IndexOf(lowestDefenceOne) >= 0) { pos2Score[pos] += 2; } // 能攻击到攻击最低的目标,额外 1 分 if (standPos2Targets[pos].IndexOf(lowestAttackOne) >= 0) { pos2Score[pos] += 1; } } var posArr = standPos2Targets.Keys.ToArray(); posArr.SwiftSort((a, b) => pos2Score[b] - pos2Score[a]); onStandPos(posArr[0].Key, posArr[0].Value); }