public void simmulateWholeTurn() { help.ErrorLog("########################################################################################################"); help.ErrorLog("simulate best board"); help.ErrorLog("########################################################################################################"); //this.bestboard.printActions(); Playfield tempbestboard = new Playfield(); tempbestboard.printBoard(); if (bestmove != null && bestmove.actionType != actionEnum.endturn) // save the guessed move, so we doesnt need to recalc! { bestmove.print(); tempbestboard.doAction(bestmove); } else { tempbestboard.mana = -100; } help.logg("-------------"); tempbestboard.printBoard(); foreach (Action bestmovee in this.bestActions) { help.logg("stepp"); if (bestmovee != null && bestmovee.actionType != actionEnum.endturn) // save the guessed move, so we doesnt need to recalc! { bestmovee.print(); tempbestboard.doAction(bestmovee); } else { tempbestboard.mana = -100; } help.logg("-------------"); tempbestboard.printBoard(); } //help.logg("AFTER ENEMY TURN:" ); tempbestboard.sEnemTurn = true; tempbestboard.endTurn(false, this.playaround, false, Settings.Instance.playaroundprob, Settings.Instance.playaroundprob2); help.logg("ENEMY TURN:-----------------------------"); tempbestboard.value = int.MinValue; tempbestboard.prepareNextTurn(tempbestboard.isOwnTurn); Ai.Instance.enemyTurnSim[0].simulateEnemysTurn(tempbestboard, true, playaround, true, Settings.Instance.playaroundprob, Settings.Instance.playaroundprob2); }
public void simmulateWholeTurnandPrint() { help.ErrorLog("###################################"); help.ErrorLog("what would silverfish do?---------"); help.ErrorLog("###################################"); if (this.bestmoveValue >= 10000) help.ErrorLog("DETECTED LETHAL ###################################"); //this.bestboard.printActions(); Playfield tempbestboard = new Playfield(); if (bestmove != null && bestmove.actionType != actionEnum.endturn) // save the guessed move, so we doesnt need to recalc! { tempbestboard.doAction(bestmove); tempbestboard.printActionforDummies(tempbestboard.playactions[tempbestboard.playactions.Count - 1]); if (this.bestActions.Count == 0) { help.ErrorLog("end turn"); } } else { tempbestboard.mana = -100; help.ErrorLog("end turn"); } foreach (Action bestmovee in this.bestActions) { if (bestmovee != null && bestmove.actionType != actionEnum.endturn) // save the guessed move, so we doesnt need to recalc! { //bestmovee.print(); tempbestboard.doAction(bestmovee); tempbestboard.printActionforDummies(tempbestboard.playactions[tempbestboard.playactions.Count - 1]); } else { tempbestboard.mana = -100; help.ErrorLog("end turn"); } } }
public void simmulateWholeTurn() { help.ErrorLog("####################################################"); help.logg("simulate best board"); help.ErrorLog("####################################################"); //this.bestboard.printActions(); Playfield tempbestboard = new Playfield(); if (bestmove != null) // save the guessed move, so we doesnt need to recalc! { bestmove.print(); tempbestboard.doAction(bestmove); } else { tempbestboard.mana = -100; } help.logg("-------------"); tempbestboard.printBoard(); foreach (Action bestmovee in bestboard.playactions) { help.logg("stepp"); if (bestmovee != null) // save the guessed move, so we doesnt need to recalc! { bestmovee.print(); tempbestboard.doAction(bestmovee); } else { tempbestboard.mana = -100; } help.logg("-------------"); tempbestboard.printBoard(); } help.logg("AFTER ENEMY TURN:"); tempbestboard.sEnemTurn = this.simulateEnemyTurn; tempbestboard.endTurn(this.secondturnsim, this.playaround, true); }
public void simmulateWholeTurnandPrint() { help.ErrorLog("####################################################"); help.ErrorLog("what would silverfish do?---------"); help.ErrorLog("####################################################"); //this.bestboard.printActions(); Playfield tempbestboard = new Playfield(); if (bestmove != null) // save the guessed move, so we doesnt need to recalc! { tempbestboard.printActionforDummies(bestmove); tempbestboard.doAction(bestmove); } else { tempbestboard.mana = -100; help.ErrorLog("end turn"); } foreach (Action bestmovee in bestboard.playactions) { tempbestboard.printActionforDummies(bestmovee); if (bestmovee != null) // save the guessed move, so we doesnt need to recalc! { bestmovee.print(); tempbestboard.doAction(bestmovee); } else { tempbestboard.mana = -100; help.ErrorLog("end turn"); } } }
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; }
public void simulateEnemysTurn(Playfield rootfield, bool simulateTwoTurns, bool playaround, bool print, int pprob, int pprob2) { bool havedonesomething = true; posmoves.Clear(); if (print) { Helpfunctions.Instance.ErrorLog("board at enemyturn start-----------------------------"); rootfield.printBoard(); } posmoves.Add(new Playfield(rootfield)); //posmoves[0].prepareNextTurn(false); List<Playfield> temp = new List<Playfield>(); int deep = 0; int enemMana = rootfield.enemyMaxMana; if (print) { Console.WriteLine("enemMana "+ enemMana); } //playing aoe-effects if activated (and we didnt play loatheb) if (playaround && rootfield.ownloatheb == 0) { float oldval = Ai.Instance.botBase.getPlayfieldValue(posmoves[0]); posmoves[0].value = int.MinValue; enemMana = posmoves[0].EnemyCardPlaying(rootfield.enemyHeroName, enemMana, rootfield.enemyAnzCards, pprob, pprob2); float newval = Ai.Instance.botBase.getPlayfieldValue(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.ownSaboteur == 0)//loatheb doesnt do anything to heropower { 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.getTargetsForCardEnemy(posmoves[0]); foreach (Minion trgt in trgts) { if (trgt.isHero) continue; 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.hasInspire) 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; while (havedonesomething) { temp.Clear(); temp.AddRange(posmoves); havedonesomething = false; Playfield bestold = null; float bestoldval = 20000000; //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); boardcount++; } p.endEnemyTurn(); //p.guessingHeroHP = rootfield.guessingHeroHP; if (Ai.Instance.botBase.getPlayfieldValue(p) < bestoldval) // want the best enemy-play-> worst for us { bestoldval = Ai.Instance.botBase.getPlayfieldValue(p); bestold = p; } posmoves.Remove(p); if (boardcount >= maxwide) break; } if (bestoldval <= 10000 && bestold != null) { posmoves.Add(bestold); } 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 = Ai.Instance.botBase.getPlayfieldValue(p); if (bestval > val)// we search the worst value { bestplay = p; bestval = val; } } if (print) { Helpfunctions.Instance.ErrorLog("best enemy board----------------------------------"); bestplay.printBoard(); } rootfield.value = bestplay.value; if (simulateTwoTurns && bestplay.value > -1000) { bestplay.prepareNextTurn(true); rootfield.value = Settings.Instance.firstweight * bestval + Settings.Instance.secondweight * Ai.Instance.nextTurnSimulator[this.thread].doallmoves(bestplay, false, print); } }
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 void simulateEnemysTurn(Playfield rootfield, bool simulateTwoTurns, bool playaround, bool print, int pprob, int pprob2) { bool havedonesomething = true; posmoves.Clear(); posmoves.Add(new Playfield(rootfield)); //posmoves[0].prepareNextTurn(false); List<Playfield> temp = new List<Playfield>(); int deep = 0; int enemMana = Math.Min(rootfield.enemyMaxMana + 1, 10); if (playaround && !rootfield.loatheb) { float oldval = Ai.Instance.botBase.getPlayfieldValue(posmoves[0]); posmoves[0].value = int.MinValue; enemMana = posmoves[0].EnemyCardPlaying(rootfield.enemyHeroName, enemMana, rootfield.enemyAnzCards, pprob, pprob2); float newval = Ai.Instance.botBase.getPlayfieldValue(posmoves[0]); posmoves[0].value = int.MinValue; 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.loatheb) { int abilityPenality = 0; havedonesomething = true; // if we have mage or priest, we have to target something#################################################### if (posmoves[0].enemyHeroName == HeroEnum.mage || posmoves[0].enemyHeroName == HeroEnum.priest) { List<Minion> trgts = posmoves[0].enemyHeroAblility.card.getTargetsForCardEnemy(posmoves[0]); foreach (Minion trgt in trgts) { if (trgt.isHero) continue; 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 { // the other classes dont have to target#################################################### 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); } } foreach (Minion m in posmoves[0].enemyMinions) { if (m.Angr == 0) continue; m.numAttacksThisTurn = 0; m.playedThisTurn = false; m.updateReadyness(); } doSomeBasicEnemyAi(posmoves[0]); int count = 0; //movegen... while (havedonesomething) { temp.Clear(); temp.AddRange(posmoves); havedonesomething = false; Playfield bestold = null; float bestoldval = 20000000; foreach (Playfield p in temp) { 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); count++; } //p.endCurrentPlayersTurnAndStartTheNextOne(1, false); p.endEnemyTurn(); p.guessingHeroHP = rootfield.guessingHeroHP; if (Ai.Instance.botBase.getPlayfieldValue(p) < bestoldval) // want the best enemy-play-> worst for us { bestoldval = Ai.Instance.botBase.getPlayfieldValue(p); bestold = p; } posmoves.Remove(p); if (count >= maxwide) break; } if (bestoldval <= 10000 && bestold != null) { posmoves.Add(bestold); } deep++; if (count >= maxwide) break; } foreach (Playfield p in posmoves) { if (!p.complete) p.endEnemyTurn(); } float bestval = int.MaxValue; Playfield bestplay = posmoves[0]; foreach (Playfield p in posmoves) { p.guessingHeroHP = rootfield.guessingHeroHP; float val = Ai.Instance.botBase.getPlayfieldValue(p); if (bestval > val)// we search the worst value { bestplay = p; bestval = val; } } if (print) bestplay.printBoard(); rootfield.value = bestplay.value; if (simulateTwoTurns && bestplay.value > -1000) { bestplay.prepareNextTurn(true); rootfield.value = 0.5f * bestval + 0.5f * Ai.Instance.nextTurnSimulator.doallmoves(bestplay, false); } }
public void simulateEnemysTurn(Playfield rootfield, bool simulateTwoTurns, bool playaround, bool print, int pprob, int pprob2) { bool havedonesomething = true; posmoves.Clear(); if (print) { sf.Helpfunctions.ErrorLog("board at enemyturn start-----------------------------"); rootfield.printBoard(); } posmoves.Add(new Playfield(rootfield)); //posmoves[0].prepareNextTurn(false); List<Playfield> temp = new List<Playfield>(); int deep = 0; int enemMana = Math.Min(rootfield.enemyMaxMana + 1, 10); if (playaround && !rootfield.loatheb) { float oldval = sf.Ai.botBase.getPlayfieldValue(posmoves[0]); posmoves[0].value = int.MinValue; enemMana = posmoves[0].EnemyCardPlaying(rootfield.enemyHeroStartClass, enemMana, rootfield.enemyAnzCards, pprob, pprob2); float newval = sf.Ai.botBase.getPlayfieldValue(posmoves[0]); posmoves[0].value = int.MinValue; posmoves[0].enemyAnzCards--; posmoves[0].triggerCardsChanged(false); 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.loatheb) { int abilityPenality = 0; havedonesomething = true; // if we have mage/priest/hunter, we have to target something#################################################### if (posmoves[0].enemyHeroName == HeroEnum.mage || posmoves[0].enemyHeroName == HeroEnum.priest || posmoves[0].enemyHeroName == HeroEnum.hunter) { List<Minion> trgts = posmoves[0].enemyHeroAblility.card.getTargetsForCardEnemy(posmoves[0]); foreach (Minion trgt in trgts) { if (trgt.isHero) continue; 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 { // the other classes dont have to target#################################################### 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); } } foreach (Minion m in posmoves[0].enemyMinions) { if (m.Angr == 0) continue; m.numAttacksThisTurn = 0; m.playedThisTurn = false; m.updateReadyness(); } doSomeBasicEnemyAi(posmoves[0]); int boardcount = 0; //sf.Movegenerator... int i = 0; int count = 0; Playfield p = null; while (havedonesomething) { temp.Clear(); temp.AddRange(posmoves); havedonesomething = false; Playfield bestold = null; float bestoldval = 20000000; //foreach (Playfield p in temp) count = temp.Count; for (i = 0; i < count; i++) { p = temp[i]; if (p.complete) { continue; } List<Action> actions = sf.Movegenerator.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); boardcount++; } p.endEnemyTurn(); p.guessingHeroHP = rootfield.guessingHeroHP; if (sf.Ai.botBase.getPlayfieldValue(p) < bestoldval) // want the best enemy-play-> worst for us { bestoldval = sf.Ai.botBase.getPlayfieldValue(p); bestold = p; } posmoves.Remove(p); if (boardcount >= maxwide) break; } if (bestoldval <= 10000 && bestold != null) { posmoves.Add(bestold); } 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 = 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 = sf.Ai.botBase.getPlayfieldValue(p); if (bestval > val)// we search the worst value { bestplay = p; bestval = val; } } if (print) { sf.Helpfunctions.ErrorLog("best enemy board----------------------------------"); bestplay.printBoard(); } rootfield.value = bestplay.value; if (simulateTwoTurns && bestplay.value > -1000) { bestplay.prepareNextTurn(true); rootfield.value = sf.Settings.firstweight * bestval + sf.Settings.secondweight * sf.Ai.nextTurnSimulator[this.thread].doallmoves(bestplay, false, print); } }
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; }
private void reorderingActions() { if (bestplay.enemySecretCount > 0) return; if (bestplay.playactions.Count < 2) return; if (Ai.Instance.botBase.getPlayfieldValue(bestplay) < 10000) return; Playfield tmpPf = new Playfield(); if (tmpPf.anzEnemyTaunt > 0) return; List<Action> reorderedActions = new List<Action>(); Dictionary<Action, int> actDmgDict = new Dictionary<Action, int>(); tmpPf.enemyHero.Hp = 30; try { int useability = 0; foreach (Action a in bestplay.playactions) { if (a.actionType == actionEnum.useHeroPower) useability = 1; if (a.actionType == actionEnum.attackWithHero) useability++; int actDmd = tmpPf.enemyHero.Hp + tmpPf.enemyHero.armor; tmpPf.doAction(a); actDmd -= (tmpPf.enemyHero.Hp + tmpPf.enemyHero.armor); actDmgDict.Add(a, actDmd); } if (useability > 1) return; } catch { return; } foreach (var pair in actDmgDict.OrderByDescending(pair => pair.Value)) { reorderedActions.Add(pair.Key); } tmpPf = new Playfield(); foreach (Action a in reorderedActions) { bool found = false; switch (a.actionType) { case actionEnum.playcard: foreach (Handmanager.Handcard hc in tmpPf.owncards) { if (hc.entity == a.card.entity) { if (tmpPf.mana >= hc.card.getManaCost(tmpPf, hc.manacost)) found = true; break; } } break; case actionEnum.attackWithMinion: foreach (Minion m in tmpPf.ownMinions) { if (m.entityID == a.own.entityID) { if (!a.own.Ready) return; found = true; break; } } break; case actionEnum.attackWithHero: if (tmpPf.ownHero.Ready) found = true; break; case actionEnum.useHeroPower: if (tmpPf.ownAbilityReady && tmpPf.mana >= tmpPf.ownHeroAblility.card.getManaCost(tmpPf, tmpPf.ownHeroAblility.manacost)) found = true; break; } if (!found) return; tmpPf.doAction(a); } if (Ai.Instance.botBase.getPlayfieldValue(tmpPf) >= 10000) { bestplay.playactions.Clear(); bestActions.Clear(); bestplay.playactions.AddRange(reorderedActions); Helpfunctions.Instance.logg("Reordered actions:"); foreach (Action a in bestplay.playactions) { this.bestActions.Add(new Action(a)); a.print(); } } }