[TestFixture] public class AiTest { [Test] public void Test() { Settings.Instance.LogFolderPath = @"C:\repository\GitHub\ChuckLu\Test\HearthbuddyRelease\Logs"; Settings.Instance.DataFolderPath = @"C:\repository\GitHub\ChuckLu\Test\HearthbuddyRelease\Routines\DefaultRoutine\SilverFish\Data\"; if (Hrtprozis.Instance.settings == null) { Hrtprozis.Instance.setInstances(); ComboBreaker.Instance.setInstances(); PenalityManager.Instance.setInstances(); } //-mode: 0-all, 1-lethalcheck, 2-normal Ai ai = Ai.Instance; ai.autoTester(true, string.Empty, 2); } }
if (mode == 0 || mode == 1) { doallmoves(false, true); calcTime = (DateTime.Now - strt).TotalSeconds; help.logg("calculated " + calcTime); retval.Add(calcTime); } if (Settings.Instance.berserkIfCanFinishNextTour > 0 && bestmoveValue > 5000) { } else if (bestmoveValue < 10000) { // normal if (mode == 0 || mode == 2) { posmoves.Clear(); pMain = new Playfield(); pMain.print = printstuff; posmoves.Add(pMain); strt = DateTime.Now; doallmoves(false, false); calcTime = (DateTime.Now - strt).TotalSeconds; help.logg("calculated " + calcTime); retval.Add(calcTime); } }
发现格雷迈恩的效果,不知道怎么触发的,需要直接运行exe调试
在 routine.Tick();设置断点,F11之后会加载DefaultRoutine.dll
// Triton.Bot.RoutineManager // Token: 0x060011C9 RID: 4553 RVA: 0x000B65BC File Offset: 0x000B47BC public static void Tick(IRoutine routine) { RoutineManager.smethod_0(routine, RoutineManager.routineEvent_2); try { routine.Tick(); } catch (Exception exception) { RoutineManager.ilog_0.Error("Exception during routine Tick.", exception); } RoutineManager.smethod_0(routine, RoutineManager.routineEvent_3); }
// HREngine.Bots.Ai // Token: 0x06000061 RID: 97 RVA: 0x00009000 File Offset: 0x00007200 private void doallmoves(bool test, bool isLethalCheck) { foreach (EnemyTurnSimulator ets in this.enemyTurnSim) { ets.setMaxwide(true); } foreach (EnemyTurnSimulator ets2 in this.enemySecondTurnSim) { ets2.setMaxwide(true); } this.posmoves[0].isLethalCheck = isLethalCheck; this.mainTurnSimulator.doallmoves(this.posmoves[0]); this.bestplay = this.mainTurnSimulator.bestboard; float bestval = this.mainTurnSimulator.bestmoveValue; this.help.loggonoff(true); this.help.logg("-------------------------------------"); bool flag = this.bestplay.ruleWeight != 0; if (flag) { this.help.logg("ruleWeight " + this.bestplay.ruleWeight * -1); } bool flag2 = this.settings.printRules > 0; if (flag2) { string[] rulesStr = this.bestplay.rulesUsed.Split(new char[] { '@' }); foreach (string rs in rulesStr) { bool flag3 = rs == ""; if (!flag3) { this.help.logg("rule: " + rs); } } } this.help.logg("value of best board " + bestval); this.bestActions.Clear(); this.bestmove = null; ActionNormalizer an = new ActionNormalizer(); bool flag4 = this.settings.adjustActions > 0; if (flag4) { an.adjustActions(this.bestplay, isLethalCheck); } foreach (Action a in this.bestplay.playactions) { this.bestActions.Add(new Action(a)); a.print(false); } bool flag5 = this.bestActions.Count >= 1; if (flag5) { this.bestmove = this.bestActions[0]; this.bestActions.RemoveAt(0); } this.bestmoveValue = bestval; bool flag6 = this.bestmove != null && this.bestmove.actionType > actionEnum.endturn; if (flag6) { this.nextMoveGuess = new Playfield(); this.nextMoveGuess.doAction(this.bestmove); } else { this.nextMoveGuess.mana = -100; } if (isLethalCheck) { this.lethalMissing = this.bestplay.enemyHero.armor + this.bestplay.enemyHero.Hp; this.help.logg("missing dmg to lethal " + this.lethalMissing); } }
// HREngine.Bots.MiniSimulator // Token: 0x060000E0 RID: 224 RVA: 0x00018480 File Offset: 0x00016680 public float doallmoves(Playfield playf) { this.print = playf.print; this.isLethalCheck = playf.isLethalCheck; this.enoughCalculations = false; this.botBase = Ai.Instance.botBase; this.posmoves.Clear(); this.twoturnfields.Clear(); this.addToPosmoves(playf); bool havedonesomething = true; List<Playfield> temp = new List<Playfield>(); int deep = 0; this.calculated = 0; Playfield bestold = null; this.bestoldval = -2E+07f; while (havedonesomething) { bool flag = this.printNormalstuff; if (flag) { Helpfunctions.Instance.logg("ailoop"); } GC.Collect(); temp.Clear(); temp.AddRange(this.posmoves); this.posmoves.Clear(); havedonesomething = false; this.threadnumberGlobal = 0; bool flag2 = this.print; if (flag2) { this.startEnemyTurnSimThread(temp, 0, temp.Count); } else { Parallel.ForEach<Tuple<int, int>>(Partitioner.Create(0, temp.Count), delegate(Tuple<int, int> range) { this.startEnemyTurnSimThread(temp, range.Item1, range.Item2); }); } foreach (Playfield p in temp) { bool flag3 = this.totalboards > 0; if (flag3) { this.calculated += p.nextPlayfields.Count; } bool flag4 = this.calculated <= this.totalboards; if (flag4) { this.posmoves.AddRange(p.nextPlayfields); p.nextPlayfields.Clear(); } float pVal = this.botBase.getPlayfieldValue(p); bool flag5 = pVal > this.bestoldval; if (flag5) { this.bestoldval = pVal; bestold = p; this.bestoldDuplicates.Clear(); } else { bool flag6 = pVal == this.bestoldval; if (flag6) { this.bestoldDuplicates.Add(p); } } } bool flag7 = this.isLethalCheck && this.bestoldval >= 10000f; if (flag7) { this.posmoves.Clear(); } bool flag8 = this.posmoves.Count > 0; if (flag8) { havedonesomething = true; } bool flag9 = this.printNormalstuff; if (flag9) { int donec = 0; foreach (Playfield p2 in this.posmoves) { bool complete = p2.complete; if (complete) { donec++; } } Helpfunctions.Instance.logg(string.Concat(new object[] { "deep ", deep, " len ", this.posmoves.Count, " dones ", donec })); } this.cuttingposibilities(this.isLethalCheck); bool flag10 = this.printNormalstuff; if (flag10) { Helpfunctions.Instance.logg("cut to len " + this.posmoves.Count); } deep++; temp.Clear(); bool flag11 = this.calculated > this.totalboards; if (flag11) { this.enoughCalculations = true; } bool flag12 = deep >= this.maxdeep; if (flag12) { this.enoughCalculations = true; } } bool flag13 = this.dirtyTwoTurnSim > 0 && !this.twoturnfields.Contains(bestold); if (flag13) { this.twoturnfields.Add(bestold); } this.posmoves.Clear(); this.posmoves.Add(bestold); this.posmoves.AddRange(this.bestoldDuplicates); bool flag14 = !this.isLethalCheck && this.bestoldval < 10000f; if (flag14) { this.doDirtyTwoTurnsim(); } bool flag15 = this.posmoves.Count >= 1; float result; if (flag15) { this.posmoves.Sort((Playfield a, Playfield b) => this.botBase.getPlayfieldValue(b).CompareTo(this.botBase.getPlayfieldValue(a))); Playfield bestplay = this.posmoves[0]; float bestval = this.botBase.getPlayfieldValue(bestplay); int pcount = this.posmoves.Count; for (int i = 1; i < pcount; i++) { float val = this.botBase.getPlayfieldValue(this.posmoves[i]); bool flag16 = bestval > val; if (flag16) { break; } bool flag17 = this.posmoves[i].cardsPlayedThisTurn > bestplay.cardsPlayedThisTurn; if (!flag17) { bool flag18 = this.posmoves[i].cardsPlayedThisTurn == bestplay.cardsPlayedThisTurn; if (flag18) { bool flag19 = bestplay.optionsPlayedThisTurn > this.posmoves[i].optionsPlayedThisTurn; if (flag19) { goto IL_57A; } bool flag20 = bestplay.optionsPlayedThisTurn == this.posmoves[i].optionsPlayedThisTurn && bestplay.enemyHero.Hp <= this.posmoves[i].enemyHero.Hp; if (flag20) { goto IL_57A; } } bestplay = this.posmoves[i]; bestval = val; } IL_57A:; } this.bestmove = bestplay.getNextAction(); this.bestmoveValue = bestval; this.bestboard = new Playfield(bestplay); this.bestboard.guessingHeroHP = bestplay.guessingHeroHP; this.bestboard.value = bestplay.value; this.bestboard.hashcode = bestplay.hashcode; this.bestoldDuplicates.Clear(); result = bestval; } else { this.bestmove = null; this.bestmoveValue = -100000f; this.bestboard = playf; result = -10000f; } return result; }
// HREngine.Bots.MiniSimulatorNextTurn // Token: 0x060000EE RID: 238 RVA: 0x00019890 File Offset: 0x00017A90 public float doallmoves(Playfield playf, bool print = false) { bool isLethalCheck = playf.isLethalCheck; int totalboards = Settings.Instance.nextTurnTotalBoards; int maxwide = Settings.Instance.nextTurnMaxWide; int maxdeep = Settings.Instance.nextTurnDeep; bool playaround = Settings.Instance.playaround; int playaroundprob = Settings.Instance.playaroundprob; int playaroundprob2 = Settings.Instance.playaroundprob2; this.botBase = Ai.Instance.botBase; this.posmoves.Clear(); this.posmoves.Add(new Playfield(playf)); bool havedonesomething = true; List<Playfield> temp = new List<Playfield>(); int deep = 0; this.calculated = 0; Playfield bestold = null; float bestoldval = -2E+07f; while (havedonesomething) { temp.Clear(); temp.AddRange(this.posmoves); havedonesomething = false; foreach (Playfield p in temp) { bool flag = p.complete || p.ownHero.Hp <= 0; if (!flag) { List<Action> actions = this.movegen.getMoveList(p, this.usePenalityManager, this.useCutingTargets, true); foreach (Action a2 in actions) { havedonesomething = true; Playfield pf = new Playfield(p); pf.doAction(a2); bool flag2 = pf.ownHero.Hp > 0; if (flag2) { this.posmoves.Add(pf); } bool flag3 = totalboards > 0; if (flag3) { this.calculated++; } } p.endTurn(); bool flag4 = !isLethalCheck; if (flag4) { this.startEnemyTurnSim(p, this.simulateSecondTurn, false, playaround, playaroundprob, playaroundprob2); } bool flag5 = this.botBase.getPlayfieldValue(p) > bestoldval; if (flag5) { bestoldval = this.botBase.getPlayfieldValue(p); bestold = p; } this.posmoves.Remove(p); bool flag6 = this.calculated > totalboards; if (flag6) { break; } } } this.cuttingposibilities(maxwide); deep++; bool flag7 = this.calculated > totalboards; if (flag7) { break; } bool flag8 = deep >= maxdeep; if (flag8) { break; } } this.posmoves.Add(bestold); foreach (Playfield p2 in this.posmoves) { bool flag9 = !p2.complete; if (flag9) { p2.endTurn(); bool flag10 = !isLethalCheck; if (flag10) { this.startEnemyTurnSim(p2, this.simulateSecondTurn, false, playaround, playaroundprob, playaroundprob2); } } } bool flag11 = this.posmoves.Count >= 1; float result; if (flag11) { this.posmoves.Sort((Playfield a, Playfield b) => this.botBase.getPlayfieldValue(b).CompareTo(this.botBase.getPlayfieldValue(a))); Playfield bestplay = this.posmoves[0]; float bestval = this.botBase.getPlayfieldValue(bestplay); int pcount = this.posmoves.Count; for (int i = 1; i < pcount; i++) { float val = this.botBase.getPlayfieldValue(this.posmoves[i]); bool flag12 = bestval > val; if (flag12) { break; } bool flag13 = bestplay.playactions.Count <= this.posmoves[i].playactions.Count; if (!flag13) { bestplay = this.posmoves[i]; bestval = val; } } this.bestmove = bestplay.getNextAction(); this.bestmoveValue = bestval; this.bestboard = new Playfield(bestplay); result = bestval; } else { this.bestmove = null; this.bestmoveValue = -100000f; this.bestboard = playf; result = -10000f; } return result; }