aboutsummaryrefslogtreecommitdiff
path: root/src/2015/day22/aoc.cpp
diff options
context:
space:
mode:
authorkaiwu <kaiwu2004@gmail.com>2022-12-08 11:41:21 +0800
committerkaiwu <kaiwu2004@gmail.com>2022-12-08 11:41:21 +0800
commit2aef63bbb79fc39031b23473f8949724b6af0f1e (patch)
tree66d88c64c7cf99d55bfc0c472d010bdf49663099 /src/2015/day22/aoc.cpp
parent5eb95d08e5d8947ca4d2c1521607c917b8ac9daa (diff)
downloadadvent-of-code-2aef63bbb79fc39031b23473f8949724b6af0f1e.tar.gz
advent-of-code-2aef63bbb79fc39031b23473f8949724b6af0f1e.zip
2015 day22 part1
Diffstat (limited to 'src/2015/day22/aoc.cpp')
-rw-r--r--src/2015/day22/aoc.cpp96
1 files changed, 85 insertions, 11 deletions
diff --git a/src/2015/day22/aoc.cpp b/src/2015/day22/aoc.cpp
index e9aa969..2489124 100644
--- a/src/2015/day22/aoc.cpp
+++ b/src/2015/day22/aoc.cpp
@@ -1,22 +1,36 @@
#include "aoc.h"
+#include <string.h>
#include <vector>
namespace aoc2015 {
-static spell bosskill = {0, 1, 8, 0, 0, 0, 0};
+static spell bosskill = {"bosskill", 0, 1, 8, 0, 0, 0, 0};
static spell spells[5] = {
- {53, 1, 4, 0, 0, 0, 0},
- {73, 1, 2, 2, 0, 0, 0},
- {113, 6, 0, 0, 0, 7, 0},
- {173, 6, 3, 0, 0, 0, 0},
- {229, 5, 0, 0, 101, 0, 0},
+ {"Magic Missile", 53, 1, 4, 0, 0, 0, 0},
+ {"Drain", 73, 1, 2, 2, 0, 0, 0},
+ {"Shield", 113, 6, 0, 0, 0, 7, 0},
+ {"Poison", 173, 6, 3, 0, 0, 0, 0},
+ {"Recharge", 229, 5, 0, 0, 101, 0, 0},
};
+// spells wizard w can pick
+std::vector<spell*> can_spell(const wizard& w) {
+ std::vector<spell*> is;
+ for (int i = 0; i < 5; i++) {
+ spell* s = w.wp->spells[i];
+ if (s != nullptr && s->tick == 0 && w.mana >= s->costs) {
+ is.push_back(s);
+ }
+ }
+ return is;
+}
+
+// effect for wizard w
void effects(wizard& w) {
for (int i = 0; i < 5; i++) {
spell* s = w.spells[i];
if (s != nullptr && s->tick > 0) {
- w.points -= s->damage;
+ w.points -= s->damage < w.armor ? 1 : s->damage;
w.wp->points += s->heals;
w.wp->mana += s->payback;
w.wp->armor += s->protect;
@@ -25,8 +39,69 @@ void effects(wizard& w) {
}
}
-void fight(int turn, wizard& me, wizard& boss, int* cost, std::vector<int>& costs) {
- // wizard* w = turn % 2 == 1 ? &me : &boss;
+void start_of_each_turn (wizard& me, wizard& boss) {
+ for (int i = 2; i < 5; i++) {
+ spell* s = boss.spells[i];
+ if (s->tick > 0) {
+ if (strcmp(s->name, "Shield") == 0) {
+ me.armor = 7;
+ }
+ if (strcmp(s->name, "Poison") == 0) {
+ boss.points -= s->damage;
+ }
+ if (strcmp(s->name, "Recharge") == 0) {
+ me.mana += s->payback;
+ }
+ s->tick -= 1;
+ }
+ else {
+ if (strcmp(s->name, "Shield") == 0) {
+ me.armor = 0;
+ }
+ }
+ }
+}
+
+void instant_effect(spell* s, wizard& me, wizard& boss) {
+ if (strcmp(s->name, "Magic Missile") == 0) {
+ boss.points -= s->damage;
+ }
+ if (strcmp(s->name, "Drain") == 0) {
+ boss.points -= s->damage;
+ me.points += s->heals;
+ }
+}
+
+void fight(int turn, wizard me, wizard boss, int cost, std::vector<int>& costs) {
+ start_of_each_turn(me, boss);
+ if (turn % 2 == 1) { // my turn
+ printf("player points[%d] armor[%d] mana[%d]\n", me.points, me.armor, me.mana);
+ if (me.points > 0) {
+ auto ss = can_spell(me);
+ for(auto& s : ss) {
+ printf("choose %s\n", s->name);
+ s->tick = s->turns;
+ me.mana -= s->costs;
+ instant_effect(s, me, boss);
+ fight(turn+1, me, boss, cost + s->costs, costs);
+ me.mana += s->costs;
+ s->tick = 0;
+ }
+ }
+ else {
+ printf("player lose\n");
+ }
+ } else { // boss turn
+ printf("boss points[%d]\n", boss.points);
+ if (boss.points <= 0) { // boss lose
+ printf("boss lose\n");
+ costs.push_back(cost);
+ }
+ else {
+ me.points -= bosskill.damage;
+ fight(turn+1, me, boss, cost, costs);
+ }
+ }
}
std::pair<int, int> day22(wizard me, wizard boss) {
@@ -36,9 +111,8 @@ std::pair<int, int> day22(wizard me, wizard boss) {
for (int i = 0; i < 5; i++) {
boss.spells[i] = spells + i;
}
- int cost{0};
std::vector<int> costs;
- fight(1, me, boss, &cost, costs);
+ fight(1, me, boss, 0, costs);
int min{INT32_MAX};
for(auto& c : costs) {