using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Cute; namespace Wizard; public class BestOpenSpaceAttackAI { private EnemyAI AI; public AIVirtualActionInfo Cr_FirstActionInfo; public PlayPtnWithToken Cr_BestPlayPtnWithToken; private ulong[] _defaultPlayptnHashArray; public BestOpenSpaceAttackAI(EnemyAI ai) { AI = ai; } public IEnumerator _CrSimulate(AIVirtualField originalField, PlayPtnWithToken[] bestPlayPtnsWithToken) { AI.IsInVirutalSimulation = true; float maxFieldValue = float.MinValue; int bestFirstDeadActionIndex = int.MaxValue; List bestActionInfoSequence = null; AIVirtualField bestField = originalField; Cr_BestPlayPtnWithToken = null; Cr_FirstActionInfo = null; _defaultPlayptnHashArray = AISimulationUtility.CalculatePlayptnWithTokenHashs(originalField, bestPlayPtnsWithToken); ParallelJob job = ParallelJob.Dispatch(delegate { try { int count = originalField.AllyInplayCards.Count; List list = new List(); for (int i = 0; i < originalField.AllyInplayCards.Count; i++) { AIVirtualCard aIVirtualCard = originalField.AllyInplayCards[i]; int num = 0; for (num = 0; num < list.Count && !(aIVirtualCard.Value < originalField.AllyInplayCards[list[num]].Value); num++) { } list.Insert(num, i); } int num2 = (1 << originalField.AllyInplayCards.Count) - 1; List list2 = new List(); for (int j = 0; j <= num2; j++) { if (IsValidBreakIndex(originalField.AllyInplayCards, list, j)) { if (AI.IsBattleEnd || AI.IsRunWeakLogic) { break; } int[] allyAttackers = GetAllyAttackers(originalField, list, j); ulong item = AISimulationUtility.CalculateAttackSequenceHash(allyAttackers, originalField); if (!list2.Contains(item)) { List list3 = new List(); for (int k = 0; k < originalField.EnemyInplayCards.Count; k++) { if (originalField.EnemyInplayCards[k].IsUnit) { list3.Add(k); } } if (AI.IsRunWeakLogic) { break; } List list4 = AIMathematicsLibrary.EnumeratePermutations(list3).ToList(); List list5 = new List(); for (int l = 0; l < list4.Count; l++) { List enemyTargetIndexes = list4[l].ToList(); if (AISimulationUtility.IsValidEnemyTargetIndexes(originalField.EnemyInplayCards, enemyTargetIndexes)) { ulong item2 = AISimulationUtility.CalculateTargetSequenceHash(list4[l], originalField); if (!list5.Contains(item2)) { int num3 = (1 << allyAttackers.Length) - 1; for (int m = 0; m <= num3; m++) { if (AI.IsRunWeakLogic) { return; } bool[] attackLeaderOrFollowerFlags = GetAttackLeaderOrFollowerFlags(m, allyAttackers.Length); AIVirtualField aIVirtualField = new AIVirtualField(originalField); List actionInfoSequence = AISimulationUtility.GetActionInfoSequence(aIVirtualField, allyAttackers, attackLeaderOrFollowerFlags, -1); List enemyTargetSequence = AISimulationUtility.GetEnemyTargetSequence(aIVirtualField, enemyTargetIndexes); BattleSequencer.ExecSimulation(aIVirtualField, actionInfoSequence, enemyTargetSequence, new SimulationSetting(isHandRemovalValid: true, useLeaderAttackPreCheck: false, noSkipAttack: true)); _ = aIVirtualField.EnemyClass.IsDead; if (AI.IsRunWeakLogic) { return; } float num4 = AISimulationUtility.EvaluateField(aIVirtualField, EvaluationType.SIMPLE); if (AI.IsRunWeakLogic) { return; } int openCount = count - aIVirtualField.AllyInplayCards.Count((AIVirtualCard c) => !c.IsDead); PlayPtnWithToken bestPlayPtnWithToken = null; int bestFirstDeadActionIndex2 = int.MaxValue; float num5 = AISimulationUtility.EvaluateLegalPlayPtnAfterSimulation(aIVirtualField, actionInfoSequence, bestPlayPtnsWithToken, openCount, _defaultPlayptnHashArray, out bestPlayPtnWithToken, out bestFirstDeadActionIndex2); float num6 = num4 + num5; if (AI.IsRunWeakLogic) { return; } if (EnemyAI.IsLargerThan(num6, maxFieldValue) || (EnemyAI.IsSameValue(num6, maxFieldValue) && bestFirstDeadActionIndex2 < bestFirstDeadActionIndex)) { maxFieldValue = num6; bestFirstDeadActionIndex = bestFirstDeadActionIndex2; Cr_BestPlayPtnWithToken = bestPlayPtnWithToken; bestActionInfoSequence = actionInfoSequence; bestField = aIVirtualField; } } list5.Add(item2); } } } list2.Add(item); } } } } catch (Exception) { } }); while (!job.isDone) { yield return null; if (AI.IsRunWeakLogic) { AI.IsInVirutalSimulation = false; yield break; } } if (AI.IsBattleEnd) { AI.IsInVirutalSimulation = false; yield break; } if (bestActionInfoSequence.Count > 0) { Cr_FirstActionInfo = BattleSequencer.GetFirstActionInfo(bestActionInfoSequence, bestField, Cr_BestPlayPtnWithToken.PlayPtn); } AI.IsInVirutalSimulation = false; } private bool IsValidBreakIndex(List allyCards, List sortedInplayIndex, int sortedBreakIndex) { for (int i = 0; i < allyCards.Count; i++) { if (((sortedBreakIndex >> i) & 1) > 0) { AIVirtualCard aIVirtualCard = allyCards[sortedInplayIndex[i]]; if (aIVirtualCard.IsAmulet || aIVirtualCard.AttackableCount <= 0) { return false; } } } return true; } private int[] GetAllyAttackers(AIVirtualField field, List sortedInplayIndex, int sortedBreakIndex) { List list = new List(); for (int i = 0; i < sortedInplayIndex.Count; i++) { if (!field.AllyInplayCards[sortedInplayIndex[i]].IsAmulet && ((sortedBreakIndex >> i) & 1) > 0) { list.Add(sortedInplayIndex[i]); } } return list.ToArray(); } private bool[] GetAttackLeaderOrFollowerFlags(int index, int attackerCount) { bool[] array = new bool[attackerCount]; for (int i = 0; i < attackerCount; i++) { if (((index >> i) & 1) > 0) { array[i] = true; } else { array[i] = false; } } return array; } }