Example #1
0
        public float DoAllMoves(Playfield playf)
        {
            print              = playf.print;
            isLethalCheck      = playf.isLethalCheck;
            enoughCalculations = false;
            botBase            = Ai.Instance.botBase;
            posmoves.Clear();
            twoturnfields.Clear();
            addToPosmoves(playf);
            bool             havedonesomething = true;
            List <Playfield> temp = new List <Playfield>();
            int deep = 0;

            calculated = 0;
            Playfield bestold = null;

            bestoldval = -20000000;
            while (havedonesomething)
            {
                if (printNormalstuff)
                {
                    LogHelper.WriteCombatLog($"ailoop{deep}");
                }
                GC.Collect();
                temp.Clear();
                temp.AddRange(posmoves);
                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 (totalboards > 0)
                    {
                        calculated += p.nextPlayfields.Count;
                    }
                    if (calculated <= totalboards)
                    {
                        posmoves.AddRange(p.nextPlayfields);
                        p.nextPlayfields.Clear();
                    }

                    //get the best Playfield
                    float pVal = botBase.getPlayfieldValue(p);
                    if (pVal > bestoldval)
                    {
                        bestoldval = pVal;
                        bestold    = p;
                        bestoldDuplicates.Clear();
                    }
                    else if (Math.Abs(pVal - bestoldval) < 0.001f)
                    {
                        bestoldDuplicates.Add(p);
                    }
                }

                if (isLethalCheck && bestoldval >= 10000)
                {
                    posmoves.Clear();
                }

                if (posmoves.Count > 0)
                {
                    havedonesomething = true;
                }

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

                cuttingposibilities(isLethalCheck);//will update posmoves

                if (printNormalstuff)
                {
                    LogHelper.WriteCombatLog("cut to len " + posmoves.Count);
                }

                int itemPlayfieldIndex = 0;
                foreach (var itemPlayfield in posmoves)
                {
                    itemPlayfieldIndex++;
                    var actionsCount = itemPlayfield.playactions.Count;
                    LogHelper.WriteTestCombatLog($"{nameof(itemPlayfield)}{itemPlayfieldIndex} with {actionsCount} actions");
                    itemPlayfield.printActions();
                }
                deep++;
                temp.Clear();

                if (calculated > totalboards)
                {
                    enoughCalculations = true;
                }

                if (deep >= maxdeep)
                {
                    enoughCalculations = true;
                }
            }

            if (dirtyTwoTurnSim > 0 && !twoturnfields.Contains(bestold))
            {
                twoturnfields.Add(bestold);
            }
            posmoves.Clear();
            posmoves.Add(bestold);
            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;
                    }
                    if (posmoves[i].cardsPlayedThisTurn == bestplay.cardsPlayedThisTurn)
                    {
                        if (bestplay.optionsPlayedThisTurn > posmoves[i].optionsPlayedThisTurn)
                        {
                            continue;
                        }
                        if (bestplay.optionsPlayedThisTurn == posmoves[i].optionsPlayedThisTurn && bestplay.enemyHero.HealthPoints <= posmoves[i].enemyHero.HealthPoints)
                        {
                            continue;
                        }
                    }
                    bestplay = posmoves[i];
                    bestval  = val;
                }
                bestmove                 = bestplay.getNextAction();
                bestmoveValue            = bestval;
                bestboard                = new Playfield(bestplay);
                bestboard.guessingHeroHP = bestplay.guessingHeroHP;
                bestboard.value          = bestplay.value;
                bestboard.hashcode       = bestplay.hashcode;
                bestoldDuplicates.Clear();
                return(bestval);
            }
            bestmove      = null;
            bestmoveValue = -100000;
            bestboard     = playf;

            return(-10000);
        }