using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Cute; namespace Wizard; public class BestInPlayMoveAI : IBattleSimulationAI { private EnemyAI AI; private InplayMovePatternFilter _patternFilter; private AIRuleBaseBattleSimulator _ruleBaseSimulator; private SimulationResult BestRecord; private SimulationAdditionalActionInfoSet _simAdditionalOptions; public AIVirtualField Cr_MaxField => BestRecord.BestResultField; public float Cr_MaxFieldValue => BestRecord.MaxFieldValue; public float Cr_MaxFieldValueAtSelfTurnEnd => BestRecord.MaxFieldValueAtSelfTurnEnd; public AIVirtualActionInfo Cr_FirstActionInfo { get; private set; } public List Cr_MaxActionInfoSequence => BestRecord.ActionSequence; public int Cr_minimumActionLengthOnWinPlan => BestRecord.MinActionLengthOfLethal; public BestInPlayMoveAI(EnemyAI ai) { AI = ai; _patternFilter = new InplayMovePatternFilter(); } public IEnumerator _CrSimulate(AIVirtualField originalField, bool doesUseEvo, bool checkTimeOverLogic, PlayPtnWithToken[] bestPlayPtnsWithToken = null, SimulationAdditionalActionInfoSet additionalActions = null) { AI.IsInVirutalSimulation = true; _ruleBaseSimulator = new AIRuleBaseBattleSimulator(AI, bestPlayPtnsWithToken, canChangeToTimeOverLogic: false); BestRecord = new SimulationResult(); _simAdditionalOptions = additionalActions; ParallelJob job = ParallelJob.Dispatch(delegate { try { RunSimulation(originalField, doesUseEvo); } catch (Exception) { } }); while (!job.isDone) { yield return null; if (checkTimeOverLogic && AI.IsRunWeakLogic) { AI.IsInVirutalSimulation = false; yield break; } } if (Cr_MaxField == null) { AI.IsInVirutalSimulation = false; yield break; } if (Cr_MaxActionInfoSequence.Count > 0) { Cr_FirstActionInfo = BattleSequencer.GetFirstActionInfo(Cr_MaxActionInfoSequence, Cr_MaxField, Cr_MaxField.BestPlayPtn); } AI.IsInVirutalSimulation = false; } private void RunSimulation(AIVirtualField originalField, bool doesUseEvo) { AIVirtualField originalField2 = new AIVirtualField(originalField); List enemyFollowers = GetEnemyFollowers(originalField2); RunAllBreakPattern(originalField2, enemyFollowers, doesUseEvo); } private void RunAllBreakPattern(AIVirtualField originalField, List enemyFollowers, bool doesUseEvo) { RunOnePattern(doesUseEvo, new List(), originalField, enemyFollowers); List list = new List(); int num = enemyFollowers.Count; while (num > 0 && !AI.IsBattleEnd && !AI.IsRunWeakLogic) { int[] patternGroup = AISimulationUtility.GetPatternGroup(num); if (patternGroup != null) { for (int i = 0; i < patternGroup.Length; i++) { if (AI.IsBattleEnd) { break; } if (AI.IsRunWeakLogic) { break; } List enemyTargets = AISimulationUtility.GetEnemyTargets(originalField.EnemyInplayCards, enemyFollowers, patternGroup[i], originalField.BestPlayPtn); ulong item = AISimulationUtility.CalculateTargetSequenceHash(enemyTargets.ToArray(), originalField); if (!list.Contains(item)) { _patternFilter.CheckBreakPatternCondition(originalField, enemyTargets); AIOneMoreLastwordUtility.SortEnemyTargetByBreakBonus(originalField, enemyTargets); RunOnePattern(doesUseEvo, enemyTargets, originalField, enemyFollowers); list.Add(item); if (_patternFilter.IsBestBreakPattern) { return; } } } } num--; } } private void RunOnePattern(bool doesUseEvo, List enemyTargets, AIVirtualField originalField, List enemyFollowers) { if (!AISimulationUtility.IsValidEnemyTargetIndexes(originalField.EnemyInplayCards, enemyTargets)) { return; } int num = (doesUseEvo ? originalField.AllyInplayCards.Count : 0); for (int i = -1; i < num; i++) { if (AISimulationUtility.IsValuableEvoIndex(i, originalField)) { MostValuableAttackPattern(originalField, BestRecord, i, enemyTargets); } } } private void MostValuableAttackPattern(AIVirtualField originalField, SimulationResult bestRecord, int evoIndex, List enemyTargets) { List attackerSequencePermLists = AIMathematicsLibrary.EnumeratePermutations(GetAllyInplayIndexLIst(originalField)).ToList(); AIVirtualField dontUseHandAllRemovalFieldSub = null; if (originalField.IsHandAllRemovalWaiting()) { dontUseHandAllRemovalFieldSub = new AIVirtualField(originalField); } ExecuteAttackSequenceForAllFields(originalField, dontUseHandAllRemovalFieldSub, enemyTargets, attackerSequencePermLists, evoIndex, bestRecord); } private void ExecuteAttackSequenceForAllFields(AIVirtualField originalField, AIVirtualField DontUseHandAllRemovalFieldSub, List enemyTargets, List attackerSequencePermLists, int evoIndex, SimulationResult bestRecord) { List list = new List(); int count = attackerSequencePermLists.Count; for (int i = 0; i < count; i++) { if (AI.IsRunWeakLogic) { break; } int[] array = attackerSequencePermLists[i]; ulong item = AISimulationUtility.CalculateAttackSequenceHash(array, originalField); if (!list.Contains(item)) { _ruleBaseSimulator.RunSequence(originalField, array, evoIndex, enemyTargets, bestRecord, _simAdditionalOptions, _patternFilter); if (DontUseHandAllRemovalFieldSub != null) { _ruleBaseSimulator.RunSequence(DontUseHandAllRemovalFieldSub, array, evoIndex, enemyTargets, bestRecord, _simAdditionalOptions, _patternFilter); } list.Add(item); } } } private List GetEnemyFollowers(AIVirtualField originalField) { List list = new List(); for (int i = 0; i < originalField.EnemyInplayCards.Count; i++) { AIVirtualCard aIVirtualCard = originalField.EnemyInplayCards[i]; if (!aIVirtualCard.IsUnit) { continue; } bool flag = false; for (int j = 0; j < list.Count; j++) { AIVirtualCard aIVirtualCard2 = originalField.EnemyInplayCards[list[j]]; if (EnemyAI.IsLargerThan(aIVirtualCard.Value, aIVirtualCard2.Value)) { list.Insert(j, i); flag = true; break; } } if (!flag) { list.Add(i); } } return list; } private List GetAllyInplayIndexLIst(AIVirtualField originalField) { List list = new List(); for (int i = 0; i < originalField.AllyInplayCards.Count; i++) { AIVirtualCard aIVirtualCard = originalField.AllyInplayCards[i]; if (aIVirtualCard.IsUnit && !aIVirtualCard.IsDead && aIVirtualCard.AttackableCount > 0) { list.Add(i); } } return list; } }