package tactic import "github.com/golangconf/gophers-and-dragons/game" func ChooseCard(s game.State) game.CardType { // coef := s.Creep.Damage.High() + s.Creep.Damage.Low() // coef := s.Creep.Damage.High() + s.Creep.Damage.Low() + s.Creep.Damage.Low() coef := 25 if s.Avatar.HP < coef { // If have a Heal card and enough MP to cast it, use it. if s.Can(game.CardHeal) { return game.CardHeal } } if shouldRest(s) { return game.CardRest } // Fight only weak monsters and run away from everything else. switch s.Creep.Type { case game.CreepCheepy, game.CreepImp: return game.CardAttack default: return chooseAttack(s) } } func shouldRest(s game.State) bool { canRecoverOnCoward := hasTrait(s, game.TraitCoward) && s.Creep.IsFull() && s.Avatar.HP < s.Avatar.MaxHP-3 whileStunned := s.Creep.Stun == 2 return (canRecoverOnCoward || whileStunned) && s.Avatar.MP >= 14 } func chooseAttack(s game.State) game.CardType { if s.Creep.HP <= 2 { return game.CardAttack } switch { case s.Creep.Type == game.CreepKubus: return fightKubus(s) case s.Creep.Type == game.CreepDragon: return fightDragon(s) // for mummies case hasTrait(s, game.TraitWeakToFire) && !hasTrait(s, game.TraitMagicImmunity) && s.Creep.HP >= 3 && s.Can(game.CardFirebolt): return game.CardFirebolt case s.Can(game.CardParry) && !hasTrait(s, game.TraitRanged) && ((s.Creep.Damage.Low() > 2 && s.Creep.Damage.High() > 4) || s.Avatar.HP < 10): return game.CardParry case s.Can(game.CardStun) && !s.Creep.IsStunned(): return game.CardStun case s.Can(game.CardPowerAttack): return game.CardPowerAttack // case s.Can(game.CardMagicArrow) && // hasTrait(s, game.TraitMagicAura) && // !hasTrait(s, game.TraitMagicImmunity) && // s.Avatar.MP >= 16: // return game.CardMagicArrow default: return game.CardAttack } } func fightKubus(s game.State) game.CardType { if s.Creep.IsFull() { if s.Avatar.HP <= 30 { return game.CardRetreat } // fight or flight } switch { case s.Creep.Damage.Low() >= 5 && s.Can(game.CardParry): return game.CardParry case canStun(s): return game.CardStun case s.Can(game.CardPowerAttack): return game.CardPowerAttack default: return game.CardAttack } } func canStun(s game.State) bool { return s.Can(game.CardStun) && !s.Creep.IsStunned() } func hasTrait(s game.State, trait game.CreepTrait) bool { return s.Creep.Traits.Has(trait) } func fightDragon(s game.State) game.CardType { switch { case s.Can(game.CardParry): return game.CardParry case canStun(s): return game.CardStun case s.Can(game.CardHeal): return game.CardHeal case s.Can(game.CardPowerAttack): return game.CardPowerAttack default: return game.CardAttack } }