2018 day 24 More work
This commit is contained in:
@@ -1,19 +1,33 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
ArmyTypeImmune = 1 << iota
|
||||
ArmyTypeInfection
|
||||
)
|
||||
|
||||
type Army struct {
|
||||
tp int
|
||||
units int
|
||||
hp int
|
||||
immunities []string
|
||||
weaknesses []string
|
||||
damageType string
|
||||
strength int
|
||||
init int
|
||||
id int
|
||||
tp int
|
||||
units int
|
||||
hp int
|
||||
immunities []string
|
||||
weaknesses []string
|
||||
damageType string
|
||||
strength int
|
||||
init int
|
||||
target *Army
|
||||
targettedBy *Army
|
||||
}
|
||||
|
||||
func NewArmy(inp string, tp int) *Army {
|
||||
func NewArmy(inp string, tp, id int) *Army {
|
||||
a := new(Army)
|
||||
a.tp = tp
|
||||
a.id = id
|
||||
|
||||
// Pull the parenthetical out, if one is there
|
||||
var prnth, other string
|
||||
@@ -43,38 +57,154 @@ func NewArmy(inp string, tp int) *Army {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Now parse out immunities and weaknesses
|
||||
if len(prnth) > 3 {
|
||||
prnth = prnth[1:len(prnth)-1]
|
||||
var inImmune bool
|
||||
for _, v := range strings.Fields(prnth) {
|
||||
if v == "immune" {
|
||||
inImmune = true
|
||||
} else if v == "weak" {
|
||||
inImmune = false
|
||||
}
|
||||
if v == "to" {
|
||||
continue
|
||||
}
|
||||
if v[len(v)-1] == ';' || v[len(v)-1] == ',' {
|
||||
v = v[:len(v)-1]
|
||||
}
|
||||
if inImmune {
|
||||
a.immunities = append(a.immunities, v)
|
||||
} else {
|
||||
a.weaknesses = append(a.weaknesses, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Now parse out immunities and weaknesses
|
||||
if len(prnth) > 3 {
|
||||
prnth = prnth[1 : len(prnth)-1]
|
||||
var inImmune bool
|
||||
for _, v := range strings.Fields(prnth) {
|
||||
if v == "immune" {
|
||||
inImmune = true
|
||||
continue
|
||||
} else if v == "weak" {
|
||||
inImmune = false
|
||||
continue
|
||||
}
|
||||
if v == "to" {
|
||||
continue
|
||||
}
|
||||
if v[len(v)-1] == ';' || v[len(v)-1] == ',' {
|
||||
v = v[:len(v)-1]
|
||||
}
|
||||
if inImmune {
|
||||
a.immunities = append(a.immunities, v)
|
||||
} else {
|
||||
a.weaknesses = append(a.weaknesses, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *Army) IsImmuneTo(val string) bool {
|
||||
for _, v := range a.immunities {
|
||||
if v == val {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (a *Army) IsWeakTo(val string) bool {
|
||||
for _, v := range a.weaknesses {
|
||||
if v == val {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (a *Army) Power() int {
|
||||
return a.units * a.strength
|
||||
}
|
||||
|
||||
func (a *Army) FindTarget(group []*Army) {
|
||||
var tgt *Army
|
||||
var tgtDmg int
|
||||
for _, v := range group {
|
||||
if v.targettedBy != nil {
|
||||
continue
|
||||
}
|
||||
wrkDmg := a.CalculateDamage(v)
|
||||
if tgt == nil || wrkDmg > tgtDmg {
|
||||
tgt = v
|
||||
tgtDmg = wrkDmg
|
||||
} else if wrkDmg == tgtDmg {
|
||||
if v.Power() > tgt.Power() {
|
||||
tgt = v
|
||||
tgtDmg = wrkDmg
|
||||
} else if v.Power() == tgt.Power() {
|
||||
if v.init > tgt.init {
|
||||
tgt = v
|
||||
tgtDmg = wrkDmg
|
||||
}
|
||||
}
|
||||
}
|
||||
if Debug {
|
||||
var tpTxt string
|
||||
if a.tp == ArmyTypeImmune {
|
||||
tpTxt = "Immune System"
|
||||
} else {
|
||||
tpTxt = "Infection"
|
||||
}
|
||||
fmt.Printf("%s group %d would deal defending group %d %d damage\n", tpTxt, a.id, tgt.id, tgtDmg)
|
||||
}
|
||||
}
|
||||
if tgt != nil {
|
||||
a.target = tgt
|
||||
tgt.targettedBy = a
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Army) CalculateDamage(b *Army) int {
|
||||
if b.IsWeakTo(a.damageType) {
|
||||
return a.Power() * 2
|
||||
} else if b.IsImmuneTo(a.damageType) {
|
||||
return 0
|
||||
}
|
||||
return a.Power()
|
||||
}
|
||||
|
||||
func (a *Army) Damage(b *Army) int {
|
||||
var unitsDefeated int
|
||||
dmg := a.CalculateDamage(b)
|
||||
for dmg > 0 {
|
||||
dmg -= b.hp
|
||||
if dmg > 0 && b.units > 0 {
|
||||
b.units--
|
||||
unitsDefeated++
|
||||
}
|
||||
}
|
||||
b.targettedBy = nil
|
||||
return unitsDefeated
|
||||
}
|
||||
|
||||
func (a *Army) Fight() {
|
||||
if a.target != nil {
|
||||
var tpTxt string
|
||||
if a.tp == ArmyTypeImmune {
|
||||
tpTxt = "Immune System"
|
||||
} else if a.tp == ArmyTypeInfection {
|
||||
tpTxt = "Infection"
|
||||
}
|
||||
dmg := a.Damage(a.target)
|
||||
if Debug {
|
||||
fmt.Printf("%s group %d attacks defending group %d, killing %d units\n", tpTxt, a.id, a.target.id, dmg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a Army) String() string {
|
||||
ret := fmt.Sprintf("%d units each with %d hit points ", a.units, a.hp)
|
||||
if len(a.weaknesses) > 0 {
|
||||
ret = ret + fmt.Sprintf("(weaknesses: %s) ", a.weaknesses)
|
||||
}
|
||||
if len(a.immunities) > 0 {
|
||||
ret = ret + fmt.Sprintf("(immunities: %s) ", a.immunities)
|
||||
}
|
||||
ret = ret + fmt.Sprintf("with an attack that does %d %s damage at initiative %d\n",
|
||||
a.strength, a.damageType, a.init,
|
||||
)
|
||||
return ret
|
||||
}
|
||||
|
||||
// Army Sorting
|
||||
type ByPower []Army
|
||||
func (b ByPower) Len() int { return len(b) }
|
||||
type ByPower []*Army
|
||||
|
||||
func (b ByPower) Len() int { return len(b) }
|
||||
func (b ByPower) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
|
||||
func (b ByPower) Less(i, j int) { b[i].Power() < b[j].Power() }
|
||||
func (b ByPower) Less(i, j int) bool {
|
||||
if b[i].Power() == b[j].Power() {
|
||||
return b[i].init < b[j].init
|
||||
}
|
||||
return b[i].Power() < b[j].Power()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user