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(ActionType.USE_HERO_POWER, 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(ActionType.USE_HERO_POWER, posmoves[0].enemyHeroAblility, null, 0, null, abilityPenality, 0); Playfield pf = new Playfield(posmoves[0]); pf.doAction(a); posmoves.Add(pf); } } } foreach (Minion m in posmoves[0].enemyMinions) { if (m.Angr == 0) { continue; } m.numAttacksThisTurn = 0; m.playedThisTurn = false; m.updateReadyness(); } 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); } }
//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); }
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); }
public void autoTester(bool printstuff, string data = "", bool logg = true) { help.logg("simulating board "); BoardTester bt = new BoardTester(data); if (!bt.datareaded) { return; } //calculate the stuff posmoves.Clear(); posmoves.Add(new Playfield()); posmoves[0].sEnemTurn = Settings.Instance.simulateEnemysTurn; if (logg) { help.logg("readed:"); help.logg(posmoves[0].getCompleteBoardForSimulating("", "", "")); } if (logg) { foreach (Playfield p in this.posmoves) { p.value = botBase.GetPlayfieldValue(p); p.printBoard(); } } help.logg("ownminionscount " + posmoves[0].ownMinions.Count); help.logg("owncardscount " + posmoves[0].owncards.Count); foreach (var item in this.posmoves[0].owncards) { if (item.canplayCard(posmoves[0])) { help.logg("card " + item.card.name + " is playable :" + item.canplayCard(posmoves[0]) + " cost/mana: " + item.manacost + "/" + posmoves[0].mana); } } if (Playfield.Instance.ownAbilityReady) { if (posmoves[0].ownHeroAblility.card.canplayCard(posmoves[0], 2)) { 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); } } else { help.logg("ability is NOT READY"); } // lethalcheck + normal DateTime strt = DateTime.Now; doallmoves(false, true); help.logg("calculated " + (DateTime.Now - strt).TotalSeconds); double timeneeded = 0; if (bestmoveValue < 8500) { posmoves.Clear(); posmoves.Add(new Playfield()); posmoves[0].sEnemTurn = Settings.Instance.simulateEnemysTurn; strt = DateTime.Now; doallmoves(false, false); timeneeded = (DateTime.Now - strt).TotalSeconds; help.logg("calculated 2 " + (DateTime.Now - strt).TotalSeconds); } if (printstuff) { this.mainTurnSimulator.printPosmoves(); simmulateWholeTurn(this.mainTurnSimulator.bestboard); help.logg("Best Board Actions:"); this.mainTurnSimulator.bestboard.printActions(); help.logg(""); help.logg("calculated " + timeneeded); } if (bt.boardToSimulate >= 0) { int input = 0; while (input >= 0) { Console.WriteLine("write Index of board you want to simulate:"); String cnslrdl = Console.ReadLine(); try { input = Convert.ToInt32(cnslrdl); simmulateWholeTurn(this.mainTurnSimulator.getBoard(input)); } catch { Console.WriteLine("testmode ended..."); input = -1; } } } else { //Console.WriteLine("notestmode"); } }