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
}
}