public override void OnAttack(Board board, Card attacker, Card target) { bool IsAttackingWithHero = (attacker.Id == board.HeroFriend.Id); bool IsAttackingWithWeapon = (board.WeaponFriend != null && attacker.Id == board.WeaponFriend.Id); if ((IsAttackingWithHero || IsAttackingWithWeapon) && board.WeaponFriend != null) //If we attack with weapon equipped { switch (board.WeaponFriend.Template.Id) { } } if (!IsAttackingWithHero && !IsAttackingWithWeapon) { if (target != null && target.CurrentAtk >= attacker.CurrentHealth && !attacker.IsDivineShield) { OnMinionDeath(board, attacker); } } if (BoardHelper.IsFirstMove(board)) { OnFirstAction(board, attacker, target, false, true, false); } //DebugLog("ATTACKER: " + attacker.Template.Name + ", standard value: " + GetCardValue(board, attacker) + ", added cost: " + WeaponAttackGlobalCost + "; TARGET: " + ", standard value: " + GetCardValue(board, target)); //DebugBestLog("BEST ATTACKER: " + attacker.Template.Name + ", standard value: " + GetCardValue(board, attacker) + ", added cost: " + WeaponAttackGlobalCost + "; TARGET: " + ", standard value: " + GetCardValue(board, target)); }
private void SetMainValues(Board b) { MinionEnemyTauntAddedValue = 5; MinionEnemyWindfuryAddedValue = 2.5f; MinionDivineShieldAddedValue = 2; FriendCardDrawMultiplier = 3f; EnemyCardDrawMultiplier = 1; if (BoardHelper.GetOwnHP(b) - BoardHelper.GetEnemyHP(b) > 15) { HeroEnemyHealthMultiplier = 1; } else { HeroEnemyHealthMultiplier = 1; } if (BoardHelper.GetOwnHP(b) < 15 && BoardHelper.IsAggroClass(b.EnemyClass)) { HeroFriendHealthMultiplier = 2; } else { HeroFriendHealthMultiplier = 1; } MinionEnemyAttackMultiplier = 1; MinionEnemyHealthMultiplier = 1; MinionFriendAttackMultiplier = 1; MinionFriendHealthMultiplier = 1; }
public override void OnCastWeapon(Board board, Card weapon, Card target) { switch (weapon.Template.Id) { case Card.Cards.FP1_021: //Death's Bite, ID: FP1_021 if (board.WeaponFriend != null && GetThreatModifier(target) == 0) { WeaponCastGlobalCost += 10; } WeaponCastGlobalValue += board.MinionFriend.FindAll(x => _enrageableMinions.Contains(x.Template.Id) && x.CurrentHealth > 1).Count; WeaponCastGlobalValue += board.Hand.FindAll(x => _enrageableMinions.Contains(x.Template.Id) && board.ManaAvailable + 1 >= x.CurrentCost).Count; break; case Card.Cards.CS2_106: //Fiery War Axe, ID: CS2_106 if (board.WeaponFriend != null) { WeaponCastGlobalCost += 10; } break; } if (BoardHelper.IsFirstMove(board)) { OnFirstAction(board, weapon, target, false, false, false); } //DebugLog("WEAPON: " + weapon.Template.Name + ", standard value: " + GetCardValue(board, weapon) + ", added value: " + WeaponCastGlobalValue + ", added cost: " + WeaponCastGlobalCost + "; TARGET: " + ", standard value: " + GetCardValue(board, target)); //DebugBestLog("BEST WEAPON: " + weapon.Template.Name + ", standard value: " + GetCardValue(board, weapon) + ", added value: " + WeaponCastGlobalValue + ", added cost: " + WeaponCastGlobalCost + "; TARGET: " + ", standard value: " + GetCardValue(board, target)); }
public override void OnCastAbility(Board board, Card ability, Card target) { if (BoardHelper.GetOwnHP(board) <= 15) { HeroPowerGlobalCost -= 10; } if (board.TurnCount < 2) { HeroPowerGlobalCost += 10; } HeroPowerGlobalCost += 2; if (BoardHelper.IsFirstMove(board)) { OnFirstAction(board, ability, target, false, false, true); } //DebugLog("ABILITY: " + ability.Template.Name + ", standard value: " + GetCardValue(board, ability) + ", added cost: " + HeroPowerGlobalCost + "; TARGET: " + ", standard value: " + GetCardValue(board, target)); //DebugBestLog("BEST ABILITY: " + ability.Template.Name + ", standard value: " + GetCardValue(board, ability) + ", added cost: " + HeroPowerGlobalCost + "; TARGET: " + ", standard value: " + GetCardValue(board, target)); }
public float GetCardValue(Board board, Card card) { float value = 0; //divine shield value if (card.IsDivineShield) { value += MinionDivineShieldAddedValue; } if (card.IsFriend) { value += card.CurrentHealth * MinionFriendHealthMultiplier + card.CurrentAtk * MinionFriendAttackMultiplier; if (card.IsFrozen) { value -= 1; } } else { value += GetThreatModifier(card); //Taunt value if (card.IsTaunt) { value += BoardHelper.GetEnemyTauntValue(board); } float windfury = 1; if (card.IsWindfury) { windfury = 2; } value += card.CurrentHealth * MinionEnemyHealthMultiplier + card.CurrentAtk * MinionEnemyAttackMultiplier * windfury; } return(value); }
public void OnFirstAction(Board board, Card minion, Card target, bool castCard, bool attackCard, bool castAbility) { if (board.Hand.Any(x => x.Template.Id == Card.Cards.GVG_074)) { if (minion.Template.Id == Card.Cards.GVG_074) { SecretModifier += 50; } return; } Card.CClass enemyclass = board.EnemyClass; bool lowestValueActor = false; if (minion != null && board.GetWorstMinionCanAttack() != null && board.GetWorstMinionCanAttack().Id == minion.Id && castCard) { lowestValueActor = true; } else if (minion != null && board.GetWorstMinionFromHand() != null && board.GetWorstMinionFromHand().Id == minion.Id && castCard) { lowestValueActor = true; } switch (enemyclass) { case Card.CClass.HUNTER: if (castAbility && minion.Template.Id == Card.Cards.CS1h_001 && target.Type == Card.CType.MINION && target.IsFriend && target.CurrentHealth <= 2 && target.MaxHealth >= 3) { SecretModifier += 20; } if (castCard && minion.Template.Id == Card.Cards.FP1_007) { SecretModifier += 50; } if (castCard && minion.Template.Id == Card.Cards.EX1_093) { if ((board.GetLeftMinion(minion) != null && board.GetLeftMinion(minion).CurrentHealth == 2) && (board.GetRightMinion(minion) != null && board.GetRightMinion(minion).CurrentHealth == 2)) { if (BoardHelper.Get2HpMinions(board) > 1) { SecretModifier += 50; } } else if (board.GetLeftMinion(minion) != null && board.GetLeftMinion(minion).CurrentHealth == 2) { if (BoardHelper.Get2HpMinions(board) > 0) { SecretModifier += 25; } } else if (board.GetRightMinion(minion) != null && board.GetRightMinion(minion).CurrentHealth == 2) { if (BoardHelper.Get2HpMinions(board) > 0) { SecretModifier += 25; } } } if (attackCard) { if (lowestValueActor && !board.TrapMgr.TriggeredHeroWithMinion) { if (BoardHelper.GetWeakMinions(board) > 1 && board.MinionEnemy.Count > 0) { if (target.Type == Card.CType.HERO) { if (board.MinionEnemy.Count == 0 || BoardHelper.GetCanAttackMinions(board) == 1) { SecretModifier += 5; } else { SecretModifier -= BoardHelper.GetWeakMinions(board) * 3; } } if (target.Type == Card.CType.MINION) { SecretModifier += 2.5f; } } } if (!lowestValueActor && (!board.TrapMgr.TriggeredHeroWithMinion || !board.TrapMgr.TriggeredMinionWithMinion)) { SecretModifier -= 1.5f; } } else { SecretModifier -= 5; } break; case Card.CClass.MAGE: if (!board.TrapMgr.TriggeredCastMinion && lowestValueActor && castCard) { SecretModifier += 25; } break; case Card.CClass.PALADIN: if (!board.TrapMgr.TriggeredHeroWithMinion && lowestValueActor && minion != null && castCard && target != null && target.Type == Card.CType.HERO && attackCard) { SecretModifier += 5; } break; } if (castCard) { board.TrapMgr.TriggeredCastMinion = true; } else if (castAbility) { } else if (attackCard) { if (target != null && target.Type == Card.CType.HERO) { board.TrapMgr.TriggeredHeroWithMinion = true; } if (target != null && target.Type == Card.CType.MINION) { board.TrapMgr.TriggeredMinionWithMinion = true; } } }
public override void OnCastSpell(Board board, Card spell, Card target) { switch (spell.Template.Id) { case Card.Cards.EX1_392: //Battle Rage SpellsCastGlobalCost += 3; SpellsCastGlobalValue += board.MinionFriend.FindAll(x => x.CurrentHealth < x.MaxHealth).Count *FriendCardDrawMultiplier + (board.HeroFriend.CurrentHealth < 30 ? 1 : 0) * FriendCardDrawMultiplier; break; case Card.Cards.CS2_108: //Execute SpellsCastGlobalCost += MIN_VALUE_EXECUTE; break; case Card.Cards.EX1_607: //Inner Rage if (board.MinionEnemy.Contains(target)) { SpellsCastGlobalCost += 10; } if (board.MinionFriend.Contains(target)) { SpellsCastGlobalCost += 8; } if (board.MinionFriend.Contains(target) && BoardHelper.CanBeEnraged(target, _enrageableMinions) && target.CanAttack) { SpellsCastGlobalValue += 4; } if (board.MinionFriend.Contains(target) && BoardHelper.CanBeEnraged(target, _bestEnrageableMinions) && target.CanAttack) { SpellsCastGlobalValue += 10; } break; case Card.Cards.EX1_391: //Slam if (board.MinionEnemy.Contains(target) && BoardHelper.CanImmediatelyKill(target, spell.CurrentAtk)) { SpellsCastGlobalCost += 6; } if (board.MinionEnemy.Contains(target) && !BoardHelper.CanImmediatelyKill(target, spell.CurrentAtk)) { SpellsCastGlobalCost += 4; } if (board.MinionFriend.Contains(target) && BoardHelper.CanImmediatelyKill(target, spell.CurrentAtk)) { SpellsCastGlobalCost += NEVER_PLAY; } if (board.MinionFriend.Contains(target) && !BoardHelper.CanBeEnraged(target, _bestEnrageableMinions) && board.Hand.Count > 1) { SpellsCastGlobalCost += NEVER_PLAY; } if (board.MinionFriend.Contains(target) && BoardHelper.CanBeEnraged(target, _bestEnrageableMinions)) { SpellsCastGlobalValue += 2; } break; case Card.Cards.EX1_400: //Whirlwind SpellsCastGlobalCost += 6; SpellsCastGlobalValue += board.MinionEnemy.FindAll(x => x.CurrentHealth == 1).Count * 2 - board.MinionFriend.FindAll(x => x.CurrentHealth == 1).Count * 2; SpellsCastGlobalValue += board.MinionFriend.FindAll(x => _enrageableMinions.Contains(x.Template.Id) && !_bestEnrageableMinions.Contains(x.Template.Id) && x.CurrentHealth > 1).Count * 2; SpellsCastGlobalValue += board.MinionFriend.FindAll(x => _bestEnrageableMinions.Contains(x.Template.Id) && x.CurrentHealth > 1).Count * 3; break; case Card.Cards.GAME_005: //The Coin SpellsCastGlobalCost += GetCoinValue(board); break; } if (BoardHelper.IsFirstMove(board)) { OnFirstAction(board, spell, target, true, false, false); } //DebugLog("SPELL: " + spell.Template.Name + ", standard value: " + GetCardValue(board, spell) + ", added value: " + SpellsCastGlobalValue + ", added cost: " + SpellsCastGlobalCost + "; TARGET: " + ", standard value: " + GetCardValue(board, target)); //DebugBestLog("BEST SPELL: " + spell.Template.Name + ", standard value: " + GetCardValue(board, spell) + ", added value: " + SpellsCastGlobalValue + ", added cost: " + SpellsCastGlobalCost + "; TARGET: " + ", standard value: " + GetCardValue(board, target)); }
public override void OnCastMinion(Board board, Card minion, Card target) { switch (minion.Template.Id) { case Card.Cards.EX1_007: //Acolyte of Pain, ID: EX1_007 if (BoardHelper.CanBeImmediatelyKilledByEnemy(board, minion) && board.Hand.Count < CARDS_IN_HAND_THRESHHOLD) { MinionCastGlobalCost += GetCardValue(board, minion) * 0.3f; } break; case Card.Cards.EX1_402: //Armorsmith, ID: EX1_402 if (BoardHelper.CanBeImmediatelyKilledByEnemy(board, minion) && !BoardHelper.CanPlayCard(board, _enragingSpells, minion.CurrentCost)) { MinionCastGlobalCost += GetCardValue(board, minion) * 0.5f; } break; case Card.Cards.EX1_012: //Bloodmage Thalnos, ID: EX1_012 if (BoardHelper.CanBeImmediatelyKilledByEnemy(board, minion) || board.Hand.Count > CARDS_IN_HAND_THRESHHOLD || !BoardHelper.CanPlayCard(board, Card.Cards.EX1_400, minion.CurrentCost)) // EX1_400 - whirlwind { MinionCastGlobalCost += GetCardValue(board, minion) * 0.5f; } break; case Card.Cards.EX1_603: //Cruel Taskmaster, ID: EX1_603 if ((target.CurrentHealth == 1 && !BoardHelper.IsOwnMinion(board, target)) || BoardHelper.CanEnrageOrGetArmor(board, _enragingSpells, _enrageableMinions) || BoardHelper.CanExecute(board, MIN_VALUE_EXECUTE, minion.CurrentCost)) { MinionCastGlobalValue += 0; // GetCardValue(board, minion) * 1.3f; } else { MinionCastGlobalCost += GetCardValue(board, minion) * 0.5f; } break; case Card.Cards.NEW1_022: //Dread Corsair, ID: NEW1_022 if (BoardHelper.CanPlayDreadCorsair(board, minion)) { MinionCastGlobalValue += GetCardValue(board, minion) * 1.3f; } else { MinionCastGlobalCost += GetCardValue(board, minion) * 0.5f; } break; case Card.Cards.GVG_110: //Dr. Boom break; case Card.Cards.EX1_604: //Frothing Berserker if (BoardHelper.CanBeImmediatelyKilledByEnemy(board, minion) && !BoardHelper.CanCharge(board, minion) && !BoardHelper.CanPlayTaunt(board, minion.CurrentCost)) { MinionCastGlobalCost += GetCardValue(board, minion) * 0.5f; } if (!BoardHelper.CanBePlayedAndEnraged(board, _enragingSpells, minion) || !BoardHelper.CanCharge(board, minion) || !BoardHelper.CanPlayTaunt(board, minion.CurrentCost)) { MinionCastGlobalCost += GetCardValue(board, minion) * 0.3f; } break; case Card.Cards.CS2_147: //Gnomish Inventor break; case Card.Cards.BRM_019: //Grim Patron if ((BoardHelper.CanBeImmediatelyKilledByEnemy(board, minion) && !BoardHelper.CanBePlayedAndEnraged(board, _enragingSpells, minion)) || !(BoardHelper.CanCharge(board, minion) && BoardHelper.AnyEnemyTargets(board, 2))) { MinionCastGlobalCost += GetCardValue(board, minion) * 2f; } break; case Card.Cards.EX1_084: //Warsong Commander if (!BoardHelper.CanPlayWarsongCommander(board, minion)) { MinionCastGlobalCost += GetCardValue(board, minion) * 2f; } break; case Card.Cards.BRMA03_1: //Emperor Thaurissan if (board.Hand.Count < 3) { MinionCastGlobalCost += GetCardValue(board, minion) * 0.5f; } if (board.Hand.Count > 5) { MinionCastGlobalValue += GetCardValue(board, minion) * 1.2f; } break; case Card.Cards.EX1_414: //Grommash Hellscream, ID: EX1_414 if (!BoardHelper.CanBePlayedAndEnraged(board, _enragingSpells, minion)) { MinionCastGlobalCost += GetCardValue(board, minion) * 0.5f; } break; case Card.Cards.FP1_024: //Unstable Ghoul, ID: FP1_024 if (board.MinionEnemy.Count == 0 || !BoardHelper.CanEnrageOrGetArmor(board, _enragingSpells, _enrageableMinions)) { MinionCastGlobalCost += GetCardValue(board, minion) * 0.5f; } break; } if (BoardHelper.IsFirstMove(board)) { OnFirstAction(board, minion, target, true, false, false); } //DebugLog("MINION: " + minion.Template.Name + ", standard value: " + GetCardValue(board, minion) + ", added value: " + MinionCastGlobalValue + ", added cost: " + MinionCastGlobalCost + "; TARGET: " + ", standard value: " + GetCardValue(board, target)); //DebugBestLog("BEST MINION: " + minion.Template.Name + ", standard value: " + GetCardValue(board, minion) + ", added value: " + MinionCastGlobalValue + ", added cost: " + MinionCastGlobalCost + "; TARGET: " + ", standard value: " + GetCardValue(board, target)); }
// MAIN METHODS public override float GetBoardValue(Board board) { float value = 0; SetMainValues(board); //Hero friend value value += board.HeroFriend.CurrentHealth * HeroFriendHealthMultiplier + board.HeroFriend.CurrentArmor * HeroFriendHealthMultiplier; //Hero enemy value value -= board.HeroEnemy.CurrentHealth * HeroEnemyHealthMultiplier + board.HeroEnemy.CurrentArmor * HeroEnemyHealthMultiplier; //enemy board foreach (Card c in board.MinionEnemy) { value -= GetCardValue(board, c); } //friend board foreach (Card c in board.MinionFriend) { value += GetCardValue(board, c); } //casting costs value -= MinionCastGlobalCost; value -= SpellsCastGlobalCost; value -= WeaponCastGlobalCost; //casting action value value += WeaponCastGlobalValue; value += SpellsCastGlobalValue; value += MinionCastGlobalValue; //heropower vost value -= HeroPowerGlobalCost; //Weapon attack cost value -= WeaponAttackGlobalCost; if (board.HeroEnemy.CurrentHealth <= 0) { value += 10000; } if (board.HeroFriend.CurrentHealth <= 0 && board.FriendCardDraw == 0) { value -= 100000; } value += GlobalValueModifier; value += board.FriendCardDraw * FriendCardDrawMultiplier; value -= board.EnemyCardDraw * EnemyCardDrawMultiplier; value += SecretModifier; DebugLog("Actions: " + BoardHelper.GetActionsAsString(board) + ", Value: " + value); DebugBestLog("Best calculated actions: " + BoardHelper.GetActionsAsString(board) + ", Value: " + value); return(value); }