using System.Collections.Generic; using System.Linq; using UnityEngine; namespace Wizard; public static class AISimulationUtility { public static int FULL_SIMULATION_MOVE_COUNT_TURESHOLD = 16; public static float ILLEGAL_PLAYPTN_VALUE = -1000f; private static readonly int[] PATTERN_GROUP_FOR_5 = new int[1] { 31 }; private static readonly int[] PATTERN_GROUP_FOR_4 = new int[5] { 30, 29, 27, 23, 15 }; private static readonly int[] PATTERN_GROUP_FOR_3 = new int[10] { 28, 26, 25, 22, 21, 19, 14, 13, 11, 7 }; private static readonly int[] PATTERN_GROUP_FOR_2 = new int[10] { 24, 20, 18, 17, 12, 10, 9, 6, 5, 3 }; private static readonly int[] PATTERN_GROUP_FOR_1 = new int[5] { 16, 8, 4, 2, 1 }; private static ulong[] PRIME_NUMBERS_FOR_ENEMY = new ulong[6] { 67uL, 9221uL, 181uL, 271939uL, 3001uL, 12277uL }; private static ulong[] PRIME_NUMBERS_FOR_ALLY = new ulong[6] { 4919uL, 11149uL, 187651uL, 139uL, 3011uL, 2003uL }; public static List GetActionInfoSequence(AIVirtualField field, int[] permList, bool[] isAttackFollowerFlags, int evoIndex) { List list = new List(); if (permList != null && permList.Length <= field.AllyInplayCards.Count((AIVirtualCard c) => c.IsUnit) && permList.Length == isAttackFollowerFlags.Length) { for (int num = 0; num < permList.Length; num++) { int num2 = permList[num]; AIVirtualCard originalActor = field.AllyInplayCards[num2]; AIVirtualCard currentFieldActor = field.AllyInplayCards.FirstOrDefault((AIVirtualCard card) => card.CardIndex == originalActor.CardIndex); if (currentFieldActor == null) { break; } if (num2 == evoIndex && !currentFieldActor.IsEvolution) { field.AllyInplayCards[num2].IsUseEvo = true; if (field.CardListSet.AllyClassAndInplayCards.Any((AIVirtualCard c) => c.IsFirstEvo(currentFieldActor, field.BestPlayPtn))) { list.Insert(0, new AIVirtualTargetSelectAction(currentFieldActor, currentFieldActor, AIOperationType.EVOLVE)); } else { list.Add(new AIVirtualTargetSelectAction(currentFieldActor, currentFieldActor, AIOperationType.EVOLVE)); } } list.Add(new AIVirtualAttackInfo(currentFieldActor, isAttackFollowerFlags[num])); } } field.ActionLength = 0; return list; } public static List GetEnemyTargets(List enemyInplayCards, List targetCandidates, int breakPtnIndex, List playPtn) { List list = new List(); for (int i = 0; i < targetCandidates.Count; i++) { int num = targetCandidates[i]; if (!enemyInplayCards[num].IsAmulet && ((breakPtnIndex >> i) & 1) > 0) { AddTarget(enemyInplayCards, num, list, playPtn); } } return list; } private static void AddTarget(List targetCandidates, int targetIndex, List virtualCardList, List playPtn) { AIVirtualCard tagOwner = targetCandidates[targetIndex]; int num = -1; for (int i = 0; i < virtualCardList.Count; i++) { if (targetCandidates[virtualCardList[i]].IsBreakLast(playPtn)) { num = i; break; } } if (tagOwner.IsBreakFirst(playPtn)) { virtualCardList.Insert(0, targetIndex); } else if (tagOwner.IsBreakLast(playPtn)) { virtualCardList.Add(targetIndex); } else if (num >= 0) { virtualCardList.Insert(num, targetIndex); } else { virtualCardList.Add(targetIndex); } } public static List GetEnemyTargetSequence(AIVirtualField field, List enemyTargetIndexes) { List list = new List(); for (int i = 0; i < enemyTargetIndexes.Count; i++) { if (enemyTargetIndexes[i] < field.EnemyInplayCards.Count && enemyTargetIndexes[i] >= 0) { list.Add(field.EnemyInplayCards[enemyTargetIndexes[i]]); } } return list; } public static bool IsValidEnemyTargetIndexes(List enemyCards, List enemyTargetIndexes) { if (enemyTargetIndexes.Count > enemyCards.Count) { return false; } for (int i = 0; i < enemyTargetIndexes.Count; i++) { if (enemyCards[enemyTargetIndexes[i]].IsAmulet) { return false; } } return true; } public static bool IsValuableEvoIndex(int evoIndex, AIVirtualField originalField) { if (evoIndex >= 0 && !originalField.AllyInplayCards[evoIndex].IsUnit) { return false; } if (evoIndex >= 0) { AIVirtualCard aIVirtualCard = originalField.AllyInplayCards[evoIndex]; AIVirtualTargetSelectAction situation = new AIVirtualTargetSelectAction(aIVirtualCard, aIVirtualCard, AIOperationType.EVOLVE, (AISelectedTargetInfoSet)null); if (!aIVirtualCard.IsAbleEvolution() || aIVirtualCard.CreateAIVirtualSelectInfo(originalField, situation) != null) { return false; } } return true; } public static bool IsBestRecord(AIVirtualField field, float currentFieldValue, float valueAtSelfTurnEnd, SimulationResult bestRecord) { if (field.EnemyClass.IsDead) { int actionLength = field.ActionLength; if (actionLength < bestRecord.MinActionLengthOfLethal || (actionLength == bestRecord.MinActionLengthOfLethal && EnemyAI.IsLargerThan(currentFieldValue, bestRecord.MaxFieldValue))) { return true; } } else { if (EnemyAI.IsLargerThan(currentFieldValue, bestRecord.MaxFieldValue)) { return true; } if (EnemyAI.IsSameValue(currentFieldValue, bestRecord.MaxFieldValue) && EnemyAI.IsLargerThan(valueAtSelfTurnEnd, bestRecord.MaxFieldValueAtSelfTurnEnd)) { return true; } } return false; } public static bool ExecuteVirtualAction(AIVirtualActionInfo actionInfo, AIVirtualActionInfo evolutionInfo, List enemyTargetSequence, SimulationSetting setting) { AIVirtualField selfField = actionInfo.Actor.SelfField; if (actionInfo.IsAlreadyUsed) { _ = (actionInfo.Actor.IsPlayer ? "p" : "e") + actionInfo.Actor.CardIndex; return false; } if (actionInfo.Actor.IsDead) { actionInfo.IsAlreadyUsed = true; return false; } if (actionInfo.ActionType == AIOperationType.EVOLVE) { actionInfo.IsAlreadyUsed = true; if (actionInfo.Actor.IsEvolution) { return false; } if (!actionInfo.Actor.IsUseEvo) { return false; } AIVirtualEvolutionSimulator.ManualEvolve(actionInfo, selfField); selfField.EvoUsedCard = actionInfo.Actor; } else if (actionInfo is AIVirtualAttackInfo aIVirtualAttackInfo) { AIVirtualAttackInfo aIVirtualAttackInfo2 = aIVirtualAttackInfo; if (aIVirtualAttackInfo.AttackTarget != null) { aIVirtualAttackInfo2 = new AIVirtualAttackInfo(aIVirtualAttackInfo.Actor, aIVirtualAttackInfo.IsAttackFollower, aIVirtualAttackInfo.PremiseAction); } AIVirtualCard aIVirtualCard = BattleSequencer.FindAttackTarget(selfField, aIVirtualAttackInfo2, enemyTargetSequence, evolutionInfo, setting.IsHandRemovalValid, setting.NoSkipAttack, aIVirtualAttackInfo2.IsAttackFollower); bool isAttackerUsed = false; if (aIVirtualCard != null) { AIAttackSimulationUtility.SimulateAttackIfValuable(aIVirtualAttackInfo2, selfField, setting.UseLeaderAttackPreCheck, ref isAttackerUsed); if (aIVirtualCard.IsDead) { aIVirtualAttackInfo2.IsBreakTarget = true; } } else { aIVirtualAttackInfo2.SetAttackTarget(null); isAttackerUsed = true; } actionInfo.IsAlreadyUsed = isAttackerUsed; if (!aIVirtualAttackInfo2.IsAttackSuccessed) { return false; } } return true; } public static float EvaluateField(AIVirtualField field, EvaluationType type) { switch (type) { case EvaluationType.FULL: return field.EvaluateField() - (field.EnemyClass.IsDead ? 0f : field.EvaluateThreaten()); case EvaluationType.SELF_TURN: case EvaluationType.SIMPLE: return field.EvaluateField(); default: return 0f; } } public static float EvaluateLegalPlayPtnAfterSimulation(AIVirtualField fieldTemp, List actionInfoSequence, PlayPtnWithToken[] playPtnsWithToken, int openCount, ulong[] defaultPlayptnHashs, out PlayPtnWithToken bestPlayPtnWithToken, out int bestFirstDeadActionIndex) { bestFirstDeadActionIndex = int.MaxValue; bestPlayPtnWithToken = null; ulong[] array = CalculatePlayptnWithTokenHashs(fieldTemp, playPtnsWithToken); PlayPtnWithToken[] array2 = new PlayPtnWithToken[playPtnsWithToken.Length]; for (int i = 0; i < playPtnsWithToken.Length; i++) { PlayPtnWithToken playPtnWithToken = playPtnsWithToken[i]; if (playPtnWithToken == null || array[i] != defaultPlayptnHashs[i]) { array2[i] = null; } else { array2[i] = playPtnWithToken; } } if (array2.Any((PlayPtnWithToken p) => p != null)) { return EvaluatePlayPtnValue(fieldTemp, actionInfoSequence, array2, openCount, out bestPlayPtnWithToken, out bestFirstDeadActionIndex); } return ILLEGAL_PLAYPTN_VALUE; } private static float EvaluatePlayPtnValue(AIVirtualField fieldTemp, List actionInfoSequence, PlayPtnWithToken[] playPtnsWithToken, int openCount, out PlayPtnWithToken bestPlayPtnWithToken, out int bestFirstDeadActionIndex) { AIVirtualFieldRollBackBasicProcessor aIVirtualFieldRollBackBasicProcessor = new AIVirtualFieldRollBackBasicProcessor(fieldTemp); AIStyleQuery styleQuery = fieldTemp.ParamQuery.styleQuery; float num = float.MinValue; bestFirstDeadActionIndex = int.MaxValue; bestPlayPtnWithToken = null; for (int num2 = openCount; num2 >= 0; num2--) { if (playPtnsWithToken[num2] != null) { PlayPtnWithToken playPtnWithToken = playPtnsWithToken[num2]; if (playPtnWithToken != null) { List list = (fieldTemp.BestPlayPtn = playPtnWithToken.PlayPtn); fieldTemp.UpdateBestPlayptnRecordOnSim(list); List tokenPtn = playPtnWithToken.TokenPtn; if (list.Count == tokenPtn.Count) { float num3 = float.MinValue; for (int i = 0; i < fieldTemp.AllyInplayCards.Count; i++) { AIVirtualCard aIVirtualCard = fieldTemp.AllyInplayCards[i]; if (aIVirtualCard.IsUnit && !aIVirtualCard.IsDead && aIVirtualCard.IsAbleEvolution()) { float num4 = aIVirtualCard.EvaluateAllEvoBonus(list, new AIVirtualTargetSelectAction(aIVirtualCard, aIVirtualCard, AIOperationType.EVOLVE, (AISelectedTargetInfoSet)null)); if (num4 > num3) { num3 = num4; } } } float num5 = 0f; AISinglePlayptnRecord playptnRecordOnSim = fieldTemp.GetPlayptnRecordOnSim(list); for (int j = 0; j < tokenPtn.Count; j++) { TokenPlayPattern tokenPlayPattern = tokenPtn[j]; AIVirtualCard aIVirtualCard2 = fieldTemp.AllyHandCards[list[j]]; AIVirtualTargetSelectAction situation = new AIVirtualTargetSelectAction(aIVirtualCard2, aIVirtualCard2, AIOperationType.PLAY, (AISelectedTargetInfoSet)null); AIPreprocessSimulationUtility.SimulatePreprocess(aIVirtualCard2, situation, fieldTemp, AIScriptTokenArgType.WHEN_PLAY, isPseudo: true); bool flag = fieldTemp.StyleQuery.IsPlayBreak(aIVirtualCard2, list, situation); bool flag2 = playptnRecordOnSim.PlayedCardList[j].PlayType == PlaySimulationType.Accelerate; if (!flag && !flag2) { num5 += aIVirtualCard2.EvaluateValueOnField(list, null, useStyle: true); } num5 += aIVirtualCard2.EvaluatePlayValue(list, situation); num5 += (aIVirtualCard2.GetAllBreakBonus(list, useIgnoreInBattle: false) + aIVirtualCard2.GetAllLeaveBonus(list, useIgnoreInBattle: false)) * (flag ? 1f : EnemyAI.BREAKBONUS_RATE_IN_HAND); fieldTemp.UpdateVirtualFieldWhenEvaluation(aIVirtualCard2, situation); if (tokenPlayPattern.TokenInfoPairList != null && tokenPlayPattern.TokenInfoPairList.Count > 0) { for (int k = 0; k < tokenPlayPattern.TokenInfoPairList.Count; k++) { AITokenInformation aITokenInformation = tokenPlayPattern.TokenInfoPairList[k]; int tokenId = aITokenInformation.TokenId; AIVirtualCard tokenFromId = fieldTemp.AI.tokenManager.GetTokenFromId(tokenId, aIVirtualCard2.IsAlly, fieldTemp); num5 += tokenFromId.EvaluateValueOnField(list, null, useStyle: true); num5 += (tokenFromId.GetAllBreakBonus(list, useIgnoreInBattle: false) + tokenFromId.GetAllLeaveBonus(list, useIgnoreInBattle: false)) * EnemyAI.BREAKBONUS_RATE_IN_HAND; if (aITokenInformation.TokenType == AITokenType.Reanimate) { num5 += tokenFromId.GetReanimateBonus(list); } } } if (j == 0 && aIVirtualCard2.IsFollower(list) && aIVirtualCard2.IsAbleEvolution()) { float num6 = aIVirtualCard2.EvaluateAllEvoBonus(list, new AIVirtualTargetSelectAction(aIVirtualCard2, aIVirtualCard2, AIOperationType.EVOLVE, (AISelectedTargetInfoSet)null)); if (num6 > num3) { num5 += num6; } } } aIVirtualFieldRollBackBasicProcessor.ResetVirtualFieldToStart(); num5 += AIEvaluateBonusFromOhterUtility.GetPlayPtnBonus(fieldTemp, list) + styleQuery.GetPlayptnBonus(fieldTemp, list); int num7 = int.MaxValue; for (int l = 0; l < actionInfoSequence.Count; l++) { if (actionInfoSequence[l].Actor != null && actionInfoSequence[l].Actor.IsDead) { num7 = l; break; } } if (EnemyAI.IsLargerThan(num5, num) || (EnemyAI.IsSameValue(num5, num) && num7 < bestFirstDeadActionIndex)) { num = num5; bestFirstDeadActionIndex = num7; bestPlayPtnWithToken = playPtnWithToken; } } } } } return num; } public static float CalculateMoveFirstBonusValue(List moves) { if (moves == null || !moves.Any()) { return 0f; } AIVirtualCard actor = moves[0].Actor; return actor.SelfField.StyleQuery.GetFirstMoveBonus(actor, moves); } public static float CalculateOneOnOneBothDeadBonus(List moves) { if (moves.Count <= 1 || !(moves[0] is AIVirtualAttackInfo)) { return 0f; } AIVirtualAttackInfo aIVirtualAttackInfo = moves[0] as AIVirtualAttackInfo; if (aIVirtualAttackInfo.Actor.IsDead && aIVirtualAttackInfo.IsBreakTarget) { return 0.002f; } return 0f; } public static List GetAllMovesForFullSimulation(AIVirtualField field, bool doesUseEvo, SimulationAdditionalActionInfoSet additionalActionInfoSet) { AIVirtualTargetSelectAction aIVirtualTargetSelectAction = null; List extraActions = null; AISinglePlayptnRecord playPtnRecord = null; if (additionalActionInfoSet != null) { aIVirtualTargetSelectAction = additionalActionInfoSet.ForceEvoAction; extraActions = additionalActionInfoSet.ExtraActionBaseList; playPtnRecord = additionalActionInfoSet.PlayPtnRecord; } List list = null; if (doesUseEvo) { list = GetAllVirtualInplayMove(field); } else { list = GetAllVirtualAttackMove(field); if (aIVirtualTargetSelectAction != null) { AIVirtualActionInfo aIVirtualActionInfo = CreateActionInfoOnFieldFromSituation(field, aIVirtualTargetSelectAction); if (aIVirtualActionInfo != null) { list.Add(aIVirtualActionInfo); } } } List allExtraActionList = GetAllExtraActionList(field, extraActions, playPtnRecord); if (allExtraActionList != null && allExtraActionList.Count > 0) { list.AddRange(allExtraActionList); } list.Add(new AIVirtualTurnEndInfo(field.AllyClass)); return list; } private static List GetAllVirtualInplayMove(AIVirtualField field) { List list = new List(); List allVirtualEvolMove = GetAllVirtualEvolMove(field); List allVirtualAttackMove = GetAllVirtualAttackMove(field); for (int i = 0; i < allVirtualEvolMove.Count; i++) { list.Add(allVirtualEvolMove[i]); } for (int j = 0; j < allVirtualAttackMove.Count; j++) { list.Add(allVirtualAttackMove[j]); } return list; } private static List GetAllVirtualEvolMove(AIVirtualField field) { List list = new List(); if (field.EvoUsedCard != null) { return list; } for (int i = 0; i < field.AllyInplayCards.Count; i++) { AIVirtualCard aIVirtualCard = field.AllyInplayCards[i]; if (!aIVirtualCard.IsDead) { AIVirtualTargetSelectAction aIVirtualTargetSelectAction = new AIVirtualTargetSelectAction(aIVirtualCard, aIVirtualCard, AIOperationType.EVOLVE); if (aIVirtualCard.IsAbleEvolution() && aIVirtualCard.CreateAIVirtualSelectInfo(field, aIVirtualTargetSelectAction) == null) { list.Add(aIVirtualTargetSelectAction); } } } return list; } private static List GetAllVirtualAttackMove(AIVirtualField field) { List list = new List(); for (int i = 0; i < field.AllyInplayCards.Count; i++) { AIVirtualCard aIVirtualCard = field.AllyInplayCards[i]; if (aIVirtualCard.IsDead) { continue; } for (int j = 0; j < field.EnemyInplayCards.Count; j++) { AIVirtualCard aIVirtualCard2 = field.EnemyInplayCards[j]; AIVirtualAttackInfo aIVirtualAttackInfo = new AIVirtualAttackInfo(aIVirtualCard, aIVirtualCard2); if (!aIVirtualCard2.IsDead && AIAttackSimulationUtility.IsAttackPossible(field, aIVirtualAttackInfo)) { list.Add(aIVirtualAttackInfo); } } } for (int k = 0; k < field.AllyInplayCards.Count; k++) { AIVirtualCard aIVirtualCard3 = field.AllyInplayCards[k]; if (!aIVirtualCard3.IsDead) { AIVirtualAttackInfo aIVirtualAttackInfo2 = new AIVirtualAttackInfo(aIVirtualCard3, field.EnemyClass); if (!field.EnemyClass.IsDead && AIAttackSimulationUtility.IsAttackPossible(field, aIVirtualAttackInfo2)) { list.Add(aIVirtualAttackInfo2); } } } return list; } private static List GetAllExtraActionList(AIVirtualField field, List extraActions, AISinglePlayptnRecord playPtnRecord) { if (extraActions == null || extraActions.Count <= 0) { return null; } List list = null; for (int i = 0; i < extraActions.Count; i++) { AIVirtualActionInfo aIVirtualActionInfo = extraActions[i]; if (aIVirtualActionInfo.ActionType != AIOperationType.PLAY || !(CreateActionInfoOnFieldFromSituation(field, aIVirtualActionInfo) is AIVirtualTargetSelectAction aIVirtualTargetSelectAction)) { continue; } List list2 = aIVirtualTargetSelectAction.Actor.CreateAIVirtualSelectInfo(field, aIVirtualTargetSelectAction); if (list2 == null || list2.Count <= 0) { if (AIPlayCardSimulationUtility.IsAbleToPlayCard(aIVirtualTargetSelectAction, field, EnemyAI.EmptyPlayPtn) && field.AllyInplayCards.Count((AIVirtualCard c) => !c.IsDead) < 5) { list = AIParamQuery.AddElementToList(aIVirtualTargetSelectAction, list); } continue; } AISelectedTargetInfoSet preDecidedTargetSet = null; if (aIVirtualTargetSelectAction.SelectedTargets.IsAnyTargetExists()) { preDecidedTargetSet = aIVirtualTargetSelectAction.SelectedTargets; } List allTargetSelectSimulationPattern = AIVirtualTargetSelectSimulator.GetAllTargetSelectSimulationPattern(list2, preDecidedTargetSet, aIVirtualTargetSelectAction, field, playPtnRecord); if (allTargetSelectSimulationPattern == null || allTargetSelectSimulationPattern.Count <= 0) { continue; } for (int num = 0; num < allTargetSelectSimulationPattern.Count; num++) { AISelectedTargetInfoSet selectedTargetList = allTargetSelectSimulationPattern[num]; AIVirtualTargetSelectAction aIVirtualTargetSelectAction2 = new AIVirtualTargetSelectAction(aIVirtualTargetSelectAction.Actor, aIVirtualTargetSelectAction.OriginalCard, AIOperationType.PLAY, selectedTargetList); if (AIPlayCardSimulationUtility.IsAbleToPlayCard(aIVirtualTargetSelectAction2, field, EnemyAI.EmptyPlayPtn) && field.AllyInplayCards.Count < 5) { list = AIParamQuery.AddElementToList(aIVirtualTargetSelectAction2, list); } } } return list; } public static float EvaluateAttackValueAfterAllSkill(AIVirtualField field, AISituationInfo situation, List allyAttackers, List enemyRemains, List playPtn) { for (int i = 0; i < allyAttackers.Count; i++) { allyAttackers[i].CalculateCardValueWhenDestroyed(playPtn, situation); } for (int j = 0; j < enemyRemains.Count; j++) { enemyRemains[j].CalculateCardValueWhenDestroyed(playPtn, situation); } enemyRemains.OrderBy((AIVirtualCardStatusInfo info) => info.ValueWhenDestroyed); float num = 0f; AIVirtualAttackInfo aIVirtualAttackInfo = new AIVirtualAttackInfo(null, null); for (int num2 = 0; num2 < enemyRemains.Count; num2++) { AIVirtualCardStatusInfo aIVirtualCardStatusInfo = enemyRemains[num2]; aIVirtualAttackInfo.SetAttackTarget(aIVirtualCardStatusInfo.BaseCard); float num3 = 0f; List usedAttackers = null; int num4 = 0; List list = null; int num5 = (int)Mathf.Pow(2f, allyAttackers.Count); for (int num6 = 0; num6 < num5; num6++) { int num7 = num6; int num8 = 0; int num9 = 0; int num10 = 0; float num11 = 0f; float num12 = 0f; List list2 = new List(); List list3 = new List(); while (num7 > 0) { if (num7 % 2 == 1) { AIVirtualCardStatusInfo aIVirtualCardStatusInfo2 = allyAttackers[num8]; if (!aIVirtualCardStatusInfo2.BaseCard.IsAttackable(EnemyAI.EmptyPlayPtn)) { num8++; num7 /= 2; continue; } aIVirtualAttackInfo.SetActor(aIVirtualCardStatusInfo2.BaseCard); list2.Add(aIVirtualCardStatusInfo2); num9 += aIVirtualCardStatusInfo.BaseCard.SimulateDamageAmount(aIVirtualCardStatusInfo2.BaseCard.SimulateAttackAmount(aIVirtualCardStatusInfo2.Attack, aIVirtualAttackInfo)); num10 += aIVirtualCardStatusInfo.BaseCard.SimulateDamageAmount(aIVirtualCardStatusInfo2.BaseCard.SimulateAttackAmount(aIVirtualAttackInfo)); int num13 = aIVirtualCardStatusInfo2.BaseCard.SimulateDamageAmount(aIVirtualCardStatusInfo.BaseCard.SimulateAttackAmount(aIVirtualCardStatusInfo.Attack, aIVirtualAttackInfo)); int num14 = aIVirtualCardStatusInfo2.BaseCard.SimulateDamageAmount(aIVirtualCardStatusInfo.BaseCard.SimulateAttackAmount(aIVirtualAttackInfo)); list3.Add(num13); if (num13 >= aIVirtualCardStatusInfo2.Life) { num11 += aIVirtualCardStatusInfo2.ValueWhenDestroyed; } int num15 = Mathf.Max(0, aIVirtualCardStatusInfo2.Life - num13); int num16 = Mathf.Max(0, aIVirtualCardStatusInfo2.BaseCard.Life - num14); num12 += (float)(num15 - num16); } num8++; num7 /= 2; } float num17 = 0f; num17 = ((num10 >= aIVirtualCardStatusInfo.BaseCard.Life) ? 0f : ((num9 >= aIVirtualCardStatusInfo.Life) ? (aIVirtualCardStatusInfo.ValueWhenDestroyed - num11) : 0f)); num17 += num12; if (num3 < num17) { num3 = num17; usedAttackers = list2; num4 = num9; list = list3; } } if (usedAttackers != null && list != null) { allyAttackers.RemoveAll((AIVirtualCardStatusInfo card) => usedAttackers.Contains(card)); num += num3; for (int num18 = 0; num18 < usedAttackers.Count; num18++) { AIVirtualCardStatusInfo aIVirtualCardStatusInfo3 = usedAttackers[num18]; int num19 = list[num18]; aIVirtualCardStatusInfo3.ModifyStatus(aIVirtualCardStatusInfo3.Attack, aIVirtualCardStatusInfo3.Life - num19); } aIVirtualCardStatusInfo.ModifyStatus(aIVirtualCardStatusInfo.Attack, aIVirtualCardStatusInfo.Life - num4); } } return num; } public static int[] GetPatternGroup(int count) { return count switch { 5 => PATTERN_GROUP_FOR_5, 4 => PATTERN_GROUP_FOR_4, 3 => PATTERN_GROUP_FOR_3, 2 => PATTERN_GROUP_FOR_2, 1 => PATTERN_GROUP_FOR_1, _ => null, }; } public static int Factorial(int n) { if (n <= 1) { return 1; } return n * Factorial(n - 1); } public static ulong CalculateTargetSequenceHash(int[] permList, AIVirtualField field) { ulong num = 0uL; for (int i = 0; i < permList.Length; i++) { AIVirtualCard aIVirtualCard = field.EnemyInplayCards[permList[i]]; num += aIVirtualCard.GetHash() * PRIME_NUMBERS_FOR_ENEMY[i]; } return num; } public static ulong CalculateAttackSequenceHash(int[] permList, AIVirtualField field) { ulong num = 0uL; for (int i = 0; i < permList.Length; i++) { AIVirtualCard aIVirtualCard = field.AllyInplayCards[permList[i]]; num += aIVirtualCard.GetHash() * PRIME_NUMBERS_FOR_ALLY[i]; } return num; } public static ulong[] CalculatePlayptnWithTokenHashs(AIVirtualField field, PlayPtnWithToken[] bestPlayptnWithTokens) { if (bestPlayptnWithTokens == null) { return null; } ulong[] array = new ulong[bestPlayptnWithTokens.Length]; for (int i = 0; i < bestPlayptnWithTokens.Length; i++) { PlayPtnWithToken playPtnWithToken = bestPlayptnWithTokens[i]; if (playPtnWithToken == null) { array[i] = 0uL; } else { array[i] = field.CalculatePlayptnHash(playPtnWithToken.PlayPtn); } } return array; } public static AIVirtualActionInfo CreateActionInfoOnFieldFromSituation(AIVirtualField fieldTemp, AISituationInfo situation) { if (situation == null || situation.Actor == null) { return null; } switch (situation.ActionType) { case AIOperationType.ATTACK: { AIVirtualAttackInfo attackInfo = situation as AIVirtualAttackInfo; if (attackInfo != null) { AIVirtualCard sourceCard = fieldTemp.AllyInplayCards.Find((AIVirtualCard c) => c.IsSameCard(attackInfo.Actor)); AIVirtualCard target = fieldTemp.CardListSet.EnemyClassAndInplayCards.Find((AIVirtualCard c) => c.IsSameCard(attackInfo.AttackTarget)); return new AIVirtualAttackInfo(sourceCard, target); } return null; } case AIOperationType.EVOLVE: { AIVirtualCard aIVirtualCard2 = fieldTemp.AllyInplayCards.Find((AIVirtualCard c) => c.IsSameCard(situation.Actor)); if (aIVirtualCard2.IsEvolution) { return null; } aIVirtualCard2.IsUseEvo = true; AISelectedTargetInfoSet similarTargetInfoSet = situation.SelectedTargets.GetSimilarTargetInfoSet(fieldTemp); return new AIVirtualTargetSelectAction(aIVirtualCard2, aIVirtualCard2, AIOperationType.EVOLVE, similarTargetInfoSet); } case AIOperationType.PLAY: { AIVirtualCard aIVirtualCard = fieldTemp.AllyHandCards.Find((AIVirtualCard c) => c.IsSameCard(situation.OriginalCard)); if (aIVirtualCard == null) { return null; } return new AIVirtualTargetSelectAction(aIVirtualCard.IsSameCard(situation.Actor) ? aIVirtualCard : new AIVirtualCard(situation.Actor, fieldTemp), aIVirtualCard, AIOperationType.PLAY); } default: return null; } } }