using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace D21._1 { class Program { static bool Attack(MonsterBoss boss, Inventory inventory) { var heroe = new Heroe(); foreach (var item in inventory) { heroe.Armor += item.Armor; heroe.Damage += item.Damage; } boss.Heal(); while (heroe.HitPoints > 0 && boss.HitPoints > 0) { var hatk = Math.Max(heroe.Damage - boss.Armor, 1); boss.HitPoints -= hatk; if (boss.HitPoints <= 0) break; var batk = Math.Max(boss.Damage - heroe.Armor, 1); heroe.HitPoints -= batk; } return heroe.HitPoints > 0; } static void TryOutfits(Dictionary armory, MonsterBoss boss, ref int best, ref int worst, int cost = 0, HashSet triedInventories = null, Inventory heroeInventory = null) { var wCount = heroeInventory?.Count() ?? 0; var aCount = heroeInventory?.Count() ?? 0; var rCount = heroeInventory?.Count() ?? 0; if (triedInventories == null) triedInventories = new HashSet(); if (wCount == 1 && aCount == 1 && rCount == 2) { if (cost > best && cost < worst) return; if (triedInventories.Contains(heroeInventory) == false) { if (Attack(boss, heroeInventory)) { if (cost < best) best = cost; } else { if (cost > worst) worst = cost; } triedInventories.Add(heroeInventory); } return; } foreach ((Item item, int price) in armory) { if (heroeInventory?.Contains(item) ?? false) continue; if (item is Weapon && wCount == 1) continue; if (item is Armor && aCount == 1) continue; if (item is Ring && rCount == 2) continue; var newInventory = new Inventory() { Item = item, NextEntry = heroeInventory }; TryOutfits(armory, boss, ref best, ref worst, cost + price, triedInventories, newInventory); } } static void Main(string[] args) { if (args.Length < 1) throw new ArgumentException(); if (File.Exists(args[0]) == false) throw new FileNotFoundException(); var armory = BuildArmory(); MonsterBoss boss = ParseFile(args); int best = int.MaxValue, worst = 0; TryOutfits(armory, boss, ref best, ref worst); Console.WriteLine($"Best outfit is worth {best} gp"); Console.WriteLine($"Worst outfit is worth {worst} gp"); } private static MonsterBoss ParseFile(string[] args) { int hp = 0, atk = 0, ac = 0; using (var file = File.OpenText(args[0])) { hp = int.Parse(file.ReadLine().Split(": ")[1]); atk = int.Parse(file.ReadLine().Split(": ")[1]); ac = int.Parse(file.ReadLine().Split(": ")[1]); } var boss = new MonsterBoss(hp) { Damage = atk, Armor = ac }; return boss; } private static Dictionary BuildArmory() { return new Dictionary { { new Weapon() { Name = "Dagger", Damage = 4 }, 8 }, { new Weapon() { Name = "Shortsword", Damage = 5 }, 10 }, { new Weapon() { Name = "Warhammer", Damage = 6 }, 25 }, { new Weapon() { Name = "Longsword", Damage = 7 }, 40 }, { new Weapon() { Name = "Greataxe", Damage = 8 }, 74 }, { new Armor() { Name = "None" }, 0 }, { new Armor() { Name = "Leather", Armor = 1 }, 13 }, { new Armor() { Name = "Chainmail", Armor = 2 }, 31 }, { new Armor() { Name = "Splintmail", Armor = 3 }, 53 }, { new Armor() { Name = "Bandedmail", Armor = 4 }, 75 }, { new Armor() { Name = "Platemail", Armor = 5 }, 102 }, { new Ring() { Name = "Left Hand" }, 0 }, { new Ring() { Name = "Right Hand" }, 0 }, { new Ring() { Name = "Damage +1", Damage = 1 }, 25 }, { new Ring() { Name = "Damage +2", Damage = 2 }, 50 }, { new Ring() { Name = "Damage +3", Damage = 3 }, 100 }, { new Ring() { Name = "Defense +1", Armor = 1 }, 20 }, { new Ring() { Name = "Defense +2", Armor = 2 }, 40 }, { new Ring() { Name = "Defense +3", Armor = 3 }, 80 }, }; } } }