public List <Action> getMoveList(Playfield p, bool isLethalCheck, bool usePenalityManager, bool useCutingTargets) { //generates only own moves List <Action> ret = new List <Action>(); if (p.complete || p.ownHero.Hp <= 0) { return(ret); } //play cards: List <CardDB.cardName> playedcards = new List <CardDB.cardName>(); bool superplacement = false; bool useplacement = Settings.Instance.simulatePlacement && p.turnCounter == 0 && p.ownMinions.Count >= 2; foreach (Minion hc in p.ownMinions) { if (hc.handcard.card.name == CardDB.cardName.direwolfalpha || hc.handcard.card.name == CardDB.cardName.flametonguetotem || hc.handcard.card.name == CardDB.cardName.defenderofargus) { superplacement = true; break; } } foreach (Handmanager.Handcard hc in p.owncards) { 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) { ret.AddRange(this.doAllChoices(p, hc, isLethalCheck, usePenalityManager)); } else { int bestplace = p.getBestPlace(c, isLethalCheck); if (hc.canplayCard(p)) { List <Minion> trgts = c.getTargetsForCard(p); if (isLethalCheck && trgts.Count >= 1 && (c.damagesTarget || c.damagesTargetWithSpecial)) // only target enemy hero during Lethal check! { if (trgts.Count >= 1 && trgts[0].isHero && !trgts[0].own) // first minion is enemy hero (or he is not in list) { trgts.Clear(); trgts.Add(p.enemyHero); } else { // no enemy hero -> enemy have taunts ->kill the taunts from left to right if (trgts.Count >= 1) { Minion trg = trgts[0]; trgts.Clear(); trgts.Add(trg); } } } int cardplayPenality = 0; if (trgts.Count == 0) { if (usePenalityManager) { cardplayPenality = pen.getPlayCardPenality(c, null, p, 0, isLethalCheck); if (cardplayPenality <= 499) { if (useplacement && ((hc.card.name == CardDB.cardName.direwolfalpha || hc.card.name == CardDB.cardName.flametonguetotem || hc.card.name == CardDB.cardName.defenderofargus) || (superplacement && hc.card.type == CardDB.cardtype.MOB))) { int adding = 1; int subbing = 0; if (hc.card.name == CardDB.cardName.direwolfalpha || hc.card.name == CardDB.cardName.flametonguetotem)//|| hc.card.name == CardDB.cardName.defenderofargus) { adding = 2; subbing = 2; } for (int placer = 0; placer < p.ownMinions.Count - subbing; placer++) { Action a = new Action(actionEnum.playcard, hc, null, placer + adding, null, cardplayPenality, 0); //Helpfunctions.Instance.ErrorLog("place " +hc.card.name + " on pos " + (placer+adding) + " mincount " + p.ownMinions.Count); //pf.playCard(hc, hc.position - 1, hc.entity, -1, -1, 0, bestplace, cardplayPenality); ret.Add(a); } } else { Action a = new Action(actionEnum.playcard, hc, null, bestplace, null, cardplayPenality, 0); //pf.playCard(hc, hc.position - 1, hc.entity, -1, -1, 0, bestplace, cardplayPenality); ret.Add(a); } } } else { Action a = new Action(actionEnum.playcard, hc, null, bestplace, null, cardplayPenality, 0); //pf.playCard(hc, hc.position - 1, hc.entity, -1, -1, 0, bestplace, cardplayPenality); ret.Add(a); } } else { foreach (Minion trgt in trgts) { if (usePenalityManager) { cardplayPenality = pen.getPlayCardPenality(c, trgt, p, 0, isLethalCheck); if (cardplayPenality <= 499) { //pf.playCard(hc, hc.position - 1, hc.entity, trgt.target, trgt.targetEntity, 0, bestplace, cardplayPenality); Action a = new Action(actionEnum.playcard, hc, null, bestplace, trgt, cardplayPenality, 0); ret.Add(a); } } else { //pf.playCard(hc, hc.position - 1, hc.entity, trgt.target, trgt.targetEntity, 0, bestplace, cardplayPenality); Action a = new Action(actionEnum.playcard, hc, null, bestplace, trgt, cardplayPenality, 0); ret.Add(a); } } } } } } // attack with minions ############################################################################################################### List <Minion> playedMinions = new List <Minion>(8); bool attackordermatters = this.didAttackOrderMatters(p); foreach (Minion m in p.ownMinions) { 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) if (attackordermatters) { List <Minion> tempoo = new List <Minion>(playedMinions); bool dontattacked = true; bool isSpecial = m.handcard.card.isSpecialMinion; 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 = mnn.handcard.card.isSpecialMinion; 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 <Minion> trgts = p.getAttackTargets(true); if (isLethalCheck) // only target enemy hero during Lethal check! { if (trgts.Count >= 1 && trgts[0].isHero) // first minion is always hero if existent { trgts.Clear(); trgts.Add(p.enemyHero); } else { // no enemy hero -> enemy have taunts ->kill the taunts from left to right if (trgts.Count >= 1) { Minion trg = trgts[0]; trgts.Clear(); trgts.Add(trg); } } } else { if (useCutingTargets) { trgts = this.cutAttackTargets(trgts, p, true); } } foreach (Minion trgt in trgts) { int attackPenality = 0; if (usePenalityManager) { attackPenality = pen.getAttackWithMininonPenality(m, p, trgt, isLethalCheck); if (attackPenality <= 499) { //pf.attackWithMinion(m, trgt.target, trgt.targetEntity, attackPenality); Action a = new Action(actionEnum.attackWithMinion, null, m, 0, trgt, attackPenality, 0); ret.Add(a); } } else { //pf.attackWithMinion(m, trgt.target, trgt.targetEntity, attackPenality); Action a = new Action(actionEnum.attackWithMinion, null, m, 0, trgt, attackPenality, 0); ret.Add(a); } } if ((!m.stealth || isLethalCheck) && p.enemySecretCount == 0 && trgts.Count == 1 && trgts[0].isHero)//only enemy hero is available als attack { break; } if (!attackordermatters && !m.stealth) { break; } } } // attack with hero if (p.ownHero.Ready && p.ownHero.Angr >= 1) { List <Minion> trgts = p.getAttackTargets(true); if (isLethalCheck)// only target enemy hero during Lethal check! { if (trgts.Count >= 1 && trgts[0].isHero && !trgts[0].own) { trgts.Clear(); trgts.Add(p.enemyHero); } else { // no enemy hero -> enemy have taunts ->kill the taunts from left to right if (trgts.Count >= 1) { Minion trg = trgts[0]; trgts.Clear(); trgts.Add(trg); } } } else { if (useCutingTargets) { trgts = this.cutAttackTargets(trgts, p, true); } } foreach (Minion trgt in trgts) { int heroAttackPen = 0; if (usePenalityManager) { heroAttackPen = pen.getAttackWithHeroPenality(trgt, p, isLethalCheck); } //pf.attackWithWeapon(trgt.target, trgt.targetEntity, heroAttackPen); Action a = new Action(actionEnum.attackWithHero, null, p.ownHero, 0, trgt, heroAttackPen, 0); ret.Add(a); } } // use ability /// TODO check if ready after manaup if (p.ownAbilityReady && p.mana >= 2 && p.ownHeroAblility.card.canplayCard(p, 2)) { int abilityPenality = 0; // if we have mage or priest, we have to target something#################################################### if (p.ownHeroAblility.card.cardIDenum == CardDB.cardIDEnum.CS2_034 || p.ownHeroAblility.card.cardIDenum == CardDB.cardIDEnum.CS1h_001 || p.ownHeroAblility.card.cardIDenum == CardDB.cardIDEnum.EX1_625t || p.ownHeroAblility.card.cardIDenum == CardDB.cardIDEnum.EX1_625t2 || p.ownHeroAblility.card.cardIDenum == CardDB.cardIDEnum.DS1h_292) { List <Minion> trgts = p.ownHeroAblility.card.getTargetsForCard(p); if (isLethalCheck && (p.ownHeroName == HeroEnum.mage || (p.ownHeroName == HeroEnum.priest && (p.ownHeroAblility.card.name != CardDB.cardName.lesserheal || (p.ownHeroAblility.card.name == CardDB.cardName.lesserheal && p.anzOwnAuchenaiSoulpriest >= 1)))))// only target enemy hero during Lethal check! { if (trgts.Count >= 1 && trgts[0].entitiyID == p.enemyHero.entitiyID) { trgts.Clear(); trgts.Add(p.enemyHero); } else { // no enemy hero -> enemy have taunts ->kill the taunts from left to right if (trgts.Count >= 1) { Minion trg = trgts[0]; trgts.Clear(); trgts.Add(trg); } } } foreach (Minion trgt in trgts) { if (usePenalityManager) { abilityPenality = pen.getPlayCardPenality(p.ownHeroAblility.card, trgt, p, 0, isLethalCheck); if (abilityPenality <= 499) { //pf.activateAbility(p.ownHeroAblility, trgt.target, trgt.targetEntity, abilityPenality); Action a = new Action(actionEnum.useHeroPower, p.ownHeroAblility, null, 0, trgt, abilityPenality, 0); ret.Add(a); } } else { //pf.activateAbility(p.ownHeroAblility, trgt.target, trgt.targetEntity, abilityPenality); Action a = new Action(actionEnum.useHeroPower, p.ownHeroAblility, null, 0, trgt, abilityPenality, 0); ret.Add(a); } } } else { // the other classes dont have to target#################################################### //Playfield pf = new Playfield(p); if (usePenalityManager) { abilityPenality = pen.getPlayCardPenality(p.ownHeroAblility.card, null, p, 0, isLethalCheck); if (abilityPenality <= 499) { //havedonesomething = true; //pf.activateAbility(p.ownHeroAblility, -1, -1, abilityPenality); Action a = new Action(actionEnum.useHeroPower, p.ownHeroAblility, null, 0, null, abilityPenality, 0); ret.Add(a); } } else { //havedonesomething = true; //pf.activateAbility(p.ownHeroAblility, -1, -1, abilityPenality); Action a = new Action(actionEnum.useHeroPower, p.ownHeroAblility, null, 0, null, abilityPenality, 0); ret.Add(a); } } } return(ret); }
public List <Action> getMoveList(Playfield p, bool usePenalityManager, bool useCutingTargets, bool own) { //generates only own moves List <Action> ret = new List <Action>(); List <Minion> trgts = new List <Minion>(); if (p.complete || p.ownHero.Hp <= 0) { return(ret); } //play cards: if (own) { List <string> playedcards = new List <string>(); System.Text.StringBuilder cardNcost = new System.Text.StringBuilder(); foreach (Handmanager.Handcard hc in p.owncards) { int cardCost = hc.card.getManaCost(p, hc.manacost); if ((p.nextSpellThisTurnCostHealth && hc.card.type == CardDB.cardtype.SPELL) || (p.nextMurlocThisTurnCostHealth && (TAG_RACE)hc.card.race == TAG_RACE.MURLOC)) { if (p.ownHero.Hp > cardCost || p.ownHero.immune) { } else { continue; // if not enough Hp } } else if (p.mana < cardCost) { continue; // if not enough manna } CardDB.Card c = hc.card; cardNcost.Clear(); cardNcost.Append(c.name).Append(hc.manacost); if (playedcards.Contains(cardNcost.ToString())) { continue; // dont play the same card in one loop } playedcards.Add(cardNcost.ToString()); int isChoice = (c.choice) ? 1 : 0; bool choiceDamageFound = false; for (int choice = 0 + 1 * isChoice; choice < 1 + 2 * isChoice; choice++) { if (isChoice == 1) { c = pen.getChooseCard(hc.card, choice); // do all choice if (p.ownFandralStaghelm > 0) { if (choiceDamageFound) { break; } for (int i = 1; i < 3; i++) { CardDB.Card cTmp = pen.getChooseCard(hc.card, i); // do all choice if (pen.DamageTargetDatabase.ContainsKey(cTmp.name) || (p.anzOwnAuchenaiSoulpriest > 0 && pen.HealTargetDatabase.ContainsKey(cTmp.name))) { choice = i; choiceDamageFound = true; c = cTmp; break; } //- Draw a card must be at end in the Sim_xxx - then it will selected! } } } if (p.ownMinions.Count > 6 && (c.type == CardDB.cardtype.MOB || hc.card.type == CardDB.cardtype.MOB)) { continue; } trgts = c.getTargetsForCard(p, p.isLethalCheck, true); if (trgts.Count == 0) { continue; } int cardplayPenality = 0; int bestplace = p.getBestPlace(c.type == CardDB.cardtype.MOB ? c : hc.card, p.isLethalCheck); foreach (Minion trgt in trgts) { if (usePenalityManager) { cardplayPenality = pen.getPlayCardPenality(c, trgt, p); } if (cardplayPenality <= 499) { Action a = new Action(actionEnum.playcard, hc, null, bestplace, trgt, cardplayPenality, choice); ret.Add(a); } } } } } //get targets for Hero weapon and Minions ################################################################################### trgts = p.getAttackTargets(own, p.isLethalCheck); if (!p.isLethalCheck) { trgts = this.cutAttackList(trgts); } // attack with minions List <Minion> attackingMinions = new List <Minion>(8); foreach (Minion m in (own ? p.ownMinions : p.enemyMinions)) { if (m.Ready && m.Angr >= 1 && !m.frozen) { attackingMinions.Add(m); //* add non-attacing minions } } attackingMinions = this.cutAttackList(attackingMinions); foreach (Minion m in attackingMinions) { int attackPenality = 0; foreach (Minion trgt in trgts) { if (m.cantAttackHeroes && trgt.isHero) { continue; } if (usePenalityManager) { attackPenality = pen.getAttackWithMininonPenality(m, p, trgt); } if (attackPenality <= 499) { Action a = new Action(actionEnum.attackWithMinion, null, m, 0, trgt, attackPenality, 0); ret.Add(a); } } } // attack with hero (weapon) if ((own && p.ownHero.Ready && p.ownHero.Angr >= 1) || (!own && p.enemyHero.Ready && p.enemyHero.Angr >= 1)) { int heroAttackPen = 0; foreach (Minion trgt in trgts) { if ((own ? p.ownWeapon.cantAttackHeroes : p.enemyWeapon.cantAttackHeroes) && trgt.isHero) { continue; } if (usePenalityManager) { heroAttackPen = pen.getAttackWithHeroPenality(trgt, p); } if (heroAttackPen <= 499) { Action a = new Action(actionEnum.attackWithHero, null, (own ? p.ownHero : p.enemyHero), 0, trgt, heroAttackPen, 0); ret.Add(a); } } } //############################################################################################################# // use own ability if (own) { if (p.ownAbilityReady && p.mana >= p.ownHeroAblility.card.getManaCost(p, p.ownHeroAblility.manacost)) // if ready and enough manna { CardDB.Card c = p.ownHeroAblility.card; int isChoice = (c.choice) ? 1 : 0; for (int choice = 0 + 1 * isChoice; choice < 1 + 2 * isChoice; choice++) { if (isChoice == 1) { c = pen.getChooseCard(p.ownHeroAblility.card, choice); // do all choice } int cardplayPenality = 0; int bestplace = p.ownMinions.Count + 1; //we can not manage it trgts = p.ownHeroAblility.card.getTargetsForHeroPower(p, true); foreach (Minion trgt in trgts) { if (usePenalityManager) { cardplayPenality = pen.getPlayCardPenality(p.ownHeroAblility.card, trgt, p); } if (cardplayPenality <= 499) { Action a = new Action(actionEnum.useHeroPower, p.ownHeroAblility, null, bestplace, trgt, cardplayPenality, choice); ret.Add(a); } } } } } return(ret); }
private void doallmoves(bool test, Bot botBase, bool isLethalCheck) { bool havedonesomething = true; List <Playfield> temp = new List <Playfield>(); int deep = 0; while (havedonesomething) { help.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) { continue; } //take a card and play it List <string> playedcards = new List <string>(); foreach (Handmanager.Handcard hc in p.owncards) { 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); if (hc.canplayCard(p)) { havedonesomething = true; List <targett> trgts = c.getTargetsForCard(p); if (isLethalCheck && (penman.DamageTargetDatabase.ContainsKey(c.name) || penman.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 = penman.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); this.posmoves.Add(pf); } } else { Playfield pf = new Playfield(p); havedonesomething = true; pf.playCard(hc, hc.position - 1, hc.entity, -1, -1, 0, bestplace, cardplayPenality); this.posmoves.Add(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 = penman.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); this.posmoves.Add(pf); } } else { Playfield pf = new Playfield(p); havedonesomething = true; pf.playCard(hc, hc.position - 1, hc.entity, trgt.target, trgt.targetEntity, 0, bestplace, cardplayPenality); this.posmoves.Add(pf); } } } } } } //attack with a minion List <Minion> playedMinions = new List <Minion>(8); foreach (Minion m in p.ownMinions) { 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 = penman.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 = penman.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(); 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); } } foreach (targett trgt in trgts) { int attackPenality = 0; if (usePenalityManager) { attackPenality = penman.getAttackWithMininonPenality(m, p, trgt.target, isLethalCheck); if (attackPenality <= 499) { Playfield pf = new Playfield(p); havedonesomething = true; pf.attackWithMinion(m, trgt.target, trgt.targetEntity, attackPenality); this.posmoves.Add(pf); } } else { Playfield pf = new Playfield(p); havedonesomething = true; pf.attackWithMinion(m, trgt.target, trgt.targetEntity, attackPenality); this.posmoves.Add(pf); } } if (trgts.Count == 1 && trgts[0].target == 200)//only enemy hero is available als attack { break; } } } // attack with hero if (p.ownHeroReady) { List <targett> trgts = p.getAttackTargets(); 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); } } foreach (targett trgt in trgts) { Playfield pf = new Playfield(p); int heroAttackPen = 0; if (usePenalityManager) { heroAttackPen = penman.getAttackWithHeroPenality(trgt.target, p); } pf.attackWithWeapon(trgt.target, trgt.targetEntity, heroAttackPen); this.posmoves.Add(pf); } } // use ability /// TODO check if ready after manaup if (p.ownAbilityReady && p.mana >= 2 && p.ownHeroAblility.canplayCard(p, 2)) { int abilityPenality = 0; havedonesomething = true; // if we have mage or priest, we have to target something#################################################### if (this.hp.heroname == "mage" || this.hp.heroname == "priest") { List <targett> trgts = p.ownHeroAblility.getTargetsForCard(p); if (isLethalCheck && (this.hp.heroname == "mage" || (this.hp.heroname == "priest" && p.ownHeroAblility.name != "lesserheal")))// 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 = penman.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); this.posmoves.Add(pf); } } else { Playfield pf = new Playfield(p); havedonesomething = true; pf.activateAbility(p.ownHeroAblility, trgt.target, trgt.targetEntity, abilityPenality); this.posmoves.Add(pf); } } } else { // the other classes dont have to target#################################################### Playfield pf = new Playfield(p); if (usePenalityManager) { abilityPenality = penman.getPlayCardPenality(p.ownHeroAblility, -1, pf, 0, isLethalCheck); if (abilityPenality <= 499) { havedonesomething = true; pf.activateAbility(p.ownHeroAblility, -1, -1, abilityPenality); this.posmoves.Add(pf); } } else { havedonesomething = true; pf.activateAbility(p.ownHeroAblility, -1, -1, abilityPenality); this.posmoves.Add(pf); } } } p.endTurn(); //sort stupid stuff ouf if (botBase.getPlayfieldValue(p) > bestoldval) { bestoldval = botBase.getPlayfieldValue(p); bestold = p; } if (!test) { posmoves.Remove(p); } } if (!test && bestoldval >= -10000 && bestold != null) { this.posmoves.Add(bestold); } help.loggonoff(true); int donec = 0; foreach (Playfield p in posmoves) { if (p.complete) { donec++; } } help.logg("deep " + deep + " len " + this.posmoves.Count + " dones " + donec); if (!test) { cuttingposibilities(botBase); } help.logg("cut to len " + this.posmoves.Count); help.loggonoff(false); deep++; if (deep >= this.maxdeep) { break; //remove this? } } int bestval = int.MinValue; int bestanzactions = 1000; Playfield bestplay = temp[0]; foreach (Playfield p in 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; } } help.loggonoff(true); help.logg("-------------------------------------"); help.logg("bestPlayvalue " + bestval); bestplay.printActions(); this.bestmove = bestplay.getNextAction(); this.bestmoveValue = bestval; this.bestboard = new Playfield(bestplay); /*if (bestmove != null && bestmove.cardplay && bestmove.handcard.card.type == CardDB.cardtype.MOB) * { * Playfield pf = new Playfield(); * help.logg("bestplaces:"); * pf.getBestPlacePrint(bestmove.card); * }*/ if (bestmove != null) // save the guessed move, so we doesnt need to recalc! { this.nextMoveGuess = new Playfield(); if (bestmove.cardplay) { //pf.playCard(c, hc.position - 1, hc.entity, trgt.target, trgt.targetEntity, 0, bestplace, cardplayPenality); Handmanager.Handcard hc = this.nextMoveGuess.owncards.Find(x => x.entity == bestmove.cardEntitiy); if (bestmove.owntarget >= 0 && bestmove.enemytarget >= 0 && bestmove.enemytarget <= 9 && bestmove.owntarget < bestmove.enemytarget) { this.nextMoveGuess.playCard(bestmove.handcard, hc.position - 1, hc.entity, bestmove.enemytarget - 1, bestmove.enemyEntitiy, bestmove.druidchoice, bestmove.owntarget, 0); } else { this.nextMoveGuess.playCard(bestmove.handcard, hc.position - 1, hc.entity, bestmove.enemytarget, bestmove.enemyEntitiy, bestmove.druidchoice, bestmove.owntarget, 0); } //this.nextMoveGuess.playCard(bestmove.card, hc.position - 1, hc.entity, bestmove.enemytarget, bestmove.enemyEntitiy, bestmove.druidchoice, bestmove.owntarget, 0); } if (bestmove.minionplay) { //.attackWithMinion(m, trgt.target, trgt.targetEntity, attackPenality); Minion m = this.nextMoveGuess.ownMinions.Find(x => x.entitiyID == bestmove.ownEntitiy); this.nextMoveGuess.attackWithMinion(m, bestmove.enemytarget, bestmove.enemyEntitiy, 0); } if (bestmove.heroattack) { this.nextMoveGuess.attackWithWeapon(bestmove.enemytarget, bestmove.enemyEntitiy, 0); } if (bestmove.useability) { //.activateAbility(p.ownHeroAblility, trgt.target, trgt.targetEntity, abilityPenality); this.nextMoveGuess.activateAbility(this.nextMoveGuess.ownHeroAblility, bestmove.enemytarget, bestmove.enemyEntitiy, 0); } this.bestboard.playactions.RemoveAt(0); } else { nextMoveGuess.mana = -1; } }
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 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); } } } } } } //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); } } // 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); } } } 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); }
public List <Action> getMoveList(Playfield p, bool isLethalCheck, bool usePenalityManager, bool useCutingTargets) { //generates only own moves List <Action> ret = new List <Action>(); List <Minion> trgts = new List <Minion>(); if (p.complete || p.ownHero.Hp <= 0) { return(ret); } //play cards: List <CardDB.cardName> playedcards = new List <CardDB.cardName>(); foreach (Handmanager.Handcard hc in p.owncards) { CardDB.Card c = hc.card; if (playedcards.Contains(c.name) || !hc.canplayCard(p)) { continue; // dont play the same card in one loop } playedcards.Add(c.name); int isChoice = (c.choice) ? 1 : 0; for (int i = 0 + 1 * isChoice; i < 1 + 2 * isChoice; i++) { if (isChoice == 1) { c = pen.getChooseCard(hc.card, i); // do all choice } if (p.mana >= c.getManaCost(p, hc.manacost)) // if enough manna { int cardplayPenality = 0; int bestplace = p.getBestPlace(c, isLethalCheck); trgts = c.getTargetsForCard(p, isLethalCheck); foreach (Minion trgt in trgts) { if (usePenalityManager) { cardplayPenality = pen.getPlayCardPenality(hc.card, trgt, p, i, isLethalCheck); } if (cardplayPenality <= 499) { Action a = new Action(actionEnum.playcard, hc, null, bestplace, trgt, cardplayPenality, i); //i is the choice ret.Add(a); } } } } } foreach (Action a in ret) { if (a.actionType == actionEnum.playcard) { bool isCardValid = false; foreach (Handmanager.Handcard hh in p.owncards) { if (hh.entity == a.card.entity) { isCardValid = true; break; } } if (!isCardValid) { int debug1 = 1; } } } //get targets for Hero weapon and Minions ################################################################################### trgts = p.getAttackTargets(true, isLethalCheck); if (!isLethalCheck) { trgts = this.cutAttackList(trgts); } // attack with minions List <Minion> attackingMinions = new List <Minion>(8); foreach (Minion m in p.ownMinions) { if (m.Ready && m.Angr >= 1 && !m.frozen) { attackingMinions.Add(m); //* add non-attacing minions } } attackingMinions = this.cutAttackList(attackingMinions); foreach (Minion m in attackingMinions) { int attackPenality = 0; foreach (Minion trgt in trgts) { if (usePenalityManager) { attackPenality = pen.getAttackWithMininonPenality(m, p, trgt, isLethalCheck); } if (attackPenality <= 499) { Action a = new Action(actionEnum.attackWithMinion, null, m, 0, trgt, attackPenality, 0); ret.Add(a); } } } // attack with hero (weapon) if (p.ownHero.Ready && p.ownHero.Angr >= 1) { int heroAttackPen = 0; foreach (Minion trgt in trgts) { if (usePenalityManager) { heroAttackPen = pen.getAttackWithHeroPenality(trgt, p, isLethalCheck); } if (heroAttackPen <= 499) { Action a = new Action(actionEnum.attackWithHero, null, p.ownHero, 0, trgt, heroAttackPen, 0); ret.Add(a); } } } //############################################################################################################# // use ability if (p.ownAbilityReady && p.mana >= p.ownHeroAblility.card.getManaCost(p, 2)) // if ready and enough manna { int cardplayPenality = 0; int bestplace = p.ownMinions.Count + 1; //we can not manage it trgts = p.ownHeroAblility.card.getTargetsForCard(p, isLethalCheck); foreach (Minion trgt in trgts) { if (usePenalityManager) { cardplayPenality = pen.getPlayCardPenality(p.ownHeroAblility.card, trgt, p, 0, isLethalCheck); } if (cardplayPenality <= 499) { Action a = new Action(actionEnum.useHeroPower, p.ownHeroAblility, null, bestplace, trgt, cardplayPenality, 0); //if (trgt.own == true) //{ // sf.helpfunctions.logg("ping on own minion"); //} ret.Add(a); } } } return(ret); }