day22 - working fight simulation

This commit is contained in:
Stefan Harmuth 2021-01-16 15:46:32 +01:00
parent 00c6eb8a77
commit 3b22bfcc37

View File

@ -2,6 +2,7 @@ package day22
import ( import (
"fmt" "fmt"
"math"
"strconv" "strconv"
"strings" "strings"
"tools" "tools"
@ -14,10 +15,12 @@ type Effect struct {
timer int timer int
} }
func (e Effect) copy() Effect { func (e Effect) copy() *Effect {
return Effect{e.damage, e.armor, e.mana, e.timer} return &Effect{e.damage, e.armor, e.mana, e.timer}
} }
var activeEffects map[string]*Effect
type Spell struct { type Spell struct {
cost int cost int
damage int damage int
@ -26,15 +29,14 @@ type Spell struct {
} }
type Entity struct { type Entity struct {
hitpoints int hitpoints int
mana int mana int
damage int damage int
armor int armor int
currentEffects map[string]Effect
} }
func (e Entity) copy() Entity { func (e Entity) copy() *Entity {
return Entity{e.hitpoints, e.mana, e.damage, e.armor, e.currentEffects} return &Entity{e.hitpoints, e.mana, e.damage, e.armor}
} }
func (e Entity) printStats() { func (e Entity) printStats() {
@ -50,36 +52,45 @@ var spells = map[string]Spell{
} }
func applyEffects(player, boss *Entity) { func applyEffects(player, boss *Entity) {
for eName, eData := range player.currentEffects { for eName, eData := range activeEffects {
switch eName { switch eName {
case "Shield": case "Shield":
if eData.timer == spells["Shield"].applyEffect.timer { if eData.timer == spells["Shield"].applyEffect.timer {
fmt.Println("Apply Shield")
player.armor += eData.armor player.armor += eData.armor
} else if eData.timer == 1 { } else if eData.timer == 1 {
fmt.Println("Remove Shield")
player.armor -= eData.armor player.armor -= eData.armor
} }
case "Recharge": case "Recharge":
fmt.Println("Regen Mana")
player.mana += eData.mana player.mana += eData.mana
}
eData.timer--
}
for eName, eData := range boss.currentEffects {
switch eName {
case "Poison": case "Poison":
fmt.Println("Apply Poison")
boss.hitpoints -= eData.damage boss.hitpoints -= eData.damage
} }
eData.timer-- activeEffects[eName].timer--
if eData.timer == 0 {
fmt.Println(eName, "wears off.")
delete(activeEffects, eName)
}
} }
} }
func fightRound(player, boss *Entity, spell Spell) (outcome int) { func fightRound(player, boss *Entity, spellName string) (outcome int) {
// outcome will be -1 on boss win, 0 on both living and 1 on player win // outcome will be -1 on boss win, 0 on both living and 1 on player win
spell := spells[spellName]
applyEffects(player, boss) applyEffects(player, boss)
if player.mana < spell.cost { if player.mana < spell.cost {
return -1 return -1
} }
// cast spell player.mana -= spell.cost
player.hitpoints += spell.heal
boss.hitpoints -= spell.damage
if _, ok := activeEffects[spellName]; !ok && spell.applyEffect.timer > 0 {
activeEffects[spellName] = spell.applyEffect.copy()
}
if boss.hitpoints <= 0 { if boss.hitpoints <= 0 {
return 1 return 1
@ -97,9 +108,17 @@ func fightRound(player, boss *Entity, spell Spell) (outcome int) {
return 0 return 0
} }
func minManaToTheDeath(player, boss *Entity) int {
manaUsed := 0
minManaUsed := math.MaxInt64
return manaUsed
}
func Part1(puzzle tools.AoCPuzzle) interface{} { func Part1(puzzle tools.AoCPuzzle) interface{} {
player := Entity{50, 500, 0, 0, make(map[string]Effect)} activeEffects = make(map[string]*Effect)
boss := Entity{0, 0, 0, 0, make(map[string]Effect)} player := Entity{50, 500, 0, 0}
boss := Entity{0, 0, 0, 0}
bossdata := puzzle.GetInputArray() bossdata := puzzle.GetInputArray()
for _, line := range bossdata { for _, line := range bossdata {
parts := strings.Split(line, ": ") parts := strings.Split(line, ": ")
@ -110,11 +129,16 @@ func Part1(puzzle tools.AoCPuzzle) interface{} {
boss.damage, _ = strconv.Atoi(parts[1]) boss.damage, _ = strconv.Atoi(parts[1])
} }
} }
player.printStats() player.printStats()
boss.printStats() boss.printStats()
fightRound(&player, &boss, spells["Magic Missile"]) fmt.Println("-----")
player.printStats() for _, s := range []string{"Recharge", "Shield", "Drain", "Poison", "Magic Missile"} {
boss.printStats() fightRound(&player, &boss, s)
player.printStats()
boss.printStats()
fmt.Println("-----")
}
return 0 return 0
} }