using MoreLinq.Extensions; namespace AOC2015; /// /// Day 22: /// public sealed class Day22() : Day(2015, 22, "Wizard Simulator 20XX") { private static readonly List Spells = [ new("Magic Missile", Mana: 53, Damage: 4), new("Drain", Mana: 73, Damage: 2, Heal: 2), new("Shield", Mana: 113, Armor: 7, Duration: 6), new("Poison", Mana: 173, Damage: 3, Duration: 6), new("Recharge", Mana: 229, ManaCharge: 101, Duration: 5) ]; private Dictionary _boss = new(); private record Spell( // ReSharper disable once NotAccessedPositionalProperty.Local string Name, int Mana, int Duration = 0, int Damage = 0, int Heal = 0, int Armor = 0, int ManaCharge = 0 ); private struct GameState(bool hardMode = false, int roundNumber = 0, int totalManaSpent = 0, int playerHealth = 50, int playerMana = 500, int bossHealth = 0, int bossDamage = 0, Dictionary? activeSpells = null) { public GameResult DoTurn(Spell spell) { roundNumber++; CastSpell(spell); ProcessActiveSpells(); if (bossHealth <= 0) return GameResult.Win; playerHealth -= Math.Max(1, bossDamage - activeSpells?.Sum(x => x.Key.Armor) ?? 0); if (playerHealth <= 0) return GameResult.Loss; if (hardMode) { } ProcessActiveSpells(); return bossHealth <= 0 ? GameResult.Win : GameResult.Continue; } private void CastSpell(Spell spell) { totalManaSpent += spell.Mana; playerMana -= spell.Mana; if (spell.Duration == 0) ProcessSpell(spell); else activeSpells?.Add(spell, spell.Duration); } private void ProcessActiveSpells() { if (activeSpells is null) return; activeSpells.Keys.ForEach(ProcessSpell); foreach (var (spell, duration) in activeSpells.ToList()) { if (duration == 1) activeSpells.Remove(spell); else activeSpells[spell]--; } } private void ProcessSpell(Spell spell) { bossHealth -= spell.Damage; playerHealth += spell.Heal; playerMana += spell.ManaCharge; } } private enum GameResult { Win, Loss, Continue } private GameState ProcessStates(GameState initialState) { var stateQueue = new Queue(); stateQueue.Enqueue(initialState); GameState bestGame = new(bossHealth: _boss["Hit Points"], bossDamage: _boss["Damage"]); while (stateQueue.Count > 0) { } return initialState; } public override void ProcessInput() => _boss = Input.ToDictionary(k => k.Split(": ")[0], v => int.Parse(v.Split(": ")[1])); public override object Part1() => ProcessStates(new(bossHealth: _boss["Hit Points"], bossDamage: _boss["Damage"])); public override object Part2() => ""; }