day22 - working fight simulation
This commit is contained in:
parent
00c6eb8a77
commit
3b22bfcc37
70
day22/day.go
70
day22/day.go
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user