| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- 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<Item, int> armory, MonsterBoss boss, ref int best, ref int worst, int cost = 0, HashSet<Inventory> triedInventories = null, Inventory heroeInventory = null)
- {
- var wCount = heroeInventory?.Count<Weapon>() ?? 0;
- var aCount = heroeInventory?.Count<Armor>() ?? 0;
- var rCount = heroeInventory?.Count<Ring>() ?? 0;
- if (triedInventories == null) triedInventories = new HashSet<Inventory>();
- 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<Item, int> BuildArmory()
- {
- return new Dictionary<Item, int>
- {
- { 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 },
- };
- }
- }
- }
|