Exemple #1
0
        public Bot()
        {
            //crawler stuff-----------------
            OnVictory = HandleWining;
            OnLost = HandleLosing;
            OnBattleStateUpdate = HandleOnBattleStateUpdate;
            OnMulliganStateUpdate = HandleBattleMulliganPhase;
            //-----------------------------------------
            starttime = DateTime.Now;


            Settings set = Settings.Instance;
            this.sf = Silverfish.Instance;
            behave = set.setSettings();
            sf.setnewLoggFile();
            CardDB cdb = CardDB.Instance;
            if (cdb.installedWrong)
            {
                Helpfunctions.Instance.ErrorLog("cant find CardDB");
                return;
            }

            bool teststuff = false; // set to true, to run a testfile (requires test.txt file in folder where _cardDB.txt file is located)
            bool printstuff = false; // if true, the best board of the tested file is printet stepp by stepp

            Helpfunctions.Instance.ErrorLog("----------------------------");
            Helpfunctions.Instance.ErrorLog("you are running uai V" + sf.versionnumber);
            Helpfunctions.Instance.ErrorLog("----------------------------");

            if (Settings.Instance.useExternalProcess) Helpfunctions.Instance.ErrorLog("YOU USE SILVER.EXE FOR CALCULATION, MAKE SURE YOU STARTED IT!");
            if (Settings.Instance.useExternalProcess) Helpfunctions.Instance.ErrorLog("SILVER.EXE IS LOCATED IN: " + Settings.Instance.path);



            if (teststuff)//run autotester for developpers
            {
                Ai.Instance.autoTester(printstuff);
            }
            writeSettings();
        }
        public int doallmoves(Playfield playf, bool isLethalCheck)
        {
            //Helpfunctions.Instance.logg("NXTTRN" + playf.mana);
            if (botBase == null) botBase = Ai.Instance.botBase;
            bool test = false;
            this.posmoves.Clear();
            this.addToPosmoves(playf);
            bool havedonesomething = true;
            List<Playfield> temp = new List<Playfield>();
            int deep = 0;
            //Helpfunctions.Instance.logg("NXTTRN" + playf.mana + " " + posmoves.Count);
            this.calculated = 0;
            while (havedonesomething)
            {
                if (this.printNormalstuff) Helpfunctions.Instance.logg("ailoop");
                GC.Collect();
                temp.Clear();
                temp.AddRange(this.posmoves);
                havedonesomething = false;
                Playfield bestold = null;
                int bestoldval = -20000000;
                foreach (Playfield p in temp)
                {

                    if (p.complete || p.ownHeroHp <= 0)
                    {
                        continue;
                    }

                    //take a card and play it

                    if (!p.attacked)
                    {

                        List<CardDB.cardName> playedcards = new List<CardDB.cardName>();
                        foreach (Handmanager.Handcard hc in p.owncards)
                        {
                            if (this.calculated > this.totalboards) continue;
                            CardDB.Card c = hc.card;
                            //help.logg("try play crd" + c.name + " " + c.getManaCost(p) + " " + c.canplayCard(p));
                            if (playedcards.Contains(c.name)) continue; // dont play the same card in one loop
                            playedcards.Add(c.name);
                            if (c.choice)
                            {
                                if (doAllChoices(p, hc, isLethalCheck))
                                {
                                    havedonesomething = true;
                                }
                            }
                            else
                            {
                                int bestplace = p.getBestPlace(c, isLethalCheck);
                                if (hc.canplayCard(p))
                                {
                                    havedonesomething = true;
                                    List<targett> trgts = c.getTargetsForCard(p);

                                    if (isLethalCheck && (pen.DamageTargetDatabase.ContainsKey(c.name) || pen.DamageTargetSpecialDatabase.ContainsKey(c.name)))// only target enemy hero during Lethal check!
                                    {
                                        targett trg = trgts.Find(x => x.target == 200);
                                        if (trg != null)
                                        {
                                            trgts.Clear();
                                            trgts.Add(trg);
                                        }
                                        else
                                        {
                                            // no enemy hero -> enemy have taunts ->kill the taunts from left to right
                                            if (trgts.Count >= 1)
                                            {
                                                trg = trgts[0];
                                                trgts.Clear();
                                                trgts.Add(trg);
                                            }
                                        }
                                    }


                                    int cardplayPenality = 0;

                                    if (trgts.Count == 0)
                                    {


                                        if (usePenalityManager)
                                        {
                                            cardplayPenality = pen.getPlayCardPenality(c, -1, p, 0, isLethalCheck);
                                            if (cardplayPenality <= 499)
                                            {
                                                Playfield pf = new Playfield(p);
                                                havedonesomething = true;
                                                pf.playCard(hc, hc.position - 1, hc.entity, -1, -1, 0, bestplace, cardplayPenality);
                                                addToPosmoves(pf);
                                            }
                                        }
                                        else
                                        {
                                            Playfield pf = new Playfield(p);
                                            havedonesomething = true;
                                            pf.playCard(hc, hc.position - 1, hc.entity, -1, -1, 0, bestplace, cardplayPenality);
                                            addToPosmoves(pf);
                                        }


                                    }
                                    else
                                    {
                                        if (isLethalCheck)// only target enemy hero during Lethal check!
                                        {
                                            targett trg = trgts.Find(x => x.target == 200);
                                            if (trg != null)
                                            {
                                                trgts.Clear();
                                                trgts.Add(trg);
                                            }
                                        }

                                        foreach (targett trgt in trgts)
                                        {


                                            if (usePenalityManager)
                                            {
                                                cardplayPenality = pen.getPlayCardPenality(c, trgt.target, p, 0, isLethalCheck);
                                                if (cardplayPenality <= 499)
                                                {
                                                    Playfield pf = new Playfield(p);
                                                    havedonesomething = true;
                                                    pf.playCard(hc, hc.position - 1, hc.entity, trgt.target, trgt.targetEntity, 0, bestplace, cardplayPenality);
                                                    addToPosmoves(pf);
                                                }
                                            }
                                            else
                                            {
                                                Playfield pf = new Playfield(p);
                                                havedonesomething = true;
                                                pf.playCard(hc, hc.position - 1, hc.entity, trgt.target, trgt.targetEntity, 0, bestplace, cardplayPenality);
                                                addToPosmoves(pf);
                                            }

                                        }

                                    }


                                }
                            }
                        }



                        // use ability
                        /// TODO check if ready after manaup
                        if (p.ownAbilityReady && p.mana >= 2 && p.ownHeroAblility.canplayCard(p, 2))
                        {
                            if (this.calculated > this.totalboards) continue;
                            int abilityPenality = 0;

                            havedonesomething = true;
                            // if we have mage or priest, we have to target something####################################################
                            if (p.ownHeroName == HeroEnum.mage || p.ownHeroName == HeroEnum.priest)
                            {

                                List<targett> trgts = p.ownHeroAblility.getTargetsForCard(p);

                                if (isLethalCheck && (p.ownHeroName == HeroEnum.mage || (p.ownHeroName == HeroEnum.priest && (p.ownHeroAblility.name != CardDB.cardName.lesserheal || (p.ownHeroAblility.name == CardDB.cardName.lesserheal && p.auchenaiseelenpriesterin)))))// only target enemy hero during Lethal check!
                                {
                                    targett trg = trgts.Find(x => x.target == 200);
                                    if (trg != null)
                                    {
                                        trgts.Clear();
                                        trgts.Add(trg);
                                    }
                                    else
                                    {
                                        // no enemy hero -> enemy have taunts ->kill the taunts from left to right
                                        if (trgts.Count >= 1)
                                        {
                                            trg = trgts[0];
                                            trgts.Clear();
                                            trgts.Add(trg);
                                        }
                                    }
                                }

                                foreach (targett trgt in trgts)
                                {



                                    if (usePenalityManager)
                                    {
                                        abilityPenality = pen.getPlayCardPenality(p.ownHeroAblility, trgt.target, p, 0, isLethalCheck);
                                        if (abilityPenality <= 499)
                                        {
                                            Playfield pf = new Playfield(p);
                                            havedonesomething = true;
                                            pf.activateAbility(p.ownHeroAblility, trgt.target, trgt.targetEntity, abilityPenality);
                                            addToPosmoves(pf);
                                        }
                                    }
                                    else
                                    {
                                        Playfield pf = new Playfield(p);
                                        havedonesomething = true;
                                        pf.activateAbility(p.ownHeroAblility, trgt.target, trgt.targetEntity, abilityPenality);
                                        addToPosmoves(pf);
                                    }

                                }
                            }
                            else
                            {
                                // the other classes dont have to target####################################################
                                Playfield pf = new Playfield(p);

                                if (usePenalityManager)
                                {
                                    abilityPenality = pen.getPlayCardPenality(p.ownHeroAblility, -1, pf, 0, isLethalCheck);
                                    if (abilityPenality <= 499)
                                    {
                                        havedonesomething = true;
                                        pf.activateAbility(p.ownHeroAblility, -1, -1, abilityPenality);
                                        addToPosmoves(pf);
                                    }
                                }
                                else
                                {
                                    havedonesomething = true;
                                    pf.activateAbility(p.ownHeroAblility, -1, -1, abilityPenality);
                                    addToPosmoves(pf);
                                }

                            }

                        }

                    }
                    //attack with a minion

                    List<Minion> playedMinions = new List<Minion>(8);

                    foreach (Minion m in p.ownMinions)
                    {
                        if (this.calculated > this.totalboards) continue;

                        if (m.Ready && m.Angr >= 1 && !m.frozen)
                        {
                            //BEGIN:cut (double/similar) attacking minions out#####################################
                            // DONT LET SIMMILAR MINIONS ATTACK IN ONE TURN (example 3 unlesh the hounds-hounds doesnt need to simulated hole)
                            List<Minion> tempoo = new List<Minion>(playedMinions);
                            bool dontattacked = true;
                            bool isSpecial = pen.specialMinions.ContainsKey(m.name);
                            foreach (Minion mnn in tempoo)
                            {
                                // special minions are allowed to attack in silended and unsilenced state!
                                //help.logg(mnn.silenced + " " + m.silenced + " " + mnn.name + " " + m.name + " " + penman.specialMinions.ContainsKey(m.name));

                                bool otherisSpecial = pen.specialMinions.ContainsKey(mnn.name);

                                if ((!isSpecial || (isSpecial && m.silenced)) && (!otherisSpecial || (otherisSpecial && mnn.silenced))) // both are not special, if they are the same, dont add
                                {
                                    if (mnn.Angr == m.Angr && mnn.Hp == m.Hp && mnn.divineshild == m.divineshild && mnn.taunt == m.taunt && mnn.poisonous == m.poisonous) dontattacked = false;
                                    continue;
                                }

                                if (isSpecial == otherisSpecial && !m.silenced && !mnn.silenced) // same are special
                                {
                                    if (m.name != mnn.name) // different name -> take it
                                    {
                                        continue;
                                    }
                                    // same name -> test whether they are equal
                                    if (mnn.Angr == m.Angr && mnn.Hp == m.Hp && mnn.divineshild == m.divineshild && mnn.taunt == m.taunt && mnn.poisonous == m.poisonous) dontattacked = false;
                                    continue;
                                }

                            }

                            if (dontattacked)
                            {
                                playedMinions.Add(m);
                            }
                            else
                            {
                                //help.logg(m.name + " doesnt need to attack!");
                                continue;
                            }
                            //END: cut (double/similar) attacking minions out#####################################

                            //help.logg(m.name + " is going to attack!");
                            List<targett> trgts = p.getAttackTargets(true);


                            if (isLethalCheck)// only target enemy hero during Lethal check!
                            {
                                targett trg = trgts.Find(x => x.target == 200);
                                if (trg != null)
                                {
                                    trgts.Clear();
                                    trgts.Add(trg);
                                }
                                else
                                {
                                    // no enemy hero -> enemy have taunts ->kill the taunts from left to right
                                    if (trgts.Count >= 1)
                                    {
                                        trg = trgts[0];
                                        trgts.Clear();
                                        trgts.Add(trg);
                                    }
                                }
                            }
                            else
                            {
                                if (this.useCutingTargets) trgts = this.cutAttackTargets(trgts, p, true);
                            }

                            foreach (targett trgt in trgts)
                            {


                                int attackPenality = 0;

                                if (usePenalityManager)
                                {
                                    attackPenality = pen.getAttackWithMininonPenality(m, p, trgt.target, isLethalCheck);
                                    if (attackPenality <= 499)
                                    {
                                        Playfield pf = new Playfield(p);
                                        havedonesomething = true;
                                        pf.attackWithMinion(m, trgt.target, trgt.targetEntity, attackPenality);
                                        addToPosmoves(pf);
                                    }
                                }
                                else
                                {
                                    Playfield pf = new Playfield(p);
                                    havedonesomething = true;
                                    pf.attackWithMinion(m, trgt.target, trgt.targetEntity, attackPenality);
                                    addToPosmoves(pf);
                                }


                            }
                            if ((!m.stealth || isLethalCheck) && p.enemySecretCount == 0 && trgts.Count == 1 && trgts[0].target == 200)//only enemy hero is available als attack
                            {
                                break;
                            }
                        }

                    }

                    // attack with hero
                    if (p.ownHeroReady)
                    {
                        if (this.calculated > this.totalboards) continue;
                        List<targett> trgts = p.getAttackTargets(true);

                        havedonesomething = true;

                        if (isLethalCheck)// only target enemy hero during Lethal check!
                        {
                            targett trg = trgts.Find(x => x.target == 200);
                            if (trg != null)
                            {
                                trgts.Clear();
                                trgts.Add(trg);
                            }
                            else
                            {
                                // no enemy hero -> enemy have taunts ->kill the taunts from left to right
                                if (trgts.Count >= 1)
                                {
                                    trg = trgts[0];
                                    trgts.Clear();
                                    trgts.Add(trg);
                                }
                            }
                        }
                        else
                        {
                            if (this.useCutingTargets) trgts = this.cutAttackTargets(trgts, p, true);
                        }

                        foreach (targett trgt in trgts)
                        {
                            Playfield pf = new Playfield(p);
                            int heroAttackPen = 0;
                            if (usePenalityManager)
                            {
                                heroAttackPen = pen.getAttackWithHeroPenality(trgt.target, p, isLethalCheck);
                            }
                            pf.attackWithWeapon(trgt.target, trgt.targetEntity, heroAttackPen);
                            addToPosmoves(pf);
                        }
                    }

                    


                    if (isLethalCheck)
                    {
                        p.complete = true;
                    }
                    else
                    {
                        p.endTurn(this.simulateSecondTurn, this.playaround, false, this.playaroundprob, this.playaroundprob2);
                    }

                    //sort stupid stuff ouf

                    if (botBase.getPlayfieldValue(p) > bestoldval)
                    {
                        bestoldval = botBase.getPlayfieldValue(p);
                        bestold = p;
                    }
                    if (!test)
                    {
                        posmoves.Remove(p);
                    }

                    if (this.calculated > this.totalboards) break;
                }

                if (!test && bestoldval >= -10000 && bestold != null)
                {
                    this.posmoves.Add(bestold);
                }

                //Helpfunctions.Instance.loggonoff(true);
                if (this.printNormalstuff)
                {
                    int donec = 0;
                    foreach (Playfield p in posmoves)
                    {
                        if (p.complete) donec++;
                    }
                    Helpfunctions.Instance.logg("deep " + deep + " len " + this.posmoves.Count + " dones " + donec);
                }

                if (!test)
                {
                    cuttingposibilities();
                }

                if (this.printNormalstuff)
                {
                    Helpfunctions.Instance.logg("cut to len " + this.posmoves.Count);
                }
                //Helpfunctions.Instance.loggonoff(false);
                deep++;

                if (this.calculated > this.totalboards) break;
                if (deep >= this.maxdeep) break;//remove this?
            }

            foreach (Playfield p in posmoves)//temp
            {
                if (!p.complete)
                {
                    if (isLethalCheck)
                    {
                        p.complete = true;
                    }
                    else
                    {
                        p.endTurn(this.simulateSecondTurn, this.playaround, false, this.playaroundprob, this.playaroundprob2);
                    }
                }
            }
            // Helpfunctions.Instance.logg("find best ");
            if (posmoves.Count >= 1)
            {
                int bestval = int.MinValue;
                int bestanzactions = 1000;
                Playfield bestplay = posmoves[0];//temp[0]
                foreach (Playfield p in posmoves)//temp
                {
                    int val = botBase.getPlayfieldValue(p);
                    if (bestval <= val)
                    {
                        if (bestval == val && bestanzactions < p.playactions.Count) continue;
                        bestplay = p;
                        bestval = val;
                        bestanzactions = p.playactions.Count;
                    }

                }

                this.bestmove = bestplay.getNextAction();
                this.bestmoveValue = bestval;
                this.bestboard = new Playfield(bestplay);
                //Helpfunctions.Instance.logg("return");
                return bestval;
            }
            //Helpfunctions.Instance.logg("return");
            this.bestmove = null;
            this.bestmoveValue = -100000;
            this.bestboard = playf;
            return -10000;
        }
Exemple #3
0
        public bool updateEverything(Behavior botbase)
        {
            this.botbehave = "rush";
            if (botbase is BehaviorControl) this.botbehave = "control";
            this.botbehave += " " + Ai.Instance.maxwide;
            if (Ai.Instance.secondTurnAmount>0)
            {
                if (Ai.Instance.nextMoveGuess.mana == -100)
                {
                    Ai.Instance.updateTwoTurnSim();
                }
                this.botbehave += " twoturnsim " + Ai.Instance.mainTurnSimulator.dirtyTwoTurnSim;
            }
            if (Ai.Instance.playaround)
            {
                this.botbehave += " playaround";
                this.botbehave += " " + Ai.Instance.playaroundprob + " " + Ai.Instance.playaroundprob2;
            }
            HRPlayer ownPlayer = HRPlayer.GetLocalPlayer();
            HRPlayer enemyPlayer = HRPlayer.GetEnemyPlayer();
            ownPlayerController = ownPlayer.GetHero().GetControllerId();//ownPlayer.GetHero().GetControllerId()


            // create hero + minion data
            getHerostuff();
            getMinions();
            getHandcards();
            getDecks();

            // send ai the data:
            Hrtprozis.Instance.clearAll();
            Handmanager.Instance.clearAll();

            Hrtprozis.Instance.setOwnPlayer(ownPlayerController);
            Handmanager.Instance.setOwnPlayer(ownPlayerController);

            Hrtprozis.Instance.updatePlayer(this.ownMaxMana, this.currentMana, this.cardsPlayedThisTurn, this.numMinionsPlayedThisTurn, this.ueberladung, ownPlayer.GetHero().GetEntityId(), enemyPlayer.GetHero().GetEntityId());
            Hrtprozis.Instance.updateSecretStuff(this.ownSecretList, this.enemySecretCount);

            Hrtprozis.Instance.updateOwnHero(this.ownHeroWeapon, this.heroWeaponAttack, this.heroWeaponDurability, this.heroname,  this.heroAbility, this.ownAbilityisReady, this.ownHero);
            Hrtprozis.Instance.updateEnemyHero(this.enemyHeroWeapon, this.enemyWeaponAttack, this.enemyWeaponDurability, this.enemyHeroname, this.enemyMaxMana, this.enemyAbility, this.enemyHero);

            Hrtprozis.Instance.updateMinions(this.ownMinions, this.enemyMinions);
            Handmanager.Instance.setHandcards(this.handCards, this.anzcards, this.enemyAnzCards);

            Hrtprozis.Instance.updateFatigueStats(this.ownDecksize, this.ownHeroFatigue, this.enemyDecksize, this.enemyHeroFatigue);

            //learnmode :D

            Playfield p = new Playfield();
            if (lastpf != null)
            {
                if (lastpf.isEqualf(p))
                {
                    return false;
                }
                lastpf = p;
            }
            else
            {
                lastpf = p;
            }


            // print data
            printstuff();
            Hrtprozis.Instance.printHero();
            Hrtprozis.Instance.printOwnMinions();
            Hrtprozis.Instance.printEnemyMinions();
            Handmanager.Instance.printcards();
            Probabilitymaker.Instance.printTurnGraveYard();

            // calculate stuff
            Helpfunctions.Instance.ErrorLog("calculating stuff... " + DateTime.Now.ToString("HH:mm:ss.ffff"));
            Ai.Instance.dosomethingclever(botbase);
            Helpfunctions.Instance.ErrorLog("calculating ended! " + DateTime.Now.ToString("HH:mm:ss.ffff"));
            return true;
        }
Exemple #4
0
        public void autoTester(Behavior bbase, bool printstuff)
        {
            help.logg("simulating board ");

            BoardTester bt = new BoardTester();
            this.botBase = bbase;
            hp.printHero();
            hp.printOwnMinions();
            hp.printEnemyMinions();
            hm.printcards();
            //calculate the stuff
            posmoves.Clear();
            posmoves.Add(new Playfield());
            posmoves[0].sEnemTurn = this.simulateEnemyTurn;
            foreach (Playfield p in this.posmoves)
            {
                p.printBoard();
            }
            help.logg("ownminionscount " + posmoves[0].ownMinions.Count);
            help.logg("owncardscount " + posmoves[0].owncards.Count);

            foreach (var item in this.posmoves[0].owncards)
            {
                help.logg("card " + item.card.name + " is playable :" + item.canplayCard(posmoves[0]) + " cost/mana: " + item.manacost + "/" + posmoves[0].mana);
            }
            help.logg("ability " + posmoves[0].ownHeroAblility.card.name + " is playable :" + posmoves[0].ownHeroAblility.card.canplayCard(posmoves[0], 2) + " cost/mana: " + posmoves[0].ownHeroAblility.card.getManaCost(posmoves[0], 2) + "/" + posmoves[0].mana);

            // lethalcheck + normal
            DateTime strt = DateTime.Now;
            doallmoves(false, true);
            help.logg("calculated " + (DateTime.Now - strt).TotalSeconds);
            if (bestmoveValue < 10000)
            {
                posmoves.Clear();
                posmoves.Add(new Playfield());
                posmoves[0].sEnemTurn = this.simulateEnemyTurn;
                strt = DateTime.Now;
                doallmoves(false, false);
                help.logg("calculated " + (DateTime.Now - strt).TotalSeconds);
            }

            this.mainTurnSimulator.printPosmoves();

            help.logg("bestfield");
            bestboard.printBoard();
            if (printstuff) simmulateWholeTurn();
        }
Exemple #5
0
        public bool updateEverything(Behavior botbase, bool runExtern = false, bool passiveWait = false)
        {
            this.updateBehaveString(botbase);

            HRPlayer ownPlayer = HRPlayer.GetLocalPlayer();
            HRPlayer enemyPlayer = HRPlayer.GetEnemyPlayer();
            ownPlayerController = ownPlayer.GetHero().GetControllerId();//ownPlayer.GetHero().GetControllerId()


            // create hero + minion data
            getHerostuff();
            getMinions();
            getHandcards();
            getDecks();

            // send ai the data:
            Hrtprozis.Instance.clearAll();
            Handmanager.Instance.clearAll();

            Hrtprozis.Instance.setOwnPlayer(ownPlayerController);
            Handmanager.Instance.setOwnPlayer(ownPlayerController);

            this.numOptionPlayedThisTurn = 0;
            this.numOptionPlayedThisTurn += this.cardsPlayedThisTurn + this.ownHero.numAttacksThisTurn;
            foreach (Minion m in this.ownMinions)
            {
                if (m.Hp >= 1) this.numOptionPlayedThisTurn += m.numAttacksThisTurn;
            }

            

            Hrtprozis.Instance.updatePlayer(this.ownMaxMana, this.currentMana, this.cardsPlayedThisTurn, this.numMinionsPlayedThisTurn, this.numOptionPlayedThisTurn, this.ueberladung, ownPlayer.GetHero().GetEntityId(), enemyPlayer.GetHero().GetEntityId(), this.numberMinionsDiedThisTurn, this.ownCurrentOverload, this.enemyOverload);
            Hrtprozis.Instance.setPlayereffects(this.ownDragonConsort, this.enemyDragonConsort, this.ownLoathebs, this.enemyLoathebs, this.ownMillhouse, this.enemyMillhouse, this.ownKirintor, this.ownPrepa);
            Hrtprozis.Instance.updateSecretStuff(this.ownSecretList, this.enemySecretCount);

            Hrtprozis.Instance.updateOwnHero(this.ownHeroWeapon, this.heroWeaponAttack, this.heroWeaponDurability, this.heroname, this.heroAbility, this.ownAbilityisReady, this.ownHero);
            Hrtprozis.Instance.updateEnemyHero(this.enemyHeroWeapon, this.enemyWeaponAttack, this.enemyWeaponDurability, this.enemyHeroname, this.enemyMaxMana, this.enemyAbility, this.enemyHero);

            Hrtprozis.Instance.updateMinions(this.ownMinions, this.enemyMinions);
            Handmanager.Instance.setHandcards(this.handCards, this.anzcards, this.enemyAnzCards);

            Hrtprozis.Instance.updateFatigueStats(this.ownDecksize, this.ownHeroFatigue, this.enemyDecksize, this.enemyHeroFatigue);

            Probabilitymaker.Instance.getEnemySecretGuesses(this.enemySecretList, Hrtprozis.Instance.heroNametoEnum(this.enemyHeroname));

            //learnmode :D

            Playfield p = new Playfield();



            if (lastpf != null)
            {
                if (lastpf.isEqualf(p))
                {
                    return false;
                }

                //board changed we update secrets!
                //if(Ai.Instance.nextMoveGuess!=null) Probabilitymaker.Instance.updateSecretList(Ai.Instance.nextMoveGuess.enemySecretList);
                Probabilitymaker.Instance.updateSecretList(p, lastpf);
                lastpf = p;
            }
            else
            {
                lastpf = p;
            }

            p = new Playfield();//secrets have updated :D
            // calculate stuff
            Helpfunctions.Instance.ErrorLog("calculating stuff... " + DateTime.Now.ToString("HH:mm:ss.ffff"));
            if (runExtern)
            {
                Helpfunctions.Instance.logg("recalc-check###########");
                //p.printBoard();
                //Ai.Instance.nextMoveGuess.printBoard();
                if (p.isEqual(Ai.Instance.nextMoveGuess, true))
                {

                    printstuff(false);
                    Ai.Instance.doNextCalcedMove();

                }
                else
                {
                    printstuff(true);
                    readActionFile(passiveWait);
                }
            }
            else
            {
                printstuff(false);
                Ai.Instance.dosomethingclever(botbase);
            }

            Helpfunctions.Instance.ErrorLog("calculating ended! " + DateTime.Now.ToString("HH:mm:ss.ffff"));

            return true;
        }
        public float doallmoves(Playfield playf, bool isLethalCheck)
        {
            //Helpfunctions.Instance.logg("NXTTRN" + playf.mana);
            if (botBase == null) botBase = Ai.Instance.botBase;
            bool test = false;
            this.posmoves.Clear();
            this.twoturnfields.Clear();
            this.addToPosmoves(playf);
            bool havedonesomething = true;
            List<Playfield> temp = new List<Playfield>();
            int deep = 0;
            //Helpfunctions.Instance.logg("NXTTRN" + playf.mana + " " + posmoves.Count);
            this.calculated = 0;
            while (havedonesomething)
            {
                if (this.printNormalstuff) Helpfunctions.Instance.logg("ailoop");
                GC.Collect();
                temp.Clear();
                temp.AddRange(this.posmoves);
                havedonesomething = false;
                Playfield bestold = null;
                float bestoldval = -20000000;
                foreach (Playfield p in temp)
                {

                    if (p.complete || p.ownHero.Hp <= 0)
                    {
                        continue;
                    }

                    //gernerate actions and play them!
                    List<Action> actions = movegen.getMoveList(p, isLethalCheck, usePenalityManager, useCutingTargets);
                    foreach (Action a in actions)
                    {
                        //if (deep == 0 && a.actionType == actionEnum.playcard) Helpfunctions.Instance.ErrorLog("play " + a.card.card.name);
                        havedonesomething = true;
                        Playfield pf = new Playfield(p);
                        pf.doAction(a);
                        addToPosmoves(pf);
                    }

                    // end the turn of the current board (only if its not a lethalcheck)
                    if (isLethalCheck)
                    {
                        p.complete = true;
                    }
                    else
                    {
                        p.endTurn(this.simulateSecondTurn, this.playaround, false, this.playaroundprob, this.playaroundprob2);
                    }

                    //sort stupid stuff ouf

                    if (botBase.getPlayfieldValue(p) > bestoldval)
                    {
                        bestoldval = botBase.getPlayfieldValue(p);
                        bestold = p;
                    }
                    if (!test)
                    {
                        posmoves.Remove(p);
                    }

                    if (this.calculated > this.totalboards) break;
                }

                if (!test && bestoldval >= -10000 && bestold != null)
                {
                    this.posmoves.Add(bestold);
                }

                //Helpfunctions.Instance.loggonoff(true);
                if (this.printNormalstuff)
                {
                    int donec = 0;
                    foreach (Playfield p in posmoves)
                    {
                        if (p.complete) donec++;
                    }
                    Helpfunctions.Instance.logg("deep " + deep + " len " + this.posmoves.Count + " dones " + donec);
                }

                if (!test)
                {
                    cuttingposibilities();
                }

                if (this.printNormalstuff)
                {
                    Helpfunctions.Instance.logg("cut to len " + this.posmoves.Count);
                }
                //Helpfunctions.Instance.loggonoff(false);
                deep++;

                if (this.calculated > this.totalboards) break;
                if (deep >= this.maxdeep) break;//remove this?
            }

            foreach (Playfield p in posmoves)//temp
            {
                if (!p.complete)
                {
                    if (isLethalCheck)
                    {
                        p.complete = true;
                    }
                    else
                    {
                        p.endTurn(this.simulateSecondTurn, this.playaround, false, this.playaroundprob, this.playaroundprob2);
                    }
                }
            }

            // search the best play...........................................................

            //do dirtytwoturnsim first :D
            if (!isLethalCheck) doDirtyTwoTurnsim();

            if (!isLethalCheck) this.dirtyTwoTurnSim /= 2;

            // Helpfunctions.Instance.logg("find best ");
            if (posmoves.Count >= 1)
            {
                float bestval = int.MinValue;
                int bestanzactions = 1000;
                Playfield bestplay = posmoves[0];//temp[0]
                foreach (Playfield p in posmoves)//temp
                {
                    float val = botBase.getPlayfieldValue(p);
                    if (bestval <= val)
                    {
                        if (bestval == val && bestanzactions < p.playactions.Count) continue;
                        bestplay = p;
                        bestval = val;
                        bestanzactions = p.playactions.Count;
                    }

                }

                this.bestmove = bestplay.getNextAction();
                this.bestmoveValue = bestval;
                this.bestboard = new Playfield(bestplay);
                //Helpfunctions.Instance.logg("return");
                return bestval;
            }
            //Helpfunctions.Instance.logg("return");
            this.bestmove = null;
            this.bestmoveValue = -100000;
            this.bestboard = playf;
            return -10000;
        }
        public bool updateEverything(Behavior botbase, bool runExtern = false, bool passiveWait = false)
        {
            this.updateBehaveString(botbase);


            ownPlayerController = TritonHs.OurHero.ControllerId;


            // create hero + minion data
            getHerostuff();

            //small fix for not knowing when to mulligan:
            if (ownMaxMana == 1 && currentMana == 1 && numMinionsPlayedThisTurn == 0 && cardsPlayedThisTurn == 0)
            {
                setnewLoggFile();
                getHerostuff();
            }

            getMinions();
            getHandcards();
            getDecks();

            // send ai the data:
            Hrtprozis.Instance.clearAll();
            Handmanager.Instance.clearAll();

            Hrtprozis.Instance.setOwnPlayer(ownPlayerController);
            Handmanager.Instance.setOwnPlayer(ownPlayerController);

            this.numOptionPlayedThisTurn = 0;
            this.numOptionPlayedThisTurn += this.cardsPlayedThisTurn + this.ownHero.numAttacksThisTurn;
            foreach (Minion m in this.ownMinions)
            {
                if (m.Hp >= 1) this.numOptionPlayedThisTurn += m.numAttacksThisTurn;
            }

            Hrtprozis.Instance.updatePlayer(this.ownMaxMana, this.currentMana, this.cardsPlayedThisTurn, this.numMinionsPlayedThisTurn, this.numOptionPlayedThisTurn, this.ueberladung, ownHero.entitiyID, enemyHero.entitiyID, this.numberMinionsDiedThisTurn, this.ownCurrentOverload, this.enemyOverload, this.heroPowerUsesThisTurn, this.lockandload);
            Hrtprozis.Instance.setPlayereffects(this.ownDragonConsort, this.enemyDragonConsort, this.ownLoathebs, this.enemyLoathebs, this.ownMillhouse, this.enemyMillhouse, this.ownKirintor, this.ownPrepa, this.ownsabo, this.enemysabo, this.ownFenciCoaches);
            Hrtprozis.Instance.updateSecretStuff(this.ownSecretList, this.enemySecretCount);


            Hrtprozis.Instance.updateOwnHero(this.ownHeroWeapon, this.heroWeaponAttack, this.heroWeaponDurability, this.heroname, this.heroAbility, this.ownAbilityisReady, this.ownHero, this.ownHeroPowerUsesThisGame);
            Hrtprozis.Instance.updateEnemyHero(this.enemyHeroWeapon, this.enemyWeaponAttack, this.enemyWeaponDurability, this.enemyHeroname, this.enemyMaxMana, this.enemyAbility, this.enemyHero, this.enemyHeroPowerUsesThisGame);

            Hrtprozis.Instance.updateMinions(this.ownMinions, this.enemyMinions);
            Handmanager.Instance.setHandcards(this.handCards, this.anzcards, this.enemyAnzCards);

            Hrtprozis.Instance.updateFatigueStats(this.ownDecksize, this.ownHeroFatigue, this.enemyDecksize,
                this.enemyHeroFatigue);

            Probabilitymaker.Instance.getEnemySecretGuesses(this.enemySecretList,
                Hrtprozis.Instance.heroNametoEnum(this.enemyHeroname));
            //learnmode :D

            Playfield p = new Playfield();

            if (lastpf != null)
            {
                if (lastpf.isEqualf(p))
                {
                    return false;
                }

                //board changed we update secrets!
                //if(Ai.Instance.nextMoveGuess!=null) Probabilitymaker.Instance.updateSecretList(Ai.Instance.nextMoveGuess.enemySecretList);
                Probabilitymaker.Instance.updateSecretList(p, lastpf);
                lastpf = p;
            }
            else
            {
                lastpf = p;
            }

            p = new Playfield(); //secrets have updated :D
            // calculate stuff
            Helpfunctions.Instance.ErrorLog("calculating stuff... " + DateTime.Now.ToString("HH:mm:ss.ffff"));
            if (runExtern)
            {
                Helpfunctions.Instance.logg("recalc-check###########");
                if (p.isEqual(Ai.Instance.nextMoveGuess, true))
                {
                    printstuff(p, false);
                    Ai.Instance.doNextCalcedMove();
                }
                else
                {
                    printstuff(p, true);
                    readActionFile(passiveWait);
                }
            }
            else
            {
                // Drew: This prevents the freeze during AI updates, but no API functions may be called
                // during this time!
                using (TritonHs.Memory.ReleaseFrame(true))
                {
                    printstuff(p, false);
                    //Helpfunctions.Instance.logg("middle calculations: " + DateTime.Now.ToString("HH:mm:ss.ffff"));
                    Ai.Instance.dosomethingclever(botbase);    
                }
            }

            Helpfunctions.Instance.ErrorLog("calculating ended! " + DateTime.Now.ToString("HH:mm:ss.ffff"));
            return true;
        }
        public Behavior behave = new BehaviorControl();//change this to new BehaviorRush() for rush mode
        //Behavior behave = new BehaviorRush();

        public DefaultRoutine()
        {
            // Global rules. Never keep a 4+ minion, unless it's Bolvar Fordragon (paladin).
            _mulliganRules.Add(new Tuple<string, string>("True", "card.Entity.Cost >= 4 and card.Entity.Id != \"GVG_063\""));

            // Never keep Tracking.
            _mulliganRules.Add(new Tuple<string, string>("mulliganData.UserClass == TAG_CLASS.HUNTER", "card.Entity.Id == \"DS1_184\""));

            // Example rule for self.
            //_mulliganRules.Add(new Tuple<string, string>("mulliganData.UserClass == TAG_CLASS.MAGE", "card.Cost >= 5"));

            // Example rule for opponents.
            //_mulliganRules.Add(new Tuple<string, string>("mulliganData.OpponentClass == TAG_CLASS.MAGE", "card.Cost >= 3"));

            // Example rule for matchups.
            //_mulliganRules.Add(new Tuple<string, string>("mulliganData.userClass == TAG_CLASS.HUNTER && mulliganData.OpponentClass == TAG_CLASS.DRUID", "card.Cost >= 2"));

            bool concede = false;

            HREngine.Bots.Settings set = HREngine.Bots.Settings.Instance;
            Silverfish sfff = Silverfish.Instance;
            behave = set.setSettings();

            /* // play with these settings###################################
            int enfacehp = 15;  // hp of enemy when your hero is allowed to attack the enemy face with his weapon
            int mxwde = 3000;   // numer of boards which are taken to the next deep-lvl
            int twotsamount = 0;          // number of boards where the next turn is simulated
            bool enemySecondTurnSim = false; // if he simulates the next players-turn, he also simulates the enemys respons

            bool playaround = false;  // play around some enemys aoe-spells
            // these two parameters(probs) are value between 0 and 100 (0 <= Your_Value <= 100)
            //!!! Correct description:
            int playaroundprob = 50;    // probability where the enemy NOT plays the aoe-spell: 100 - enemy never plays aoe-spell, 0 - always uses
            int playaroundprob2 = 80;   // probability where the enemy plays the aoe-spell, and your minions will survive: 100 - always survive, 0 - never(survival depends on their real HP)

            int amountBoardsInEnemyTurnSim = 40;
            int amountBoardsInEnemyTurnSimSecondStepp = 200;
            int amountBoardsInEnemySecondTurnSim = 20;

            int nextturnsimDeep = 10;
            int nextturnsimMaxWidth = 20;
            int nexttunsimMaxBoards = 160;
            int ImprovedCalculations = 1;   // 0 - disabled(for old PCs), 1 - enabled

            bool secrets = true; // playing arround enemys secrets

            int alpha = 50; // weight of the second turn in calculation (0<= alpha <= 100)

            HREngine.Bots.Settings.Instance.simulatePlacement = false;  //rudiment!!! set this true, and ai will simulate all placements, whether you have a alpha/flametongue/argus

            //###########################################################
            */

            

            if (HREngine.Bots.Settings.Instance.useExternalProcess) Helpfunctions.Instance.ErrorLog("YOU USE SILVER.EXE FOR CALCULATION, MAKE SURE YOU STARTED IT!");
            if (HREngine.Bots.Settings.Instance.useExternalProcess) Helpfunctions.Instance.ErrorLog("SILVER.EXE IS LOCATED IN: " + HREngine.Bots.Settings.Instance.path);
            
            try{

            if (HREngine.Bots.Settings.Instance.useExternalProcess)
            {
                System.Diagnostics.Process[] pname = System.Diagnostics.Process.GetProcessesByName("Silver");
                string directory = HREngine.Bots.Settings.Instance.path + "Silver.exe";
                directory = Path.GetFullPath(directory);
                Helpfunctions.Instance.ErrorLog("searching silver.exe in " + directory);

                bool hasToOpen = true;
                
                if (pname.Length >= 1)
                {
                    
                    for (int i = 0; i < pname.Length; i++)
                    {
                        
                        string fullPath = pname[i].Modules[0].FileName;
                        if (fullPath == directory) hasToOpen = false;
                    }
                }

                if (hasToOpen)
                {
                    System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(directory);
                    startInfo.WorkingDirectory = HREngine.Bots.Settings.Instance.path;
                    System.Diagnostics.Process.Start(startInfo);
                }

                System.Threading.Thread.Sleep(500);
            }
            }
            catch (Exception e)
            {
                Helpfunctions.Instance.ErrorLog("SILVER.EXE IS MISSING, bot will not work");
                Helpfunctions.Instance.ErrorLog(e.ToString());
                return;
            }

            CardDB cdb = CardDB.Instance;
            if (cdb.installedWrong)
            {
                Helpfunctions.Instance.ErrorLog("cant find CardDB");
                return;
            }

            Silverfish.Instance.setnewLoggFile();
            
           
            /*Helpfunctions.Instance.ErrorLog("set enemy-face-hp to: " + enfacehp);
            ComboBreaker.Instance.attackFaceHP = enfacehp;

            Ai.Instance.setMaxWide(mxwde);
            Helpfunctions.Instance.ErrorLog("set maxwide to: " + mxwde);

            Ai.Instance.setTwoTurnSimulation(false, twotsamount);
            Helpfunctions.Instance.ErrorLog("calculate the second turn of the " + twotsamount + " best boards");
            if (twotsamount >= 1)
            {
                //Ai.Instance.nextTurnSimulator.setEnemyTurnsim(enemySecondTurnSim);
                HREngine.Bots.Settings.Instance.simEnemySecondTurn = enemySecondTurnSim;
                if (enemySecondTurnSim) Helpfunctions.Instance.ErrorLog("simulates the enemy turn on your second turn");
            }

            if (secrets)
            {

                HREngine.Bots.Settings.Instance.useSecretsPlayArround = secrets;
                Helpfunctions.Instance.ErrorLog("playing arround secrets is " + secrets);
            }


            if (playaround)
            {
                HREngine.Bots.Settings.Instance.playarround = playaround;
                HREngine.Bots.Settings.Instance.playaroundprob = playaroundprob;
                HREngine.Bots.Settings.Instance.playaroundprob2 = playaroundprob2;
                Ai.Instance.setPlayAround();
                Helpfunctions.Instance.ErrorLog("activated playaround");
            }

            HREngine.Bots.Settings.Instance.setWeights(alpha);
             
            HREngine.Bots.Settings.Instance.enemyTurnMaxWide = amountBoardsInEnemyTurnSim;
            HREngine.Bots.Settings.Instance.enemySecondTurnMaxWide = amountBoardsInEnemySecondTurnSim;

            HREngine.Bots.Settings.Instance.nextTurnDeep = nextturnsimDeep;
            HREngine.Bots.Settings.Instance.nextTurnMaxWide = nextturnsimMaxWidth;
            HREngine.Bots.Settings.Instance.nextTurnTotalBoards = nexttunsimMaxBoards;
            //HREngine.Bots.Settings.Instance.ImprovedCalculations = ImprovedCalculations;
             
             */


            bool teststuff = false;
            // set to true, to run a testfile (requires test.txt file in filder where _cardDB.txt file is located)
            bool printstuff = false; // if true, the best board of the tested file is printet stepp by stepp
            
            

            Helpfunctions.Instance.ErrorLog("----------------------------");
            Helpfunctions.Instance.ErrorLog("you are running uai V" + Silverfish.Instance.versionnumber);
            Helpfunctions.Instance.ErrorLog("----------------------------");

            if (teststuff)
            {
                Ai.Instance.autoTester(printstuff);
            }
        }
Exemple #9
0
        public void simulateEnemysTurn(Playfield rootfield, bool simulateTwoTurns, bool playaround, bool print, int pprob, int pprob2)
        {
            if (botBase == null)
            {
                botBase = Ai.Instance.botBase;
            }

            bool havedonesomething = true;

            posmoves.Clear();
            if (print)
            {
                Helpfunctions.Instance.ErrorLog("board at enemyturn start-----------------------------");
                rootfield.value = botBase.getPlayfieldValue(rootfield);
                rootfield.printBoard();
            }
            posmoves.Add(new Playfield(rootfield));
            //posmoves[0].prepareNextTurn(false);
            List <Playfield> temp = new List <Playfield>();
            int deep     = 0;
            int enemMana = rootfield.enemyMaxMana;

            //get rid of cursed! ?
            if (posmoves[0].anzEnemyCursed >= 1)
            {
                int curseds = posmoves[0].anzEnemyCursed;

                for (int ii = curseds; ii > 0; ii--)
                {
                    if (enemMana >= 2)
                    {
                        enemMana -= 2;
                        posmoves[0].anzEnemyCursed--;
                    }
                }
            }

            if (print)
            {
                Console.WriteLine("enemMana " + enemMana);
            }

            //playing aoe-effects if activated (and we didnt play loatheb)
            if (playaround && rootfield.anzOwnLoatheb == 0)
            {
                float oldval = botBase.getPlayfieldValueEnemy(posmoves[0]);
                posmoves[0].value = int.MinValue;
                enemMana          = posmoves[0].EnemyCardPlaying(rootfield.enemyHeroName, enemMana, rootfield.enemyAnzCards, pprob, pprob2);
                float newval = botBase.getPlayfieldValueEnemy(posmoves[0]);
                posmoves[0].value = int.MinValue;
                posmoves[0].enemyAnzCards--;
                posmoves[0].triggerCardsChanged(false);
                posmoves[0].mana = enemMana;
                if (oldval < newval)
                {
                    posmoves.Clear();
                    posmoves.Add(new Playfield(rootfield));
                }
            }



            //play ability!

            if (posmoves[0].enemyAbilityReady && enemMana >= 2 && posmoves[0].enemyHeroAblility.card.canplayCard(posmoves[0], 0) && rootfield.anzOwnSaboteur == 0)
            {
                int abilityPenality = 0;

                havedonesomething = true;
                // if we have mage or priest or hunter, we have to target something####################################################


                if (penmanager.TargetAbilitysDatabase.ContainsKey(posmoves[0].enemyHeroAblility.card.cardIDenum))
                {
                    List <Minion> trgts = posmoves[0].enemyHeroAblility.card.getTargetsForCard(posmoves[0], false, false);
                    foreach (Minion trgt in trgts)
                    {
                        //if (trgt.isHero) continue;//do play his ability in basics
                        Action    a  = new Action(actionEnum.useHeroPower, posmoves[0].enemyHeroAblility, null, 0, trgt, abilityPenality, 0);
                        Playfield pf = new Playfield(posmoves[0]);
                        pf.doAction(a);
                        posmoves.Add(pf);
                    }
                }
                else
                {
                    bool hasinspire = false;
                    foreach (Minion minie in rootfield.enemyMinions)
                    {
                        if (minie.handcard.card.Inspire)
                        {
                            hasinspire = true;
                        }
                    }
                    // the other classes dont have to target####################################################
                    if ((rootfield.enemyHeroName == HeroEnum.thief && rootfield.enemyWeaponDurability == 0) || rootfield.enemyHeroName != HeroEnum.thief || hasinspire)
                    {
                        Action    a  = new Action(actionEnum.useHeroPower, posmoves[0].enemyHeroAblility, null, 0, null, abilityPenality, 0);
                        Playfield pf = new Playfield(posmoves[0]);
                        pf.doAction(a);
                        posmoves.Add(pf);
                    }
                }
            }

            //kill to strong minions with low hp

            /*if (enemMana >= 4)
             * {
             *  foreach (Playfield pf in posmoves)
             *  {
             *      Minion lowest = null;
             *      foreach (Minion m in pf.ownMinions)
             *      {
             *          if (m.Angr >= 4 && m.Hp <= 2 && m.Hp>=1)
             *          {
             *              pf.minionGetDamageOrHeal(m, 100);
             *              if (lowest == null || lowest.Angr <= m.Angr)
             *              {
             *              //    lowest = m;
             *              }
             *          }
             *      }
             *      pf.doDmgTriggers();
             *      if (lowest != null)
             *      {
             *          pf.minionGetDamageOrHeal(lowest, lowest.Hp);
             *          pf.doDmgTriggers();
             *      }
             *  }
             * }*/

            foreach (Minion m in posmoves[0].enemyMinions)
            {
                if (m.Angr == 0)
                {
                    continue;
                }
                m.numAttacksThisTurn = 0;
                m.playedThisTurn     = false;
                m.updateReadyness();
            }

            //might be more than just one
            foreach (Playfield pipi in posmoves)
            {
                doSomeBasicEnemyAi(pipi);
            }

            int boardcount = 0;
            //movegen...

            int       i       = 0;
            int       count   = 0;
            Playfield p       = null;
            Playfield bestold = null;

            while (havedonesomething)
            {
                temp.Clear();
                temp.AddRange(posmoves);
                havedonesomething = false;
                float bestoldval = int.MaxValue;

                //foreach (Playfield p in temp)
                count = temp.Count;
                for (i = 0; i < count; i++)
                {
                    p = temp[i];
                    if (p.complete)
                    {
                        continue;
                    }

                    List <Action> actions = movegen.getEnemyMoveList(p, false, true, true, 1);// 1 for not using ability moves

                    foreach (Action a in actions)
                    {
                        havedonesomething = true;
                        Playfield pf = new Playfield(p);
                        pf.doAction(a);
                        posmoves.Add(pf);

                        /*if (print)
                         * {
                         *  a.print();
                         * }*/
                        boardcount++;
                    }

                    p.endEnemyTurn();
                    //p.guessingHeroHP = rootfield.guessingHeroHP;
                    if (botBase.getPlayfieldValueEnemy(p) < bestoldval) // want the best enemy-play-> worst for us
                    {
                        bestoldval = botBase.getPlayfieldValueEnemy(p);
                        bestold    = p;
                    }
                    posmoves.Remove(p);

                    if (boardcount >= maxwide)
                    {
                        break;
                    }
                }

                if (bestoldval <= 10000 && bestold != null)
                {
                    posmoves.Add(bestold);
                }

                cuttingPosibilitiesET();

                deep++;
                if (boardcount >= maxwide)
                {
                    break;
                }
            }

            //foreach (Playfield p in posmoves)
            count = posmoves.Count;
            for (i = 0; i < count; i++)
            {
                if (!posmoves[i].complete)
                {
                    posmoves[i].endEnemyTurn();
                }
            }

            float     bestval  = int.MaxValue;
            Playfield bestplay = rootfield;// posmoves[0];

            //foreach (Playfield p in posmoves)
            count = posmoves.Count;
            for (i = 0; i < count; i++)
            {
                p = posmoves[i];
                //p.guessingHeroHP = rootfield.guessingHeroHP;
                float val = botBase.getPlayfieldValueEnemy(p);
                if (bestval > val)// we search the worst value
                {
                    bestplay = p;
                    bestval  = val;
                }

                /*if (print)
                 * {
                 *  Helpfunctions.Instance.ErrorLog(""+val);
                 *  p.printBoard();
                 * }*/
            }
            if (print)
            {
                Helpfunctions.Instance.ErrorLog("best enemy board----------------------------------");
                bestplay.printBoard();
            }
            rootfield.value = bestplay.value;
            if (simulateTwoTurns && bestplay.ownHero.Hp > 0 && bestplay.value > -1000)
            {
                bestplay.prepareNextTurn(true);
                rootfield.value = Settings.Instance.firstweight * bestval + Settings.Instance.secondweight * Ai.Instance.nextTurnSimulator[this.thread].doallmoves(bestplay, false, print);
            }
        }
Exemple #10
0
        public float doallmoves(Playfield playf, bool print = false)
        {
            //todo only one time!
            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;

            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 = -20000000;

            while (havedonesomething)
            {
                //GC.Collect();
                temp.Clear();
                temp.AddRange(this.posmoves);
                havedonesomething = false;
                foreach (Playfield p in temp)
                {
                    if (p.complete || p.ownHero.HealthPoints <= 0)
                    {
                        continue;
                    }

                    List <Action> actions = movegen.GetMoveList(p, usePenalityManager, useCutingTargets, true);
                    foreach (Action a in actions)
                    {
                        havedonesomething = true;
                        Playfield pf = new Playfield(p);
                        pf.doAction(a);
                        if (pf.ownHero.HealthPoints > 0)
                        {
                            this.posmoves.Add(pf);
                        }
                        if (totalboards > 0)
                        {
                            this.calculated++;
                        }
                    }


                    p.endTurn();

                    if (!isLethalCheck)
                    {
                        this.startEnemyTurnSim(p, this.simulateSecondTurn, false, playaround, playaroundprob, playaroundprob2);
                    }

                    //sort stupid stuff ouf

                    if (botBase.getPlayfieldValue(p) > bestoldval)
                    {
                        bestoldval = botBase.getPlayfieldValue(p);
                        bestold    = p;
                    }
                    posmoves.Remove(p);

                    if (this.calculated > totalboards)
                    {
                        break;
                    }
                }
                cuttingposibilities(maxwide);

                deep++;

                if (this.calculated > totalboards)
                {
                    break;
                }
                if (deep >= maxdeep)
                {
                    break;
                }
            }

            posmoves.Add(bestold);
            foreach (Playfield p in posmoves)
            {
                if (!p.complete)
                {
                    p.endTurn();
                    if (!isLethalCheck)
                    {
                        this.startEnemyTurnSim(p, this.simulateSecondTurn, false, playaround, playaroundprob, playaroundprob2);
                    }
                }
            }
            // find best

            if (posmoves.Count >= 1)
            {
                posmoves.Sort((a, b) => botBase.getPlayfieldValue(b).CompareTo(botBase.getPlayfieldValue(a)));

                Playfield bestplay = posmoves[0];
                float     bestval  = botBase.getPlayfieldValue(bestplay);
                int       pcount   = posmoves.Count;
                for (int i = 1; i < pcount; i++)
                {
                    float val = botBase.getPlayfieldValue(posmoves[i]);
                    if (bestval > val)
                    {
                        break;
                    }
                    if (bestplay.playactions.Count <= posmoves[i].playactions.Count)
                    {
                        continue;                                                              //priority to the minimum acts
                    }
                    bestplay = posmoves[i];
                    bestval  = val;
                }
                this.bestmove      = bestplay.getNextAction();
                this.bestmoveValue = bestval;
                this.bestboard     = new Playfield(bestplay);
                return(bestval);
            }
            this.bestmove      = null;
            this.bestmoveValue = -100000;
            this.bestboard     = playf;
            return(-10000);
        }
Exemple #11
0
        public bool getHoldList(MulliganData mulliganData, Behavior behave)
        {
            cards.Clear();
            readRules(behave.BehaviorName());
            if (!mulliganRulesLoaded)
            {
                return(false);
            }
            if (!(mulliganData.Cards.Count == 3 || mulliganData.Cards.Count == 4))
            {
                Helpfunctions.Instance.ErrorLog("[Mulligan] Mulligan is not used, since it got number of cards: " + cards.Count.ToString());
                return(false);
            }

            Log.InfoFormat("[开局留牌] 应用这个 {0} 规则:", behave.BehaviorName());

            for (var i = 0; i < mulliganData.Cards.Count; i++)
            {
                cards.Add(new CardIDEntity(mulliganData.Cards[i].Entity.Id, i));
            }
            HeroEnum ownHeroClass   = Hrtprozis.Instance.heroTAG_CLASSstringToEnum(mulliganData.UserClass.ToString());
            HeroEnum enemyHeroClass = Hrtprozis.Instance.heroTAG_CLASSstringToEnum(mulliganData.OpponentClass.ToString());

            int    manaRule    = 4;
            string MullRuleKey = getMullRuleKey(CardDB.cardIDEnum.None, ownHeroClass, enemyHeroClass, 1);

            if (MulliganRules.ContainsKey(MullRuleKey))
            {
                string[] temp = MulliganRules[MullRuleKey].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                manaRule = Convert.ToInt32(temp[2]);
            }
            else
            {
                MullRuleKey = getMullRuleKey(CardDB.cardIDEnum.None, ownHeroClass, HeroEnum.None, 1);
                if (MulliganRules.ContainsKey(MullRuleKey))
                {
                    string[] temp = MulliganRules[MullRuleKey].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                    manaRule = Convert.ToInt32(temp[2]);
                }
            }

            CardIDEntity Coin = new CardIDEntity("GAME_005", -888);

            if (cards.Count == 4)
            {
                cards.Add(Coin);                   //we have a coin
            }
            foreach (CardIDEntity CardIDEntityC in cards)
            {
                CardDB.Card c = CardDB.Instance.getCardDataFromID(CardIDEntityC.id);
                if (CardIDEntityC.hold == 0 && CardIDEntityC.holdByRule == 0)
                {
                    if (c.cost < manaRule)
                    {
                        CardIDEntityC.holdByManarule = 2;
                        CardIDEntityC.holdReason     = joinSomeTxt("保留这些卡牌因为法力值消耗:", c.cost.ToString(), " 小于预定值:", manaRule.ToString());
                    }
                    else
                    {
                        CardIDEntityC.holdByManarule = -2;
                        CardIDEntityC.holdReason     = joinSomeTxt("弃掉这些卡牌因为法力值消耗:", c.cost.ToString(), " 没有小于预定值:", manaRule.ToString());
                    }
                }

                int  allowedQuantitySimple = 0;
                int  allowedQuantityExtra  = 0;
                bool hasRuleClassSimple    = false;

                bool   hasRule           = false;
                string MullRuleKeySimple = getMullRuleKey(c.cardIDenum, ownHeroClass, enemyHeroClass, 0); //Simple key for Class enemy
                if (MulliganRules.ContainsKey(MullRuleKeySimple))
                {
                    hasRule = true; hasRuleClassSimple = true;
                }
                else
                {
                    MullRuleKeySimple = getMullRuleKey(c.cardIDenum, ownHeroClass, HeroEnum.None, 0); //Simple key for ALL enemy
                    if (MulliganRules.ContainsKey(MullRuleKeySimple))
                    {
                        hasRule = true;
                    }
                }
                if (hasRule)
                {
                    string[] val = MulliganRules[MullRuleKeySimple].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                    allowedQuantitySimple = ((val[1] == "2") ? 2 : 1) * ((val[0] == "Hold") ? 1 : -1);
                }

                hasRule = false;
                string MullRuleKeyExtra = getMullRuleKey(c.cardIDenum, ownHeroClass, enemyHeroClass, 1); //Extra key for Class enemy
                if (MulliganRules.ContainsKey(MullRuleKeyExtra))
                {
                    hasRule = true;
                }
                else if (!hasRuleClassSimple)
                {
                    MullRuleKeyExtra = getMullRuleKey(c.cardIDenum, ownHeroClass, HeroEnum.None, 1); //Extra key for ALL enemy
                    if (MulliganRules.ContainsKey(MullRuleKeyExtra))
                    {
                        hasRule = true;
                    }
                }
                if (hasRule)
                {
                    string[] val = MulliganRules[MullRuleKeyExtra].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                    allowedQuantityExtra = ((val[1] == "2") ? 2 : 1) * ((val[0] == "Hold") ? 1 : -1);
                }

                //superimpose Class rules to All rules
                bool useHold        = false;
                bool useDiscard     = false;
                bool useHoldRule    = false;
                bool useDiscardRule = false;

                if (allowedQuantitySimple != 0 && allowedQuantitySimple != allowedQuantityExtra)
                {
                    if (allowedQuantitySimple > 0)
                    {
                        useHold = true;
                    }
                    else
                    {
                        useDiscard = true;
                    }
                }
                if (allowedQuantityExtra != 0)
                {
                    if (allowedQuantityExtra < 0)
                    {
                        useDiscardRule = true;
                    }
                    else
                    {
                        useHoldRule = true;
                    }
                }

                //apply the rules
                string[] MullRuleValueExtra = new string[3];
                if (allowedQuantityExtra != 0)
                {
                    MullRuleValueExtra = MulliganRules[MullRuleKeyExtra].Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                }
                if (useDiscardRule)
                {
                    if (MullRuleValueExtra[2] != "/")
                    {
                        string[] addedCards = MullRuleValueExtra[2].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
                        MulliganRulesManual.Clear();
                        foreach (string s in addedCards)
                        {
                            MulliganRulesManual.Add(CardDB.Instance.cardIdstringToEnum(s), "");
                        }

                        foreach (CardIDEntity tmp in cards)
                        {
                            if (CardIDEntityC.entitiy == tmp.entitiy)
                            {
                                continue;
                            }
                            if (MulliganRulesManual.ContainsKey(tmp.id))
                            {
                                CardIDEntityC.holdByRule = -2;
                                CardIDEntityC.holdReason = joinSomeTxt("符合规则而弃掉: ", getClearRule(MullRuleKeyExtra));
                                break;
                            }
                        }
                    }
                }
                else if (useDiscard)
                {
                    CardIDEntityC.hold       = -2;
                    CardIDEntityC.holdReason = joinSomeTxt("符合规则而弃掉: ", getClearRule(MullRuleKeySimple));
                }

                if (useHoldRule)
                {
                    if (CardIDEntityC.holdByRule == 0)
                    {
                        string[] addedCards = MullRuleValueExtra[2].Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
                        MulliganRulesManual.Clear();
                        foreach (string s in addedCards)
                        {
                            MulliganRulesManual.Add(CardDB.Instance.cardIdstringToEnum(s), "");
                        }

                        bool foundFreeCard = false;
                        for (int i = 0; i < cards.Count; i++)
                        {
                            if (CardIDEntityC.entitiy == cards[i].entitiy)
                            {
                                continue;
                            }
                            if (MulliganRulesManual.ContainsKey(cards[i].id))
                            {
                                CardIDEntityC.holdByRule = 2;
                                CardIDEntityC.holdReason = joinSomeTxt("符合规则而保留: ", getClearRule(MullRuleKeyExtra));
                                if (cards[i].holdByRule < 0)
                                {
                                    for (int j = i; j < cards.Count; j++)
                                    {
                                        if (CardIDEntityC.entitiy == cards[j].entitiy)
                                        {
                                            continue;
                                        }
                                        if (MulliganRulesManual.ContainsKey(cards[j].id))
                                        {
                                            if (cards[j].holdByRule < 0)
                                            {
                                                continue;
                                            }
                                            foundFreeCard       = true;
                                            cards[j].holdByRule = 2;
                                            cards[j].holdReason = joinSomeTxt("符合规则而保留: ", getClearRule(MullRuleKeyExtra));
                                            break;
                                        }
                                    }
                                    if (!foundFreeCard)
                                    {
                                        foundFreeCard       = true;
                                        cards[i].holdByRule = 2;
                                        cards[i].holdReason = joinSomeTxt("符合规则而保留: ", getClearRule(MullRuleKeyExtra));
                                        break;
                                    }
                                }
                                else
                                {
                                    foundFreeCard       = true;
                                    cards[i].holdByRule = 2;
                                    cards[i].holdReason = joinSomeTxt("符合规则而保留: ", getClearRule(MullRuleKeyExtra));
                                }

                                if (allowedQuantityExtra == 1)
                                {
                                    foreach (CardIDEntity tmp in cards)
                                    {
                                        if (tmp.entitiy == CardIDEntityC.entitiy)
                                        {
                                            continue;
                                        }
                                        if (tmp.id == CardIDEntityC.id)
                                        {
                                            tmp.holdByRule = -2;
                                            tmp.holdReason = joinSomeTxt("符合规则而弃掉: ", getClearRule(MullRuleKeyExtra));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if (useHold && CardIDEntityC.holdByRule != -2)
                {
                    if (CardIDEntityC.hold == 0)
                    {
                        CardIDEntityC.hold       = 2;
                        CardIDEntityC.holdReason = joinSomeTxt("符合规则而保留: ", getClearRule(MullRuleKeySimple));
                        if (allowedQuantitySimple == 1)
                        {
                            CardIDEntityC.hold = 1;
                            foreach (CardIDEntity tmp in cards)
                            {
                                if (tmp.entitiy == CardIDEntityC.entitiy)
                                {
                                    continue;
                                }
                                if (tmp.id == CardIDEntityC.id)
                                {
                                    tmp.hold       = -2;
                                    tmp.holdReason = joinSomeTxt("discard Second card by rule: ", getClearRule(MullRuleKeySimple));
                                }
                            }
                        }
                    }
                }
            }

            if (cards.Count == 5)
            {
                cards.Remove(Coin);
            }

            foreach (CardIDEntity c in cards)
            {
                if (c.holdByRule == 0)
                {
                    if (c.hold == 0)
                    {
                        c.holdByRule = c.holdByManarule;
                    }
                    else
                    {
                        c.holdByRule = c.hold;
                    }
                }
            }

            for (var i = 0; i < mulliganData.Cards.Count; i++)
            {
                mulliganData.Mulligans[i] = (cards[i].holdByRule > 0) ? false : true;
                Log.InfoFormat("[开局留牌] {0} {1}.", mulliganData.Cards[i].Entity.Name, cards[i].holdReason);
            }
            return(true);
        }
Exemple #12
0
        public float doallmoves(Playfield playf, bool isLethalCheck)
        {
            movegen.isLethalCheck = isLethalCheck;
            print = playf.print;
            this.isLethalCheck = isLethalCheck;
            enoughCalculations = false;
            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;

            bestoldval = -20000000;
            while (havedonesomething)
            {
                if (this.printNormalstuff)
                {
                    Helpfunctions.Instance.logg("ailoop");
                }
                GC.Collect();
                temp.Clear();
                temp.AddRange(this.posmoves);
                this.posmoves.Clear();
                havedonesomething  = false;
                threadnumberGlobal = 0;

                if (print)
                {
                    startEnemyTurnSimThread(temp, 0, temp.Count);
                }
                else
                {
                    Parallel.ForEach(Partitioner.Create(0, temp.Count),
                                     range =>
                    {
                        startEnemyTurnSimThread(temp, range.Item1, range.Item2);
                    });
                }

                foreach (Playfield p in temp)
                {
                    if (this.totalboards > 0)
                    {
                        this.calculated += p.nextPlayfields.Count;
                    }
                    if (this.calculated <= this.totalboards)
                    {
                        this.posmoves.AddRange(p.nextPlayfields);
                        p.nextPlayfields.Clear();
                    }

                    //get the best Playfield
                    float pVal = botBase.getPlayfieldValue(p);
                    if (pVal > bestoldval)
                    {
                        bestoldval = pVal;
                        bestold    = p;
                    }
                    else if (pVal == bestoldval)
                    {
                        bestoldDuplicates.Add(p);
                    }
                }
                if (isLethalCheck && bestoldval >= 10000)
                {
                    this.posmoves.Clear();
                }
                if (this.posmoves.Count > 0)
                {
                    havedonesomething = true;
                }

                if (this.printNormalstuff)
                {
                    int donec = 0;
                    foreach (Playfield p in posmoves)
                    {
                        if (p.complete)
                        {
                            donec++;
                        }
                    }
                    Helpfunctions.Instance.logg("deep " + deep + " len " + this.posmoves.Count + " dones " + donec);
                }

                cuttingposibilities(isLethalCheck);

                if (this.printNormalstuff)
                {
                    Helpfunctions.Instance.logg("cut to len " + this.posmoves.Count);
                }
                deep++;
                temp.Clear();

                if (this.calculated > this.totalboards)
                {
                    enoughCalculations = true;
                }
                if (deep >= this.maxdeep)
                {
                    enoughCalculations = true;
                }
            }

            if (this.dirtyTwoTurnSim > 0 && !twoturnfields.Contains(bestold))
            {
                twoturnfields.Add(bestold);
            }
            this.posmoves.Clear();
            this.posmoves.Add(bestold);
            this.posmoves.AddRange(bestoldDuplicates);

            // search the best play...........................................................
            //do dirtytwoturnsim first :D
            if (!isLethalCheck && bestoldval < 10000)
            {
                doDirtyTwoTurnsim();
            }

            if (posmoves.Count >= 1)
            {
                posmoves.Sort((a, b) => botBase.getPlayfieldValue(b).CompareTo(botBase.getPlayfieldValue(a)));
                Playfield bestplay = posmoves[0];
                float     bestval  = botBase.getPlayfieldValue(bestplay);
                int       pcount   = posmoves.Count;
                for (int i = 1; i < pcount; i++)
                {
                    float val = botBase.getPlayfieldValue(posmoves[i]);
                    if (bestval > val)
                    {
                        break;
                    }
                    if (posmoves[i].cardsPlayedThisTurn > bestplay.cardsPlayedThisTurn)
                    {
                        continue;
                    }
                    else if (posmoves[i].cardsPlayedThisTurn == bestplay.cardsPlayedThisTurn)
                    {
                        if (bestplay.optionsPlayedThisTurn > posmoves[i].optionsPlayedThisTurn)
                        {
                            continue;
                        }
                        else if (bestplay.optionsPlayedThisTurn == posmoves[i].optionsPlayedThisTurn && bestplay.enemyHero.Hp <= posmoves[i].enemyHero.Hp)
                        {
                            continue;
                        }
                    }
                    bestplay = posmoves[i];
                    bestval  = val;
                }
                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;
                bestoldDuplicates.Clear();
                return(bestval);
            }
            this.bestmove      = null;
            this.bestmoveValue = -100000;
            this.bestboard     = playf;

            return(-10000);
        }
Exemple #13
0
        public bool updateEverything(Behavior botbase, bool quequeActions, bool runExtern = false, bool passiveWait = false, bool nodruidchoice=true)
        {
            quequeActions = false;
            Helpfunctions.Instance.ErrorLog("updateEverything");

            this.updateBehaveString(botbase);

            ownPlayerController = TritonHs.OurHero.ControllerId;


            // create hero + minion data
            getHerostuff();

            //small fix for not knowing when to mulligan:
            if (ownMaxMana == 1 && currentMana == 1 && numMinionsPlayedThisTurn == 0 && cardsPlayedThisTurn == 0)
            {
                setnewLoggFile();
                getHerostuff();
            }

            getMinions();
            getHandcards(nodruidchoice);
            getDecks();
            correctSpellpower();
            // send ai the data:
            Hrtprozis.Instance.clearAll();
            Handmanager.Instance.clearAll();

            Hrtprozis.Instance.setOwnPlayer(ownPlayerController);
            Handmanager.Instance.setOwnPlayer(ownPlayerController);

            this.numOptionPlayedThisTurn = 0;
            this.numOptionPlayedThisTurn += this.cardsPlayedThisTurn + this.ownHero.numAttacksThisTurn;
            foreach (Minion m in this.ownMinions)
            {
                if (m.Hp >= 1) this.numOptionPlayedThisTurn += m.numAttacksThisTurn;
            }

            Hrtprozis.Instance.updatePlayer(this.ownMaxMana, this.currentMana, this.cardsPlayedThisTurn, this.numMinionsPlayedThisTurn, this.numOptionPlayedThisTurn, this.ueberladung, ownHero.entitiyID, enemyHero.entitiyID, this.numberMinionsDiedThisTurn, this.ownCurrentOverload, this.enemyOverload, this.heroPowerUsesThisTurn,this.lockandload);
            Hrtprozis.Instance.setPlayereffects(this.ownDragonConsort, this.enemyDragonConsort, this.ownLoathebs, this.enemyLoathebs, this.ownMillhouse, this.enemyMillhouse, this.ownKirintor, this.ownPrepa, this.ownsabo, this.enemysabo, this.ownFenciCoaches, this.enemyCursedCardsInHand);
            Hrtprozis.Instance.updateSecretStuff(this.ownSecretList, this.enemySecretCount);


            Hrtprozis.Instance.updateOwnHero(this.ownHeroWeapon, this.heroWeaponAttack, this.heroWeaponDurability, this.heroname, this.heroAbility, this.ownAbilityisReady, this.ownHero, this.ownHeroPowerUsesThisGame);
            Hrtprozis.Instance.updateEnemyHero(this.enemyHeroWeapon, this.enemyWeaponAttack, this.enemyWeaponDurability, this.enemyHeroname, this.enemyMaxMana, this.enemyAbility, this.enemyHero, this.enemyHeroPowerUsesThisGame);

            Hrtprozis.Instance.updateMinions(this.ownMinions, this.enemyMinions);
            Handmanager.Instance.setHandcards(this.handCards, this.anzcards, this.enemyAnzCards, this.choiceCards);

            Hrtprozis.Instance.updateFatigueStats(this.ownDecksize, this.ownHeroFatigue, this.enemyDecksize, this.enemyHeroFatigue);

            Probabilitymaker.Instance.getEnemySecretGuesses(this.enemySecretList, Hrtprozis.Instance.heroNametoEnum(this.enemyHeroname));

            //learnmode :D

            Playfield p = new Playfield();


            if (lastpf != null)
            {
                if (lastpf.isEqualf(p))
                {
                    return false;
                }

                //board changed we update secrets!
                //if(Ai.Instance.nextMoveGuess!=null) Probabilitymaker.Instance.updateSecretList(Ai.Instance.nextMoveGuess.enemySecretList);
                Probabilitymaker.Instance.updateSecretList(p, lastpf);
            }


            lastpf = p;
            p = new Playfield();//secrets have updated :D
            // calculate stuff

            /*foreach (Handmanager.Handcard hc in p.owncards)
            {
                Helpfunctions.Instance.ErrorLog("hc playfield" + hc.manacost + " " + hc.getManaCost(p));
            }*/

            /*if (quequeActions)
            {
                // Detect errors in HearthRanger execution of our last set of actions and try to fix it so we don't
                // have to re-calculate the entire turn.
                Bot currentBot = (Bot)rangerbot;
                if (currentBot.numActionsSent > currentBot.numExecsReceived && !p.isEqualf(Ai.Instance.nextMoveGuess))
                {
                    Helpfunctions.Instance.ErrorLog("HR action queue did not complete!");
                    Helpfunctions.Instance.logg("board state out-of-sync due to action queue!");

                    if (Ai.Instance.restoreBestMoves(p, currentBot.queuedMoveGuesses))
                    {
                        Helpfunctions.Instance.logg("rolled back state to replay queued actions.");
                        Helpfunctions.Instance.ErrorLog("#queue-rollback#");
                    }
                }
            }*/


            Helpfunctions.Instance.ErrorLog("calculating stuff... " + DateTime.Now.ToString("HH:mm:ss.ffff"));
            
            if (runExtern)
            {
                Helpfunctions.Instance.logg("recalc-check###########");
                //p.printBoard();
                //Ai.Instance.nextMoveGuess.printBoard();
                if (p.isEqual(Ai.Instance.nextMoveGuess, true))
                {

                    printstuff(p, false);
                    Ai.Instance.doNextCalcedMove();

                }
                else
                {
                    printstuff(p, true);
                    readActionFile(passiveWait);
                }
            }
            else
            {
                using (TritonHs.Memory.ReleaseFrame(true))
                {
                    printstuff(p, false);
                    Ai.Instance.dosomethingclever(botbase);
                }
            }

            Helpfunctions.Instance.ErrorLog("calculating ended! " + DateTime.Now.ToString("HH:mm:ss.ffff"));

            return true;
        }
Exemple #14
0
 private void updateBehaveString(Behavior botbase)
 {
     this.botbehave = "rush";
     if (botbase is BehaviorControl) this.botbehave = "control";
     this.botbehave += " " + Ai.Instance.maxwide;
     if (Ai.Instance.secondTurnAmount > 0)
     {
         if (Ai.Instance.nextMoveGuess.mana == -100)
         {
             Ai.Instance.updateTwoTurnSim();
         }
         this.botbehave += " twoturnsim " + Ai.Instance.mainTurnSimulator.dirtyTwoTurnSim;
     }
     if (Ai.Instance.playaround)
     {
         this.botbehave += " playaround";
         this.botbehave += " " + Ai.Instance.playaroundprob + " " + Ai.Instance.playaroundprob2;
     }
     if (Ai.Instance.nextTurnSimulator.doEnemySecondTurn)
     {
         this.botbehave += " simEnemy2Turn";
     }
 }
Exemple #15
0
        //private void startEnemyTurnSim(Playfield p, bool simulateTwoTurns, bool print, bool playaround, int playaroundprob, int playaroundprob2)
        //{
        //    if (p.ownHero.Hp >= 1 && p.enemyHero.Hp>=1)
        //    {
        //        //simulateEnemysTurn(simulateTwoTurns, playaround, print, pprob, pprob2);
        //        p.prepareNextTurn(p.isOwnTurn);
        //        //Helpfunctions.Instance.ErrorLog("tc " + p.turnCounter);
        //        Ai.Instance.enemySecondTurnSim[this.thread].simulateEnemysTurn(p, simulateTwoTurns, playaround, print, playaroundprob, playaroundprob2);
        //        /*
        //        if (p.turnCounter >= 2)
        //            Ai.Instance.enemySecondTurnSim.simulateEnemysTurn(p, simulateTwoTurns, playaround, print, playaroundprob, playaroundprob2);
        //        else
        //            Ai.Instance.enemyTurnSim.simulateEnemysTurn(p, simulateTwoTurns, playaround, print, playaroundprob, playaroundprob2);
        //        */
        //    }
        //    p.complete = true;
        //}


        public float doallmoves(Playfield playf, bool isLethalCheck, bool print = false)
        {
            //todo only one time!
            this.doEnemySecondTurn = Settings.Instance.simEnemySecondTurn;
            int  totalboards     = Settings.Instance.nextTurnTotalBoards;
            int  maxwide         = Settings.Instance.nextTurnMaxWide;
            int  maxdeep         = Settings.Instance.nextTurnDeep;
            bool playaround      = Settings.Instance.playarround;
            int  playaroundprob  = Settings.Instance.playaroundprob;
            int  playaroundprob2 = Settings.Instance.playaroundprob2;


            //Helpfunctions.Instance.logg("NXTTRN" + playf.mana);
            if (botBase == null)
            {
                botBase = Ai.Instance.botBase;
            }
            bool test = false;

            this.posmoves.Clear();
            this.addToPosmoves(playf, totalboards);
            bool             havedonesomething = true;
            List <Playfield> temp = new List <Playfield>();
            int deep = 0;

            //Helpfunctions.Instance.logg("NXTTRN" + playf.mana + " " + posmoves.Count);
            this.calculated = 0;
            Playfield bestold = null;

            while (havedonesomething)
            {
                //if (this.printNormalstuff) Helpfunctions.Instance.logg("ailoop");
                //GC.Collect();
                temp.Clear();
                temp.AddRange(this.posmoves);
                havedonesomething = false;
                float bestoldval = -20000000;
                foreach (Playfield p in temp)
                {
                    if (p.complete || p.ownHero.Hp <= 0)
                    {
                        continue;
                    }

                    List <Action> actions = movegen.getMoveList(p, isLethalCheck, usePenalityManager, useCutingTargets);
                    foreach (Action a in actions)
                    {
                        havedonesomething = true;
                        Playfield pf = new Playfield(p);
                        pf.doAction(a);
                        addToPosmoves(pf, totalboards);
                    }


                    if (isLethalCheck)
                    {
                        p.complete = true;
                    }
                    else
                    {
                        p.sEnemTurn = this.doEnemySecondTurn;
                        p.endTurn(this.simulateSecondTurn, playaround, false, playaroundprob, playaroundprob2);
                        //this.startEnemyTurnSim(p, this.simulateSecondTurn, false, playaround, playaroundprob, playaroundprob2);
                    }

                    //sort stupid stuff ouf

                    if (botBase.getPlayfieldValue(p) > bestoldval)
                    {
                        bestoldval = botBase.getPlayfieldValue(p);
                        bestold    = p;
                    }
                    if (!test)
                    {
                        posmoves.Remove(p);
                    }

                    if (this.calculated > totalboards)
                    {
                        break;
                    }
                }

                if (!test && bestoldval >= -10000 && bestold != null)
                {
                    this.posmoves.Add(bestold);
                }

                //Helpfunctions.Instance.loggonoff(true);

                /*if (this.printNormalstuff)
                 * {
                 *  int donec = 0;
                 *  foreach (Playfield p in posmoves)
                 *  {
                 *      if (p.complete) donec++;
                 *  }
                 *  Helpfunctions.Instance.logg("deep " + deep + " len " + this.posmoves.Count + " dones " + donec);
                 * }*/

                if (!test)
                {
                    cuttingposibilities(maxwide);
                }

                //if (this.printNormalstuff) Helpfunctions.Instance.logg("cut to len " + this.posmoves.Count);
                //Helpfunctions.Instance.loggonoff(false);
                deep++;

                if (this.calculated > totalboards)
                {
                    break;
                }
                if (deep >= maxdeep)
                {
                    break;                 //remove this?
                }
            }

            foreach (Playfield p in posmoves)//temp
            {
                if (!p.complete)
                {
                    if (isLethalCheck)
                    {
                        p.complete = true;
                    }
                    else
                    {
                        p.sEnemTurn = this.doEnemySecondTurn;
                        p.endTurn(this.simulateSecondTurn, playaround, false, playaroundprob, playaroundprob2);
                        //this.startEnemyTurnSim(p, this.simulateSecondTurn, false, playaround, playaroundprob, playaroundprob2);
                    }
                }
            }
            // Helpfunctions.Instance.logg("find best ");
            if (posmoves.Count >= 1)
            {
                float     bestval        = int.MinValue;
                int       bestanzactions = 1000;
                Playfield bestplay       = posmoves[0]; //temp[0]
                foreach (Playfield p in posmoves)       //temp
                {
                    float val = botBase.getPlayfieldValue(p);
                    if (bestval <= val)
                    {
                        if (bestval == val && bestanzactions < p.playactions.Count)
                        {
                            continue;
                        }
                        bestplay       = p;
                        bestval        = val;
                        bestanzactions = p.playactions.Count;
                    }
                }
                this.bestboard = new Playfield(bestplay);

                if (print)
                {
                    Helpfunctions.Instance.ErrorLog("best board after your second turn (value included enemy second turn)----------");
                    bestplay.printBoard();
                    bestplay.value = int.MinValue;
                    //bestplay.sEnemTurn = this.doEnemySecondTurn;
                    //Ai.Instance.enemySecondTurnSim[this.thread].simulateEnemysTurn(bestplay, false, playaround, false, playaroundprob, playaroundprob2);
                    //Ai.Instance.enemySecondTurnSim.simulateEnemysTurn(bestplay, false, false, true, 100, 100); //dont play arround in enemys second turn
                }
                this.bestmove      = bestplay.getNextAction();
                this.bestmoveValue = bestval;
                this.bestboard     = new Playfield(bestplay);
                //Helpfunctions.Instance.logg("return");
                return(bestval);
            }
            //Helpfunctions.Instance.logg("return");
            this.bestmove      = null;
            this.bestmoveValue = -100000;
            this.bestboard     = playf;
            return(-10000);
        }
        /// <summary> The routine start callback. Do any initialization here. </summary>
        public void Start()
        {
            GameEventManager.NewGame += GameEventManagerOnNewGame;
            GameEventManager.GameOver += GameEventManagerOnGameOver;
            GameEventManager.QuestUpdate += GameEventManagerOnQuestUpdate;
            GameEventManager.ArenaRewards += GameEventManagerOnArenaRewards;

            foreach (var tuple in _mulliganRules)
            {
                Exception ex;
                if (
                    !VerifyCondition(tuple.Item1, new List<string> {"mulliganData"}, out ex))
                {
                    Log.ErrorFormat("[Start] There is an error with a mulligan execution condition [{1}]: {0}.", ex,
                        tuple.Item1);
                    BotManager.Stop();
                }

                if (
                    !VerifyCondition(tuple.Item2, new List<string> {"mulliganData", "card"},
                        out ex))
                {
                    Log.ErrorFormat("[Start] There is an error with a mulligan card condition [{1}]: {0}.", ex,
                        tuple.Item2);
                    BotManager.Stop();
                }
            }

            //set behaviour
            if (DefaultRoutineSettings.Instance.BotBehaviour == TAG_MODE.CONTROL)
            {
                behave = new BehaviorControl();
            }
            if (DefaultRoutineSettings.Instance.BotBehaviour == TAG_MODE.RUSH)
            {
                behave = new BehaviorRush();
            }
            if (DefaultRoutineSettings.Instance.BotBehaviour == TAG_MODE.FACE)
            {
                behave = new BehaviorFace();
            }
            if (DefaultRoutineSettings.Instance.BotBehaviour == TAG_MODE.TEST)
            {
                behave = new BehaviorMana();
            }
             //Helpfunctions.Instance.ErrorLog("start");

            
        }
Exemple #17
0
        public float doallmoves(Playfield playf, bool isLethalCheck)
        {
            //Helpfunctions.Instance.logg("NXTTRN" + playf.mana);
            if (botBase == null)
            {
                botBase = Ai.Instance.botBase;
            }
            bool test = false;

            this.posmoves.Clear();
            this.twoturnfields.Clear();
            this.addToPosmoves(playf);
            bool             havedonesomething = true;
            List <Playfield> temp = new List <Playfield>();
            int deep = 0;

            //Helpfunctions.Instance.logg("NXTTRN" + playf.mana + " " + posmoves.Count);
            this.calculated = 0;
            Helpfunctions.Instance.logg("Calculating... ");//
            while (havedonesomething)
            {
                //if (this.printNormalstuff)Helpfunctions.Instance.logg("ailoop");
                GC.Collect();
                temp.Clear();
                temp.AddRange(this.posmoves);
                havedonesomething = false;
                Playfield bestold    = null;
                float     bestoldval = -20000000;
                foreach (Playfield p in temp)
                {
                    if (p.complete || p.ownHero.Hp <= 0)
                    {
                        continue;
                    }

                    //gernerate actions and play them!
                    List <Action> actions = movegen.getMoveList(p, isLethalCheck, usePenalityManager, useCutingTargets);
                    foreach (Action a in actions)
                    {
                        //if (deep == 0 && a.actionType == actionEnum.attackWithMinion) Helpfunctions.Instance.ErrorLog("play " + a.own.entitiyID + " -> " + a.target.entitiyID);
                        havedonesomething = true;
                        Playfield pf = new Playfield(p);
                        pf.doAction(a);

                        /*if (deep == 1)
                         * {
                         *  Helpfunctions.Instance.ErrorLog("do action...");
                         *  a.print(false);
                         *  pf.printBoard();
                         * }*/
                        addToPosmoves(pf);
                    }

                    // end the turn of the current board (only if its not a lethalcheck)
                    if (isLethalCheck)
                    {
                        p.complete = true;
                    }
                    else
                    {
                        //end turn of enemy
                        p.endTurn(this.simulateSecondTurn, this.playaround, false, this.playaroundprob, this.playaroundprob2);
                        //simulate the enemys response
                        this.startEnemyTurnSim(p, this.simulateSecondTurn, false);
                    }

                    //sort stupid stuff ouf
                    float newPlayfieldValue = botBase.getPlayfieldValue(p);
                    if (newPlayfieldValue > bestoldval)
                    {
                        bestoldval = newPlayfieldValue;
                        bestold    = p;
                    }
                    if (!test)
                    {
                        posmoves.Remove(p);
                    }

                    if (this.calculated > this.totalboards)
                    {
                        break;
                    }
                }

                if (!test && bestoldval >= -10000 && bestold != null)
                {
                    this.posmoves.Add(bestold);
                }

                //Helpfunctions.Instance.loggonoff(true);
                if (this.printNormalstuff)
                {
                    int donec = 0;
                    foreach (Playfield p in posmoves)
                    {
                        if (p.complete)
                        {
                            donec++;
                        }
                    }
                    Helpfunctions.Instance.logg("deep " + deep + " len " + this.posmoves.Count + " dones " + donec);
                }

                if (!test)
                {
                    cuttingposibilities();
                }

                if (this.printNormalstuff)
                {
                    Helpfunctions.Instance.logg("cut to len " + this.posmoves.Count);
                }
                //Helpfunctions.Instance.loggonoff(false);
                deep++;

                if (this.calculated > this.totalboards)
                {
                    break;
                }
                if (deep >= this.maxdeep)
                {
                    break;                      //remove this?
                }
            }

            foreach (Playfield p in posmoves)//temp
            {
                if (!p.complete)
                {
                    if (isLethalCheck)
                    {
                        p.complete = true;
                    }
                    else
                    {
                        p.endTurn(this.simulateSecondTurn, this.playaround, false, this.playaroundprob, this.playaroundprob2);
                        this.startEnemyTurnSim(p, this.simulateSecondTurn, false);
                    }
                }
            }

            // search the best play...........................................................

            //do dirtytwoturnsim first :D
            if (!isLethalCheck)
            {
                doDirtyTwoTurnsim();
            }

            if (!isLethalCheck)
            {
                this.dirtyTwoTurnSim /= 2;
            }

            // Helpfunctions.Instance.logg("find best ");
            if (posmoves.Count >= 1)
            {
                float     bestval        = int.MinValue;
                int       bestanzactions = 1000;
                Playfield bestplay       = posmoves[0]; //temp[0]
                foreach (Playfield p in posmoves)       //temp
                {
                    float val = botBase.getPlayfieldValue(p);
                    if (bestval <= val)
                    {
                        if (bestval == val && bestanzactions <= p.playactions.Count)
                        {
                            continue;
                        }
                        bestplay       = p;
                        bestval        = val;
                        bestanzactions = p.playactions.Count;
                    }
                }
                this.bestmove      = bestplay.getNextAction();
                this.bestmoveValue = bestval;
                this.bestboard     = new Playfield(bestplay);
                //Helpfunctions.Instance.logg("return");
                return(bestval);
            }
            //Helpfunctions.Instance.logg("return");
            this.bestmove      = null;
            this.bestmoveValue = -100000;
            this.bestboard     = playf;
            return(-10000);
        }
Exemple #18
0
       public Bot()
       {
           
           behave = this.getBotBehave();
           OnVictory = HandleWining;
           OnLost = HandleLosing;
           OnBattleStateUpdate = HandleOnBattleStateUpdate;
           OnMulliganStateUpdate = HandleBattleMulliganPhase;
           starttime = DateTime.Now;
           bool concede = false;
           bool writeToSingleFile = false;

           try
           {
               this.learnmode = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.wwuaid") == "true") ? true : false;
               if (this.learnmode)
               {
                   Helpfunctions.Instance.ErrorLog("Learn mode is ON");
               }
           }
           catch
           {
               Helpfunctions.Instance.ErrorLog("a wild error occurrs! cant read the settings...");
           }
           try
           {
               concede = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.autoconcede") == "true") ? true : false;
               writeToSingleFile = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.singleLog") == "true") ? true : false;
           }
           catch
           {
               Helpfunctions.Instance.ErrorLog("a wild error occurrs! cant read the settings...");
           }
           try
           {
               this.concedeLvl = Convert.ToInt32((HRSettings.Get.ReadSetting("silverfish.xml", "uai.concedelvl")));
               if (this.concedeLvl >= 20) this.concedeLvl = 20;
               if (concede)
               {
                   Helpfunctions.Instance.ErrorLog("concede till rank " + concedeLvl);
               }
           }
           catch
           {
               Helpfunctions.Instance.ErrorLog("cant read your concede-Lvl");
           }

           try
           {
               this.stopAfterWins = Convert.ToInt32((HRSettings.Get.ReadSetting("silverfish.xml", "uai.stopwin")));
               if (this.stopAfterWins <= 0) this.stopAfterWins = 10000;
               Helpfunctions.Instance.ErrorLog("stop after " + stopAfterWins + " wins");
           }
           catch
           {
               Helpfunctions.Instance.ErrorLog("cant read stop after # of wins");
           }

           try
           {
               this.enemyConcede = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.enemyconcede") == "true") ? true : false;
               if (this.enemyConcede) Helpfunctions.Instance.ErrorLog("concede whether enemy has lethal");
           }
           catch
           {
               Helpfunctions.Instance.ErrorLog("cant read enemy concede");
           }

           this.sf = new Silverfish(writeToSingleFile);


           CardDB cdb = CardDB.Instance;
           if (cdb.installedWrong) return;


           Mulligan.Instance.setAutoConcede(concede);

           sf.setnewLoggFile();

           try
           {
               int enfacehp = Convert.ToInt32((HRSettings.Get.ReadSetting("silverfish.xml", "uai.enemyfacehp")));
               Helpfunctions.Instance.ErrorLog("set enemy-face-hp to: " + enfacehp);
               ComboBreaker.Instance.attackFaceHP = enfacehp;
           }
           catch
           {
               Helpfunctions.Instance.ErrorLog("error in reading enemy-face-hp");
           }

           try
           {
               int mxwde = Convert.ToInt32((HRSettings.Get.ReadSetting("silverfish.xml", "uai.maxwide")));
               Ai.Instance.setMaxWide(mxwde);
               if (mxwde != 3000)
               {
                   Ai.Instance.setMaxWide(mxwde);
                   Helpfunctions.Instance.ErrorLog("set maxwide to: " + mxwde);
               }
           }
           catch
           {
               Helpfunctions.Instance.ErrorLog("error in reading Maxwide from settings, please recheck the entry");
           }

           try
           {
               bool twots = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.simulateTwoTurns") == "true") ? true : false;
               Ai.Instance.setTwoTurnSimulation(twots);
               if (twots)
               {
                   Ai.Instance.setTwoTurnSimulation(twots);
                   Helpfunctions.Instance.ErrorLog("activated two turn simulation");
               }

           }
           catch
           {
               Helpfunctions.Instance.ErrorLog("error in reading two-turn-simulation from settings");
           }

           try
           {
               bool playaround = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.playAround") == "true") ? true : false;
               int playaroundprob = Convert.ToInt32(HRSettings.Get.ReadSetting("silverfish.xml", "uai.playAroundProb"));
               if (playaroundprob > 100) playaroundprob = 100;
               if (playaroundprob < 0) playaroundprob = 0;

               int playaroundprob2 = Convert.ToInt32(HRSettings.Get.ReadSetting("silverfish.xml", "uai.playAroundProb2"));
               if (playaroundprob2 < playaroundprob) playaroundprob2 = playaroundprob;
               if (playaroundprob2 > 100) playaroundprob2 = 100;
               if (playaroundprob2 < 0) playaroundprob2 = 0;
               if (playaround)
               {
                   Ai.Instance.setPlayAround(playaround,playaroundprob, playaroundprob2);
                   Helpfunctions.Instance.ErrorLog("activated playaround");
               }

           }
           catch
           {
               Helpfunctions.Instance.ErrorLog("error in reading play around settings");
           }

           Helpfunctions.Instance.ErrorLog("write to single log file is: " + writeToSingleFile);

           bool teststuff = false;
           bool printstuff = false;
           try
           {

               printstuff = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.longteststuff") == "true") ? true : false;
               teststuff = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.teststuff") == "true") ? true : false;
           }
           catch
           {
               Helpfunctions.Instance.ErrorLog("something went wrong with simulating stuff!");
           }
           Helpfunctions.Instance.ErrorLog("----------------------------");
           Helpfunctions.Instance.ErrorLog("you are running uai V"+sf.versionnumber);
           Helpfunctions.Instance.ErrorLog("----------------------------");

           if (teststuff)
           {
               Ai.Instance.autoTester(behave, printstuff);
           }
           writeSettings();
       }
Exemple #19
0
       public Bot()
       {
           behave = this.getBotBehave();
           OnVictory = HandleWining;
            OnLost = HandleLosing;
            OnBattleStateUpdate = HandleOnBattleStateUpdate;
            OnMulliganStateUpdate = HandleBattleMulliganPhase;
            starttime = DateTime.Now;
            bool concede = false;
            bool writeToSingleFile = false;

           

            try
            {
                this.learnmode = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.wwuaid") == "true") ? true : false;
                if (this.learnmode)
                {
                    Helpfunctions.Instance.ErrorLog("Learn mode is ON");
                }
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("a wild error occurrs! cant read the settings...");
            }
            try
            {
                concede = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.autoconcede") == "true") ? true : false;
                writeToSingleFile = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.singleLog") == "true") ? true : false;
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("a wild error occurrs! cant read the settings...");
            }
            try
            {
                this.concedeLvl = Convert.ToInt32((HRSettings.Get.ReadSetting("silverfish.xml", "uai.concedelvl")));
                if (this.concedeLvl >= 20) this.concedeLvl = 20;
                if (concede)
                {
                    Helpfunctions.Instance.ErrorLog("concede till rank " + concedeLvl);
                }
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("cant read your concede-Lvl");
            }

            /*try
            {
                this.stopAfterWins = Convert.ToInt32((HRSettings.Get.ReadSetting("silverfish.xml", "uai.stopwin")));
                if (this.stopAfterWins <= 0) this.stopAfterWins = 10000;
                Helpfunctions.Instance.ErrorLog("stop after " + stopAfterWins + " wins");
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("cant read stop after # of wins");
            }*/

            try
            {
                this.enemyConcede = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.enemyconcede") == "true") ? true : false;
                if (this.enemyConcede) Helpfunctions.Instance.ErrorLog("concede whether enemy has lethal");
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("cant read enemy concede");
            }

            this.sf = new Silverfish(writeToSingleFile);


            CardDB cdb = CardDB.Instance;
            if (cdb.installedWrong) return;


            Mulligan.Instance.setAutoConcede(concede);

            sf.setnewLoggFile();

            try
            {
                int enfacehp = Convert.ToInt32((HRSettings.Get.ReadSetting("silverfish.xml", "uai.enemyfacehp")));
                Helpfunctions.Instance.ErrorLog("set enemy-face-hp to: " + enfacehp);
                ComboBreaker.Instance.attackFaceHP = enfacehp;
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("error in reading enemy-face-hp");
            }

            try
            {
                int mxwde = Convert.ToInt32((HRSettings.Get.ReadSetting("silverfish.xml", "uai.maxwide")));
                if (mxwde != 3000)
                {
                    Ai.Instance.setMaxWide(mxwde);
                    Helpfunctions.Instance.ErrorLog("set maxwide to: " + mxwde);
                }
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("error in reading Maxwide from settings, please recheck the entry");
            }

           int twotsamount =0;
            try
            {
                //bool twots = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.simulateTwoTurns") == "true") ? true : false;
                twotsamount = Convert.ToInt32((HRSettings.Get.ReadSetting("silverfish.xml", "uai.simulateTwoTurnCounter")));
                if (twotsamount < 0) twotsamount = 0;
                Ai.Instance.setTwoTurnSimulation(false, twotsamount);
                Helpfunctions.Instance.ErrorLog("calculate the second turn of the " + twotsamount + " best boards");


            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("error in reading two-turn-simulation from settings");
            }

            if (twotsamount >= 1)
            {
                try
                {
                    bool enemySecondTurnSim = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.simulateEnemyOnSecondTurn") == "true") ? true : false;
                    Ai.Instance.nextTurnSimulator.setEnemyTurnsim(enemySecondTurnSim);
                    if(enemySecondTurnSim) Helpfunctions.Instance.ErrorLog("simulates the enemy turn on your second turn");


                }
                catch
                {
                    Helpfunctions.Instance.ErrorLog("error in reading enemys-two-turn-simulation from settings");
                }
            }

            try
            {
                bool playaround = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.playAround") == "true") ? true : false;
                int playaroundprob = Convert.ToInt32(HRSettings.Get.ReadSetting("silverfish.xml", "uai.playAroundProb"));
                if (playaroundprob > 100) playaroundprob = 100;
                if (playaroundprob < 0) playaroundprob = 0;

                int playaroundprob2 = Convert.ToInt32(HRSettings.Get.ReadSetting("silverfish.xml", "uai.playAroundProb2"));
                if (playaroundprob2 < playaroundprob) playaroundprob2 = playaroundprob;
                if (playaroundprob2 > 100) playaroundprob2 = 100;
                if (playaroundprob2 < 0) playaroundprob2 = 0;
                if (playaround)
                {
                    Ai.Instance.setPlayAround(playaround, playaroundprob, playaroundprob2);
                    Helpfunctions.Instance.ErrorLog("activated playaround");
                }

            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("error in reading play around settings");
            }

            Helpfunctions.Instance.ErrorLog("write to single log file is: " + writeToSingleFile);

            bool teststuff = false;
            bool printstuff = false;
            try
            {

                printstuff = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.longteststuff") == "true") ? true : false;
                teststuff = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.teststuff") == "true") ? true : false;
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("something went wrong with simulating stuff!");
            }
            Helpfunctions.Instance.ErrorLog("----------------------------");
            Helpfunctions.Instance.ErrorLog("you are running uai V" + sf.versionnumber);
            Helpfunctions.Instance.ErrorLog("----------------------------");

            try
            {
                this.useExternalProcess = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.extern") == "true") ? true : false;
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("rand read the external-process setting!");
            }

            if (this.useExternalProcess) Helpfunctions.Instance.ErrorLog("YOU USE SILVER.EXE FOR CALCULATION, MAKE SURE YOU STARTED IT!");
            if (this.useExternalProcess) Helpfunctions.Instance.ErrorLog("SILVER.EXE IS LOCATED IN: " + Settings.Instance.path);

            if (teststuff)
            {
                Ai.Instance.autoTester(printstuff);
            }
            writeSettings();
        }
Exemple #20
0
        public bool updateEverything(Behavior botbase)
        {
            this.botbehave = "rush";
            if (botbase is BehaviorControl) this.botbehave = "control";
            if (Ai.Instance.secondturnsim) this.botbehave += " twoturnsim";
            if (Ai.Instance.playaround) this.botbehave += " playaround";
            HRPlayer ownPlayer = HRPlayer.GetLocalPlayer();
            HRPlayer enemyPlayer = HRPlayer.GetEnemyPlayer();
            ownPlayerController = ownPlayer.GetHero().GetControllerId();//ownPlayer.GetHero().GetControllerId()


            // create hero + minion data
            getHerostuff();
            getMinions();
            getHandcards();
            getDecks();

            // send ai the data:
            Hrtprozis.Instance.clearAll();
            Handmanager.Instance.clearAll();

            Hrtprozis.Instance.setOwnPlayer(ownPlayerController);
            Handmanager.Instance.setOwnPlayer(ownPlayerController);

            Hrtprozis.Instance.updatePlayer(this.ownMaxMana, this.currentMana, this.cardsPlayedThisTurn, this.numMinionsPlayedThisTurn, this.ueberladung, ownPlayer.GetHero().GetEntityId(), enemyPlayer.GetHero().GetEntityId());
            Hrtprozis.Instance.updateSecretStuff(this.ownSecretList, this.enemySecretCount);

            Hrtprozis.Instance.updateOwnHero(this.ownHeroWeapon, this.heroWeaponAttack, this.heroWeaponDurability, this.heroImmuneToDamageWhileAttacking, this.heroAtk, this.heroHp, this.heroDefence, this.heroname, this.ownheroisread, this.herofrozen, this.heroAbility, this.ownAbilityisReady, this.heroNumAttacksThisTurn, this.heroHasWindfury, this.heroImmune);
            Hrtprozis.Instance.updateEnemyHero(this.enemyHeroWeapon, this.enemyWeaponAttack, this.enemyWeaponDurability, this.enemyAtk, this.enemyHp, this.enemyDefence, this.enemyHeroname, this.enemyfrozen, this.enemyAbility, this.enemyHeroImmune, this.enemyMaxMana);

            Hrtprozis.Instance.updateMinions(this.ownMinions, this.enemyMinions);
            Handmanager.Instance.setHandcards(this.handCards, this.anzcards, this.enemyAnzCards);

            Hrtprozis.Instance.updateFatigueStats(this.ownDecksize, this.ownHeroFatigue, this.enemyDecksize, this.enemyHeroFatigue);


            Playfield p = new Playfield();
            if (lastpf != null)
            {
                if (lastpf.isEqualf(p))
                {
                    return false;
                }
                lastpf = p;
            }
            else
            {
                lastpf = p;
            }

            // print data
            this.printstuff();
            Hrtprozis.Instance.printHero();
            Hrtprozis.Instance.printOwnMinions();
            Hrtprozis.Instance.printEnemyMinions();
            Handmanager.Instance.printcards();

            // calculate stuff

            

            Helpfunctions.Instance.ErrorLog("calculating stuff... " + DateTime.Now.ToString("HH:mm:ss.ffff"));
            Ai.Instance.dosomethingclever(botbase);
            Helpfunctions.Instance.ErrorLog("calculating ended! " + DateTime.Now.ToString("HH:mm:ss.ffff"));
            return true;

        }
Exemple #21
0
        public Bot()
        {
            behave                = this.getBotBehave();
            OnVictory             = HandleWining;
            OnLost                = HandleLosing;
            OnBattleStateUpdate   = HandleOnBattleStateUpdate;
            OnMulliganStateUpdate = HandleBattleMulliganPhase;
            starttime             = DateTime.Now;
            bool concede           = false;
            bool writeToSingleFile = false;

            try
            {
                this.learnmode = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.wwuaid") == "true") ? true : false;
                if (this.learnmode)
                {
                    Helpfunctions.Instance.ErrorLog("Learn mode is ON");
                }
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("a wild error occurrs! cant read the settings...");
            }
            try
            {
                concede           = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.autoconcede") == "true") ? true : false;
                writeToSingleFile = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.singleLog") == "true") ? true : false;
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("a wild error occurrs! cant read the settings...");
            }
            try
            {
                this.concedeLvl = Convert.ToInt32((HRSettings.Get.ReadSetting("silverfish.xml", "uai.concedelvl")));
                if (this.concedeLvl >= 20)
                {
                    this.concedeLvl = 20;
                }
                if (concede)
                {
                    Helpfunctions.Instance.ErrorLog("concede till rank " + concedeLvl);
                }
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("cant read your concede-Lvl");
            }

            try
            {
                this.stopAfterWins = Convert.ToInt32((HRSettings.Get.ReadSetting("silverfish.xml", "uai.stopwin")));
                if (this.stopAfterWins <= 0)
                {
                    this.stopAfterWins = 10000;
                }
                Helpfunctions.Instance.ErrorLog("stop after " + stopAfterWins + " wins");
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("cant read stop after # of wins");
            }

            try
            {
                this.enemyConcede = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.enemyconcede") == "true") ? true : false;
                if (this.enemyConcede)
                {
                    Helpfunctions.Instance.ErrorLog("concede whether enemy has lethal");
                }
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("cant read enemy concede");
            }

            this.sf = new Silverfish(writeToSingleFile);


            CardDB cdb = CardDB.Instance;

            if (cdb.installedWrong)
            {
                return;
            }


            Mulligan.Instance.setAutoConcede(concede);

            sf.setnewLoggFile();

            try
            {
                int enfacehp = Convert.ToInt32((HRSettings.Get.ReadSetting("silverfish.xml", "uai.enemyfacehp")));
                Helpfunctions.Instance.ErrorLog("set enemy-face-hp to: " + enfacehp);
                ComboBreaker.Instance.attackFaceHP = enfacehp;
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("error in reading enemy-face-hp");
            }

            try
            {
                int mxwde = Convert.ToInt32((HRSettings.Get.ReadSetting("silverfish.xml", "uai.maxwide")));
                Ai.Instance.setMaxWide(mxwde);
                if (mxwde != 3000)
                {
                    Ai.Instance.setMaxWide(mxwde);
                    Helpfunctions.Instance.ErrorLog("set maxwide to: " + mxwde);
                }
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("error in reading Maxwide from settings, please recheck the entry");
            }

            try
            {
                bool twots = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.simulateTwoTurns") == "true") ? true : false;
                Ai.Instance.setTwoTurnSimulation(twots);
                if (twots)
                {
                    Ai.Instance.setTwoTurnSimulation(twots);
                    Helpfunctions.Instance.ErrorLog("activated two turn simulation");
                }
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("error in reading two-turn-simulation from settings");
            }

            try
            {
                bool playaround     = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.playAround") == "true") ? true : false;
                int  playaroundprob = Convert.ToInt32(HRSettings.Get.ReadSetting("silverfish.xml", "uai.playAroundProb"));
                if (playaroundprob > 100)
                {
                    playaroundprob = 100;
                }
                if (playaroundprob < 0)
                {
                    playaroundprob = 0;
                }

                int playaroundprob2 = Convert.ToInt32(HRSettings.Get.ReadSetting("silverfish.xml", "uai.playAroundProb2"));
                if (playaroundprob2 < playaroundprob)
                {
                    playaroundprob2 = playaroundprob;
                }
                if (playaroundprob2 > 100)
                {
                    playaroundprob2 = 100;
                }
                if (playaroundprob2 < 0)
                {
                    playaroundprob2 = 0;
                }
                if (playaround)
                {
                    Ai.Instance.setPlayAround(playaround, playaroundprob, playaroundprob2);
                    Helpfunctions.Instance.ErrorLog("activated playaround");
                }
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("error in reading play around settings");
            }

            Helpfunctions.Instance.ErrorLog("write to single log file is: " + writeToSingleFile);

            bool teststuff  = false;
            bool printstuff = false;

            try
            {
                printstuff = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.longteststuff") == "true") ? true : false;
                teststuff  = (HRSettings.Get.ReadSetting("silverfish.xml", "uai.teststuff") == "true") ? true : false;
            }
            catch
            {
                Helpfunctions.Instance.ErrorLog("something went wrong with simulating stuff!");
            }
            Helpfunctions.Instance.ErrorLog("----------------------------");
            Helpfunctions.Instance.ErrorLog("you are running uai V" + sf.versionnumber);
            Helpfunctions.Instance.ErrorLog("----------------------------");

            if (teststuff)
            {
                Ai.Instance.autoTester(behave, printstuff);
            }
            writeSettings();
        }
Exemple #22
0
        public float doallmoves(Playfield playf, bool isLethalCheck, bool print = false)
        {

            //todo only one time!
            this.doEnemySecondTurn = sf.Settings.simEnemySecondTurn;
            int totalboards = sf.Settings.nextTurnTotalBoards;
            int maxwide = sf.Settings.nextTurnMaxWide;
            int maxdeep = sf.Settings.nextTurnDeep;
            bool playaround = sf.Settings.playarround;
            int playaroundprob = sf.Settings.playaroundprob;
            int playaroundprob2 = sf.Settings.playaroundprob2;


            //Helpfunctions.Instance.logg("NXTTRN" + playf.mana);
            if (botBase == null) botBase = sf.Ai.botBase;
            bool test = false;
            this.posmoves.Clear();
            this.addToPosmoves(playf, totalboards);
            bool havedonesomething = true;
            List<Playfield> temp = new List<Playfield>();
            int deep = 0;
            //Helpfunctions.Instance.logg("NXTTRN" + playf.mana + " " + posmoves.Count);
            this.calculated = 0;
            while (havedonesomething)
            {
                //if (this.printNormalstuff) Helpfunctions.Instance.logg("ailoop");
                //GC.Collect();
                temp.Clear();
                temp.AddRange(this.posmoves);
                havedonesomething = false;
                Playfield bestold = null;
                float bestoldval = -20000000;
                foreach (Playfield p in temp)
                {

                    if (p.complete || p.ownHero.Hp <= 0)
                    {
                        continue;
                    }

                    List<Action> actions = sf.Movegenerator.getMoveList(p, isLethalCheck, usePenalityManager, useCutingTargets);
                    foreach (Action a in actions)
                    {
                        havedonesomething = true;
                        Playfield pf = new Playfield(p);
                        pf.doAction(a);
                        addToPosmoves(pf, totalboards);
                    }


                    if (isLethalCheck)
                    {
                        p.complete = true;
                    }
                    else
                    {
                        p.sEnemTurn = this.doEnemySecondTurn;
                        p.endTurn(this.simulateSecondTurn, playaround, false, playaroundprob, playaroundprob2);
                        this.startEnemyTurnSim(p, this.simulateSecondTurn, false, playaround, playaroundprob, playaroundprob2);
                    }

                    //sort stupid stuff ouf

                    if (botBase.getPlayfieldValue(p) > bestoldval)
                    {
                        bestoldval = botBase.getPlayfieldValue(p);
                        bestold = p;
                    }
                    if (!test)
                    {
                        posmoves.Remove(p);
                    }

                    if (this.calculated > totalboards) break;
                }

                if (!test && bestoldval >= -10000 && bestold != null)
                {
                    this.posmoves.Add(bestold);
                }

                //Helpfunctions.Instance.loggonoff(true);
                /*if (this.printNormalstuff)
                {
                    int donec = 0;
                    foreach (Playfield p in posmoves)
                    {
                        if (p.complete) donec++;
                    }
                    Helpfunctions.Instance.logg("deep " + deep + " len " + this.posmoves.Count + " dones " + donec);
                }*/

                if (!test)
                {
                    cuttingposibilities(maxwide);
                }

                //if (this.printNormalstuff) Helpfunctions.Instance.logg("cut to len " + this.posmoves.Count);
                //Helpfunctions.Instance.loggonoff(false);
                deep++;

                if (this.calculated > totalboards) break;
                if (deep >= maxdeep) break;//remove this?
            }

            foreach (Playfield p in posmoves)//temp
            {
                if (!p.complete)
                {
                    if (isLethalCheck)
                    {
                        p.complete = true;
                    }
                    else
                    {
                        p.sEnemTurn = this.doEnemySecondTurn;
                        p.endTurn(this.simulateSecondTurn, playaround, false, playaroundprob, playaroundprob2);
                        this.startEnemyTurnSim(p, this.simulateSecondTurn, false, playaround, playaroundprob, playaroundprob2);
                    }
                }
            }
            // Helpfunctions.Instance.logg("find best ");
            if (posmoves.Count >= 1)
            {
                float bestval = int.MinValue;
                int bestanzactions = 1000;
                Playfield bestplay = posmoves[0];//temp[0]
                foreach (Playfield p in posmoves)//temp
                {
                    float val = botBase.getPlayfieldValue(p);
                    if (bestval <= val)
                    {
                        if (bestval == val && bestanzactions < p.playactions.Count) continue;
                        bestplay = p;
                        bestval = val;
                        bestanzactions = p.playactions.Count;
                    }

                }
                this.bestboard = new Playfield(bestplay);

                if (print)
                {
                    sf.Helpfunctions.ErrorLog("best board after your second turn (value included enemy second turn)----------");
                    bestplay.printBoard();
                    bestplay.value = int.MinValue;
                    bestplay.sEnemTurn = this.doEnemySecondTurn;
                    sf.Ai.enemySecondTurnSim[this.thread].simulateEnemysTurn(bestplay, false, playaround, false, playaroundprob, playaroundprob2);
                    //sf.Ai.enemySecondTurnSim.simulateEnemysTurn(bestplay, false, false, true, 100, 100); //dont play arround in enemys second turn

                }
                this.bestmove = bestplay.getNextAction();
                this.bestmoveValue = bestval;
                this.bestboard = new Playfield(bestplay);
                //Helpfunctions.Instance.logg("return");
                return bestval;
            }
            //Helpfunctions.Instance.logg("return");
            this.bestmove = null;
            this.bestmoveValue = -100000;
            this.bestboard = playf;
            return -10000;
        }
Exemple #23
0
        public Behavior readSettings() //takes same path as carddb
        {
            string[] lines = new string[] { };

            string       path            = this.path;
            string       cleanpath       = "Silverfish" + System.IO.Path.DirectorySeparatorChar;
            string       datapath        = path + "Data" + System.IO.Path.DirectorySeparatorChar;
            string       cleandatapath   = cleanpath + "Data" + System.IO.Path.DirectorySeparatorChar;
            string       classpath       = datapath + ownClass + System.IO.Path.DirectorySeparatorChar;
            string       cleanclasspath  = cleandatapath + ownClass + System.IO.Path.DirectorySeparatorChar;
            string       deckpath        = classpath + deckName + System.IO.Path.DirectorySeparatorChar;
            string       cleandeckpath   = cleanclasspath + deckName + System.IO.Path.DirectorySeparatorChar;
            string       enemyfilestring = "settings-" + enemyClass + ".txt";
            const string filestring      = "settings.txt";
            bool         enemysettings   = false;

            // if we have a deckName then we have a real ownClass too, not the default "druid"
            if (deckName != "" && System.IO.File.Exists(deckpath + enemyfilestring))
            {
                enemysettings = true;
                path          = deckpath;
                cleanPath     = cleandeckpath + enemyfilestring;
            }
            else if (deckName != "" && System.IO.File.Exists(deckpath + filestring))
            {
                path      = deckpath;
                cleanPath = cleandeckpath + filestring;
            }
            else if (deckName != "" && System.IO.File.Exists(classpath + enemyfilestring))
            {
                enemysettings = true;
                path          = classpath;
                cleanPath     = cleanclasspath + enemyfilestring;
            }
            else if (deckName != "" && System.IO.File.Exists(classpath + filestring))
            {
                path      = classpath;
                cleanPath = cleanclasspath + filestring;
            }
            else if (deckName != "" && System.IO.File.Exists(datapath + enemyfilestring))
            {
                enemysettings = true;
                path          = datapath;
                cleanPath     = cleandatapath + enemyfilestring;
            }
            else if (deckName != "" && System.IO.File.Exists(datapath + filestring))
            {
                path      = datapath;
                cleanPath = cleandatapath + filestring;
            }
            else if (System.IO.File.Exists(path + enemyfilestring))
            {
                enemysettings = true;
                cleanPath     = cleanpath + enemyfilestring;
            }
            else if (System.IO.File.Exists(path + filestring))
            {
                cleanPath = cleanpath + filestring;
            }
            else
            {
                Helpfunctions.Instance.logg("[Settings] cant find base settings.txt, using default settings");
                return(setDefaultSettings());
            }
            Helpfunctions.Instance.ErrorLog("[Settings] read " + cleanPath);


            const string readerror = " read error. Continuing without user-defined rules.";

            if (enemysettings)
            {
                try
                {
                    lines = System.IO.File.ReadAllLines(path + enemyfilestring);
                }
                catch
                {
                    Helpfunctions.Instance.ErrorLog(enemyfilestring + readerror);
                    return(setDefaultSettings());
                }
            }
            else
            {
                try
                {
                    lines = System.IO.File.ReadAllLines(path + filestring);
                }
                catch
                {
                    Helpfunctions.Instance.logg(filestring + readerror);
                    return(setDefaultSettings());
                }
            }

            foreach (string ss in lines)
            {
                string s = ss.Replace(" ", "");
                if (s.Contains(";"))
                {
                    s = s.Split(';')[0];
                }
                if (s.Contains("#"))
                {
                    s = s.Split('#')[0];
                }
                if (s.Contains("//"))
                {
                    s = s.Split(new string[] { "//" }, StringSplitOptions.RemoveEmptyEntries)[0];
                }
                if (s.Contains(","))
                {
                    s = s.Split(',')[0];
                }
                if (s == "" || s == " ")
                {
                    continue;
                }
                s = s.ToLower();
                const string ignoring = "[Settings] ignoring the setting ";

                string searchword = "maxwide=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.maxwide = Convert.ToInt32(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "twotsamount=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.twotsamount = Convert.ToInt32(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "simenemysecondturn=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.simEnemySecondTurn = Convert.ToBoolean(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "enfacehp=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.enfacehp = Convert.ToInt32(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "playarround=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.playarround = Convert.ToBoolean(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "playaroundprob=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.playaroundprob = Convert.ToInt32(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "playaroundprob2=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.playaroundprob2 = Convert.ToInt32(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "enemyturnmaxwide=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.enemyTurnMaxWide = Convert.ToInt32(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "enemyturnmaxwidesecondtime=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.enemyTurnMaxWideSecondTime = Convert.ToInt32(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "enemysecondturnmaxwide=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.enemySecondTurnMaxWide = Convert.ToInt32(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "nextturndeep=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.nextTurnDeep = Convert.ToInt32(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "nextturnmaxwide=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.nextTurnMaxWide = Convert.ToInt32(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "nextturntotalboards=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.nextTurnTotalBoards = Convert.ToInt32(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "usesecretsplayarround=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.useSecretsPlayArround = Convert.ToBoolean(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "alpha=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.alpha = Convert.ToInt32(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "simulateplacement=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.simulatePlacement = Convert.ToBoolean(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "useexternalprocess=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.useExternalProcess = Convert.ToBoolean(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "passivewaiting=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.passiveWaiting = Convert.ToBoolean(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "behave=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    if (a.StartsWith("control"))
                    {
                        behave = new BehaviorControl();
                    }
                    if (a.StartsWith("rush"))
                    {
                        behave = new BehaviorRush();
                    }
                    if (a.StartsWith("mana"))
                    {
                        behave = new BehaviorMana();
                    }
                    if (a.StartsWith("face"))
                    {
                        behave = new BehaviorFace();
                    }
                    if (a.StartsWith("aggrowarlock"))
                    {
                        behave = new BehaviorAggroWarlock();
                    }
                    if (a.StartsWith("aggroshaman"))
                    {
                        behave = new BehaviorAggroshaman();
                    }
                }

                searchword = "concedeonbadboard=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.enemyConcede = Convert.ToBoolean(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "concedeonboardvalue=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.enemyConcedeValue = Convert.ToInt32(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "speed=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.speedy = Convert.ToBoolean(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "usenetwork=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.useNetwork = Convert.ToBoolean(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "netaddress=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.netAddress = a;
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "tcpport=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.tcpPort = Convert.ToInt32(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                //always enabled now so ignore user setting

                /*
                 * searchword = "logbuffer=";
                 * if (s.StartsWith(searchword))
                 * {
                 *  string a = s.Replace(searchword, "");
                 *  try
                 *  {
                 *      this.logBuffer = Convert.ToInt32(a);
                 *  }
                 *  catch
                 *  {
                 *      Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                 *  }
                 * }
                 */

                searchword = "secretstandard =";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.SecretStandard = Convert.ToBoolean(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }

                searchword = "enemyherovaluemultiply=";
                if (s.StartsWith(searchword))
                {
                    string a = s.Replace(searchword, "");
                    try
                    {
                        this.enemyherovaluemultiply = Convert.ToInt32(a);
                    }
                    catch
                    {
                        Helpfunctions.Instance.ErrorLog(ignoring + searchword);
                    }
                }
            }
            //foreach ended----------

            applySettings();


            return(behave);
        }
Exemple #24
0
        private void updateBehaveString(Behavior botbase)
        {
            this.botbehave = "rush";
            if (botbase is BehaviorControl) this.botbehave = "control";
            if (botbase is BehaviorMana) this.botbehave = "mana";
            this.botbehave += " " + Ai.Instance.maxwide;
            this.botbehave += " face " + ComboBreaker.Instance.attackFaceHP;
            if (Settings.Instance.secondTurnAmount > 0)
            {
                if (Ai.Instance.nextMoveGuess.mana == -100)
                {
                    Ai.Instance.updateTwoTurnSim();
                }
                this.botbehave += " twoturnsim " + Settings.Instance.secondTurnAmount + " ntss " + Settings.Instance.nextTurnDeep + " " + Settings.Instance.nextTurnMaxWide + " " + Settings.Instance.nextTurnTotalBoards;
            }

            if (Settings.Instance.playarround)
            {
                this.botbehave += " playaround";
                this.botbehave += " " + Settings.Instance.playaroundprob + " " + Settings.Instance.playaroundprob2;
            }

            this.botbehave += " ets " + Settings.Instance.enemyTurnMaxWide;

            if (Settings.Instance.simEnemySecondTurn)
            {
                this.botbehave += " ets2 " + Settings.Instance.enemyTurnMaxWideSecondTime;
                this.botbehave += " ents " + Settings.Instance.enemySecondTurnMaxWide;
            }

            if (Settings.Instance.useSecretsPlayArround)
            {
                this.botbehave += " secret";
            }

            if (Settings.Instance.secondweight != 0.5f)
            {
                this.botbehave += " weight " + (int)(Settings.Instance.secondweight*100f);
            }

            if (Settings.Instance.simulatePlacement)
            {
                this.botbehave += " plcmnt";
            }


        }
Exemple #25
0
        public float doallmoves(Playfield playf, bool isLethalCheck)
        {
            HRSim.Helpfunctions.Instance.startTimer();
            List<Action> actions = null;
            if (botBase == null) botBase = sf.Ai.botBase;
            bool test = false;
            this.posmoves.Clear();
            this.twoturnfields.Clear();
            this.addToPosmoves(playf);
            bool havedonesomething = true;
            List<Playfield> temp = new List<Playfield>();
            int deep = 0;
            //sf.helpfunctions.logg("NXTTRN" + playf.mana + " " + posmoves.Count);
            this.calculated = 0;
            //debug
            //int loopNumber = 0;
            while (havedonesomething)
            {
                //loopNumber++;
                if (this.printNormalstuff) sf.Helpfunctions.logg("ailoop");
                GC.Collect();
                temp.Clear();
                temp.AddRange(this.posmoves);
                havedonesomething = false;
                Playfield bestold = null;
                float bestoldval = -20000000;
                foreach (Playfield p in temp)
                {

                    if (p.complete || p.ownHero.Hp <= 0)
                    {
                        continue;
                    }

                    //gernerate actions and play them!
                    actions = sf.Movegenerator.getMoveList(p, isLethalCheck, usePenalityManager, useCutingTargets);
                    Playfield ppTest = new Playfield(sf);
                    //if (loopNumber == 1)
                    //{
                    //    if (!p.isEqual(ppTest, false))
                    //    {
                    //        int debug = 1;
                    //    }
                    //    foreach (Action a in actions)
                    //    {
                    //        if (a.actionType == actionEnum.playcard)
                    //        {
                    //            if (a.card.entity == 1020) {
                    //                int debug1 = 1;
                    //            }
                    //            bool isCardValid = false;
                    //            foreach (Handmanager.Handcard hh in p.owncards)
                    //            {
                    //                if (hh.entity == a.card.entity)
                    //                {
                    //                    isCardValid = true;
                    //                    break;
                    //                }
                    //            }
                    //            if (!isCardValid)
                    //            {
                    //                int debug = 1;
                    //            }
                    //        }
                    //    }
                    //}
                    //sf.helpfunctions.ErrorLog(" ");
                    //sf.helpfunctions.ErrorLog(actions.Count + " Playfield: " + p.hashcode.ToString());
                    foreach (Action a in actions)
                    {
                       /* string aList = "";

                        if (a.actionType != null)
                        {
                            try
                            {
                                aList = aList + "type:" + a.actionType.ToString();
                            }
                            catch
                            {
                                aList = aList + "type:---";
                            }
                        }

                        if (a.card != null)
                        {
                            try
                            {
                                aList = aList + "  Cname:" + a.card.card.name.ToString();
                            }
                            catch
                            {
                                aList = aList + "  Cname:---";
                            }
                        }

                        if (a.own != null)
                        {
                            try
                            {
                                aList = aList + "  oname:" + a.own.name.ToString();
                            }
                            catch
                            {
                                aList = aList + "  oname:---";
                            }
                        }

                        if (a.place != null)
                        {
                            try
                            {
                                aList = aList + "  place:" + a.place.ToString();
                            }
                            catch
                            {
                                aList = aList + "  place:---";
                            }
                        }

                        if (a.penalty != null)
                        {
                            try
                            {
                                aList = aList + "  penalty:" + a.penalty.ToString();
                            }
                            catch
                            {
                                aList = aList + "  penalty:---";
                            }
                        }

                        sf.helpfunctions.ErrorLog(aList);*/
                            
                            //if (deep == 0 && a.actionType == actionEnum.attackWithMinion) sf.helpfunctions.ErrorLog("play " + a.own.entitiyID + " -> " + a.target.entitiyID);
                        havedonesomething = true;
                        Playfield pf = new Playfield(p);
                        pf.doAction(a);
                        addToPosmoves(pf);
                        //HRSim.Helpfunctions.Instance.logTime("action itr");
                    }
                    //sf.helpfunctions.ErrorLog("deep " + deep + " len " + this.posmoves.Count);

                    // end the turn of the current board (only if its not a lethalcheck)
                    if (isLethalCheck)
                    {
                        p.complete = true;
                    }
                    else
                    {
                        //end turn of enemy
                        p.endTurn(this.simulateSecondTurn, this.playaround, false, this.playaroundprob, this.playaroundprob2);
                        //simulate the enemys response
                        this.startEnemyTurnSim(p, this.simulateSecondTurn, false);
                    }

                    //sort stupid stuff ouf

                    if (botBase.getPlayfieldValue(p) > bestoldval)
                    {
                        bestoldval = botBase.getPlayfieldValue(p);
                        bestold = p;
                    }
                    if (!test)
                    {
                        posmoves.Remove(p);
                    }

                    //HRSim.Helpfunctions.Instance.logTime("tempp itr");

                    if (this.calculated > this.totalboards) break;
                }

                if (!test && bestoldval >= -10000 && bestold != null)
                {
                    this.posmoves.Add(bestold);
                }

                //sf.helpfunctions.loggonoff(true);
                if (this.printNormalstuff)
                {
                    int donec = 0;
                    foreach (Playfield p in posmoves)
                    {
                        if (p.complete) donec++;
                    }
                    sf.Helpfunctions.logg("deep " + deep + " len " + this.posmoves.Count + " dones " + donec);
                }

                if (!test)
                {
                    cuttingposibilities();
                }

                if (this.printNormalstuff)
                {
                    sf.Helpfunctions.logg("cut to len " + this.posmoves.Count);
                }
                //sf.helpfunctions.loggonoff(false);
                deep++;

                if (this.calculated > this.totalboards) break;
                if (deep >= this.maxdeep) break;//remove this?
                //HRSim.Helpfunctions.Instance.logTime("sth itr");
            }
            //HRSim.Helpfunctions.Instance.logTime("done sth");

            foreach (Playfield p in posmoves)//temp
            {
                if (!p.complete)
                {
                    if (isLethalCheck)
                    {
                        p.complete = true;
                    }
                    else
                    {
                        p.endTurn(this.simulateSecondTurn, this.playaround, false, this.playaroundprob, this.playaroundprob2);
                        this.startEnemyTurnSim(p, this.simulateSecondTurn, false);
                    }
                }
            }

            // search the best play...........................................................

            //do dirtytwoturnsim first :D
            if (!isLethalCheck) doDirtyTwoTurnsim();

            if (!isLethalCheck) this.dirtyTwoTurnSim /= 2;

            // sf.helpfunctions.logg("find best ");
            ////HRSim.Helpfunctions.Instance.logTime("2 turn sim");
            if (posmoves.Count >= 1)
            {
                float bestval = int.MinValue;
                int bestanzactions = 1000;
                Playfield bestplay = posmoves[0];//temp[0]
                foreach (Playfield p in posmoves)//temp
                {
                    float val = botBase.getPlayfieldValue(p);
                    sf.helpfunctions.logg("move val:" + val);
                    if (bestval <= val)
                    {
                        if (bestval == val && bestanzactions < p.playactions.Count) continue;
                        bestplay = p;
                        bestval = val;
                        bestanzactions = p.playactions.Count;
                    }
                    //HRSim.Helpfunctions.Instance.logTime("search best play itr");
                }
                //HRSim.Helpfunctions.Instance.logTime("search best play 1: " + posmoves.Count);
                this.bestmove = bestplay.getNextAction();
                this.bestmoveValue = bestval;
                this.bestboard = new Playfield(bestplay);
                //HRSim.Helpfunctions.Instance.logTime("search best play 2");
                return bestval;
            }
            //sf.helpfunctions.logg("return");
            this.bestmove = null;
            this.bestmoveValue = -100000;
            this.bestboard = playf;
            return -10000;
        }
Exemple #26
0
        public void dosomethingclever(Behavior bbase)
        {
            //return;
            //turncheck
            //help.moveMouse(950,750);
            //help.Screenshot();
            this.botBase = bbase;
            hp.updatePositions();

            posmoves.Clear();
            posmoves.Add(new Playfield());
            posmoves[0].sEnemTurn = Settings.Instance.simulateEnemysTurn;
            /* foreach (var item in this.posmoves[0].owncards)
             {
                 help.logg("card " + item.handcard.card.name + " is playable :" + item.handcard.card.canplayCard(posmoves[0]) + " cost/mana: " + item.handcard.card.cost + "/" + posmoves[0].mana);
             }
             */
            //help.logg("is hero ready?" + posmoves[0].ownHeroReady);

            help.loggonoff(false);
            //do we need to recalc?
            help.logg("recalc-check###########");
            if (this.dontRecalc && posmoves[0].isEqual(this.nextMoveGuess, true))
            {
                doNextCalcedMove();
            }
            else
            {
                help.logg("Leathal-check###########");
                bestmoveValue = -1000000;
                DateTime strt = DateTime.Now;
                if (useLethalCheck)
                {
                    strt = DateTime.Now;
                    doallmoves(false, true);
                    help.logg("calculated " + (DateTime.Now - strt).TotalSeconds);
                }

                if (bestmoveValue < 10000)
                {
                    posmoves.Clear();
                    posmoves.Add(new Playfield());
                    posmoves[0].sEnemTurn = Settings.Instance.simulateEnemysTurn;
                    help.logg("no lethal, do something random######");
                    strt = DateTime.Now;
                    doallmoves(false, false);
                    help.logg("calculated " + (DateTime.Now - strt).TotalSeconds);

                }
            }


            //help.logging(true);

        }
Exemple #27
0
        public bool getHoldList(MulliganData mulliganData, Behavior behave)
        {
            this.cards.Clear();
            this.readRules(behave.BehaviorName());
            if (!this.mulliganRulesLoaded)
            {
                return(false);
            }

            if (!(mulliganData.Cards.Count == 3 || mulliganData.Cards.Count == 4))
            {
                Helpfunctions.Instance.ErrorLog(
                    $"[Mulligan] Mulligan is not used, since it got number of cards: {this.cards.Count}");
                return(false);
            }

            Log.InfoFormat("[开局留牌] 应用这个 {0} 规则:", behave.BehaviorName());

            for (var i = 0; i < mulliganData.Cards.Count; i++)
            {
                this.cards.Add(new CardIDEntity(mulliganData.Cards[i].Entity.Id, i));
            }

            var ownHeroClass   = mulliganData.UserClass.Convert();
            var enemyHeroClass = mulliganData.OpponentClass.Convert();

            var manaRule    = 4;
            var MullRuleKey = this.getMullRuleKey(SimCard.None, ownHeroClass, enemyHeroClass, 1);

            if (this.MulliganRules.ContainsKey(MullRuleKey))
            {
                var temp = this.MulliganRules[MullRuleKey].Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                manaRule = Convert.ToInt32(temp[2]);
            }
            else
            {
                MullRuleKey = this.getMullRuleKey(SimCard.None, ownHeroClass, CardClass.INVALID, 1);
                if (this.MulliganRules.ContainsKey(MullRuleKey))
                {
                    var temp = this.MulliganRules[MullRuleKey].Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                    manaRule = Convert.ToInt32(temp[2]);
                }
            }

            var Coin = new CardIDEntity("GAME_005", -888);

            if (this.cards.Count == 4)
            {
                this.cards.Add(Coin); //we have a coin
            }

            foreach (var CardIDEntityC in this.cards)
            {
                var c = CardIDEntityC.id;
                if (CardIDEntityC.hold == 0 && CardIDEntityC.holdByRule == 0)
                {
                    if (c.Cost < manaRule)
                    {
                        CardIDEntityC.holdByManarule = 2;
                        CardIDEntityC.holdReason     = this.joinSomeTxt("保留这些卡牌因为法力值消耗:", c.Cost.ToString(), " 小于预定值:", manaRule.ToString());
                    }
                    else
                    {
                        CardIDEntityC.holdByManarule = -2;
                        CardIDEntityC.holdReason     = this.joinSomeTxt("弃掉这些卡牌因为法力值消耗:", c.Cost.ToString(), " 没有小于预定值:", manaRule.ToString());
                    }
                }

                var allowedQuantitySimple = 0;
                var allowedQuantityExtra  = 0;
                var hasRuleClassSimple    = false;

                var hasRule           = false;
                var MullRuleKeySimple = this.getMullRuleKey(c, ownHeroClass, enemyHeroClass); //Simple key for Class enemy
                if (this.MulliganRules.ContainsKey(MullRuleKeySimple))
                {
                    hasRule            = true;
                    hasRuleClassSimple = true;
                }
                else
                {
                    MullRuleKeySimple = this.getMullRuleKey(c, ownHeroClass); //Simple key for ALL enemy
                    if (this.MulliganRules.ContainsKey(MullRuleKeySimple))
                    {
                        hasRule = true;
                    }
                }

                if (hasRule)
                {
                    var val = this.MulliganRules[MullRuleKeySimple].Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                    allowedQuantitySimple = (val[1] == "2" ? 2 : 1) * (val[0] == "Hold" ? 1 : -1);
                }

                hasRule = false;
                var MullRuleKeyExtra = this.getMullRuleKey(c, ownHeroClass, enemyHeroClass, 1); //Extra key for Class enemy
                if (this.MulliganRules.ContainsKey(MullRuleKeyExtra))
                {
                    hasRule = true;
                }
                else if (!hasRuleClassSimple)
                {
                    MullRuleKeyExtra = this.getMullRuleKey(c, ownHeroClass, CardClass.INVALID, 1); //Extra key for ALL enemy
                    if (this.MulliganRules.ContainsKey(MullRuleKeyExtra))
                    {
                        hasRule = true;
                    }
                }

                if (hasRule)
                {
                    var val = this.MulliganRules[MullRuleKeyExtra].Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                    allowedQuantityExtra = (val[1] == "2" ? 2 : 1) * (val[0] == "Hold" ? 1 : -1);
                }

                //superimpose Class rules to All rules
                var useHold        = false;
                var useDiscard     = false;
                var useHoldRule    = false;
                var useDiscardRule = false;

                if (allowedQuantitySimple != 0 && allowedQuantitySimple != allowedQuantityExtra)
                {
                    if (allowedQuantitySimple > 0)
                    {
                        useHold = true;
                    }
                    else
                    {
                        useDiscard = true;
                    }
                }

                if (allowedQuantityExtra != 0)
                {
                    if (allowedQuantityExtra < 0)
                    {
                        useDiscardRule = true;
                    }
                    else
                    {
                        useHoldRule = true;
                    }
                }

                //apply the rules
                var MullRuleValueExtra = new string[3];
                if (allowedQuantityExtra != 0)
                {
                    MullRuleValueExtra = this.MulliganRules[MullRuleKeyExtra].Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                }

                if (useDiscardRule)
                {
                    if (MullRuleValueExtra[2] != "/")
                    {
                        var addedCards = MullRuleValueExtra[2].Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
                        this.MulliganRulesManual.Clear();
                        foreach (var s in addedCards)
                        {
                            this.MulliganRulesManual.Add(s, "");
                        }

                        foreach (var tmp in this.cards)
                        {
                            if (CardIDEntityC.entitiy == tmp.entitiy)
                            {
                                continue;
                            }

                            if (this.MulliganRulesManual.ContainsKey(tmp.id))
                            {
                                CardIDEntityC.holdByRule = -2;
                                CardIDEntityC.holdReason = this.joinSomeTxt("符合规则而弃掉: ", this.getClearRule(MullRuleKeyExtra));
                                break;
                            }
                        }
                    }
                }
                else if (useDiscard)
                {
                    CardIDEntityC.hold       = -2;
                    CardIDEntityC.holdReason = this.joinSomeTxt("符合规则而弃掉: ", this.getClearRule(MullRuleKeySimple));
                }

                if (useHoldRule)
                {
                    if (CardIDEntityC.holdByRule == 0)
                    {
                        var addedCards = MullRuleValueExtra[2].Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
                        this.MulliganRulesManual.Clear();
                        foreach (var s in addedCards)
                        {
                            this.MulliganRulesManual.Add(s, "");
                        }

                        var foundFreeCard = false;
                        for (var i = 0; i < this.cards.Count; i++)
                        {
                            if (CardIDEntityC.entitiy == this.cards[i].entitiy)
                            {
                                continue;
                            }

                            if (this.MulliganRulesManual.ContainsKey(this.cards[i].id))
                            {
                                CardIDEntityC.holdByRule = 2;
                                CardIDEntityC.holdReason = this.joinSomeTxt("符合规则而保留: ", this.getClearRule(MullRuleKeyExtra));
                                if (this.cards[i].holdByRule < 0)
                                {
                                    for (var j = i; j < this.cards.Count; j++)
                                    {
                                        if (CardIDEntityC.entitiy == this.cards[j].entitiy)
                                        {
                                            continue;
                                        }

                                        if (this.MulliganRulesManual.ContainsKey(this.cards[j].id))
                                        {
                                            if (this.cards[j].holdByRule < 0)
                                            {
                                                continue;
                                            }

                                            foundFreeCard            = true;
                                            this.cards[j].holdByRule = 2;
                                            this.cards[j].holdReason = this.joinSomeTxt("符合规则而保留: ", this.getClearRule(MullRuleKeyExtra));
                                            break;
                                        }
                                    }

                                    if (!foundFreeCard)
                                    {
                                        foundFreeCard            = true;
                                        this.cards[i].holdByRule = 2;
                                        this.cards[i].holdReason = this.joinSomeTxt("符合规则而保留: ", this.getClearRule(MullRuleKeyExtra));
                                        break;
                                    }
                                }
                                else
                                {
                                    foundFreeCard            = true;
                                    this.cards[i].holdByRule = 2;
                                    this.cards[i].holdReason = this.joinSomeTxt("符合规则而保留: ", this.getClearRule(MullRuleKeyExtra));
                                }

                                if (allowedQuantityExtra == 1)
                                {
                                    foreach (var tmp in this.cards)
                                    {
                                        if (tmp.entitiy == CardIDEntityC.entitiy)
                                        {
                                            continue;
                                        }

                                        if (tmp.id == CardIDEntityC.id)
                                        {
                                            tmp.holdByRule = -2;
                                            tmp.holdReason = this.joinSomeTxt("符合规则而弃掉: ", this.getClearRule(MullRuleKeyExtra));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                if (useHold && CardIDEntityC.holdByRule != -2)
                {
                    if (CardIDEntityC.hold == 0)
                    {
                        CardIDEntityC.hold       = 2;
                        CardIDEntityC.holdReason = this.joinSomeTxt("符合规则而保留: ", this.getClearRule(MullRuleKeySimple));
                        if (allowedQuantitySimple == 1)
                        {
                            CardIDEntityC.hold = 1;
                            foreach (var tmp in this.cards)
                            {
                                if (tmp.entitiy == CardIDEntityC.entitiy)
                                {
                                    continue;
                                }

                                if (tmp.id == CardIDEntityC.id)
                                {
                                    tmp.hold       = -2;
                                    tmp.holdReason = this.joinSomeTxt("discard Second card by rule: ", this.getClearRule(MullRuleKeySimple));
                                }
                            }
                        }
                    }
                }
            }

            if (this.cards.Count == 5)
            {
                this.cards.Remove(Coin);
            }

            foreach (var c in this.cards)
            {
                if (c.holdByRule == 0)
                {
                    if (c.hold == 0)
                    {
                        c.holdByRule = c.holdByManarule;
                    }
                    else
                    {
                        c.holdByRule = c.hold;
                    }
                }
            }

            for (var i = 0; i < mulliganData.Cards.Count; i++)
            {
                mulliganData.Mulligans[i] = this.cards[i].holdByRule > 0 ? false : true;
                Log.InfoFormat("[开局留牌] {0} {1}.", mulliganData.Cards[i].Entity.Name, this.cards[i].holdReason);
            }

            return(true);
        }