用单元测试来调试SilverFish AI

[TestFixture]
    public class AiTest
    {
        [Test]
        public void Test()
        {
            Settings.Instance.LogFolderPath = @"C:
epositoryGitHubChuckLuTestHearthbuddyReleaseLogs";
            Settings.Instance.DataFolderPath =
                @"C:
epositoryGitHubChuckLuTestHearthbuddyReleaseRoutinesDefaultRoutineSilverFishData";
            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;
}
原文地址:https://www.cnblogs.com/chucklu/p/11372637.html