From 3b22bfcc37c0ba14aabc983346ba03a1ae9fc7d4 Mon Sep 17 00:00:00 2001 From: Stefan Harmuth Date: Sat, 16 Jan 2021 15:46:32 +0100 Subject: [PATCH] day22 - working fight simulation --- day22/day.go | 70 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/day22/day.go b/day22/day.go index 7448ce6..311cf10 100644 --- a/day22/day.go +++ b/day22/day.go @@ -2,6 +2,7 @@ package day22 import ( "fmt" + "math" "strconv" "strings" "tools" @@ -14,10 +15,12 @@ type Effect struct { timer int } -func (e Effect) copy() Effect { - return Effect{e.damage, e.armor, e.mana, e.timer} +func (e Effect) copy() *Effect { + return &Effect{e.damage, e.armor, e.mana, e.timer} } +var activeEffects map[string]*Effect + type Spell struct { cost int damage int @@ -26,15 +29,14 @@ type Spell struct { } type Entity struct { - hitpoints int - mana int - damage int - armor int - currentEffects map[string]Effect + hitpoints int + mana int + damage int + armor int } -func (e Entity) copy() Entity { - return Entity{e.hitpoints, e.mana, e.damage, e.armor, e.currentEffects} +func (e Entity) copy() *Entity { + return &Entity{e.hitpoints, e.mana, e.damage, e.armor} } func (e Entity) printStats() { @@ -50,36 +52,45 @@ var spells = map[string]Spell{ } func applyEffects(player, boss *Entity) { - for eName, eData := range player.currentEffects { + for eName, eData := range activeEffects { switch eName { case "Shield": if eData.timer == spells["Shield"].applyEffect.timer { + fmt.Println("Apply Shield") player.armor += eData.armor } else if eData.timer == 1 { + fmt.Println("Remove Shield") player.armor -= eData.armor } case "Recharge": + fmt.Println("Regen Mana") player.mana += eData.mana - } - eData.timer-- - } - for eName, eData := range boss.currentEffects { - switch eName { case "Poison": + fmt.Println("Apply Poison") 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 + spell := spells[spellName] applyEffects(player, boss) if player.mana < spell.cost { 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 { return 1 @@ -97,9 +108,17 @@ func fightRound(player, boss *Entity, spell Spell) (outcome int) { return 0 } +func minManaToTheDeath(player, boss *Entity) int { + manaUsed := 0 + minManaUsed := math.MaxInt64 + + return manaUsed +} + func Part1(puzzle tools.AoCPuzzle) interface{} { - player := Entity{50, 500, 0, 0, make(map[string]Effect)} - boss := Entity{0, 0, 0, 0, make(map[string]Effect)} + activeEffects = make(map[string]*Effect) + player := Entity{50, 500, 0, 0} + boss := Entity{0, 0, 0, 0} bossdata := puzzle.GetInputArray() for _, line := range bossdata { parts := strings.Split(line, ": ") @@ -110,11 +129,16 @@ func Part1(puzzle tools.AoCPuzzle) interface{} { boss.damage, _ = strconv.Atoi(parts[1]) } } + player.printStats() boss.printStats() - fightRound(&player, &boss, spells["Magic Missile"]) - player.printStats() - boss.printStats() + fmt.Println("-----") + for _, s := range []string{"Recharge", "Shield", "Drain", "Poison", "Magic Missile"} { + fightRound(&player, &boss, s) + player.printStats() + boss.printStats() + fmt.Println("-----") + } return 0 }