Program.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. namespace D21._1
  6. {
  7. class Program
  8. {
  9. static bool Attack(MonsterBoss boss, Inventory inventory)
  10. {
  11. var heroe = new Heroe();
  12. foreach (var item in inventory)
  13. {
  14. heroe.Armor += item.Armor;
  15. heroe.Damage += item.Damage;
  16. }
  17. boss.Heal();
  18. while (heroe.HitPoints > 0 && boss.HitPoints > 0)
  19. {
  20. var hatk = Math.Max(heroe.Damage - boss.Armor, 1);
  21. boss.HitPoints -= hatk;
  22. if (boss.HitPoints <= 0) break;
  23. var batk = Math.Max(boss.Damage - heroe.Armor, 1);
  24. heroe.HitPoints -= batk;
  25. }
  26. return heroe.HitPoints > 0;
  27. }
  28. 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)
  29. {
  30. var wCount = heroeInventory?.Count<Weapon>() ?? 0;
  31. var aCount = heroeInventory?.Count<Armor>() ?? 0;
  32. var rCount = heroeInventory?.Count<Ring>() ?? 0;
  33. if (triedInventories == null) triedInventories = new HashSet<Inventory>();
  34. if (wCount == 1 && aCount == 1 && rCount == 2)
  35. {
  36. if (cost > best && cost < worst) return;
  37. if (triedInventories.Contains(heroeInventory) == false)
  38. {
  39. if (Attack(boss, heroeInventory)) { if (cost < best) best = cost; }
  40. else { if (cost > worst) worst = cost; }
  41. triedInventories.Add(heroeInventory);
  42. }
  43. return;
  44. }
  45. foreach ((Item item, int price) in armory)
  46. {
  47. if (heroeInventory?.Contains(item) ?? false) continue;
  48. if (item is Weapon && wCount == 1) continue;
  49. if (item is Armor && aCount == 1) continue;
  50. if (item is Ring && rCount == 2) continue;
  51. var newInventory = new Inventory() { Item = item, NextEntry = heroeInventory };
  52. TryOutfits(armory, boss, ref best, ref worst, cost + price, triedInventories, newInventory);
  53. }
  54. }
  55. static void Main(string[] args)
  56. {
  57. if (args.Length < 1) throw new ArgumentException();
  58. if (File.Exists(args[0]) == false) throw new FileNotFoundException();
  59. var armory = BuildArmory();
  60. MonsterBoss boss = ParseFile(args);
  61. int best = int.MaxValue, worst = 0;
  62. TryOutfits(armory, boss, ref best, ref worst);
  63. Console.WriteLine($"Best outfit is worth {best} gp");
  64. Console.WriteLine($"Worst outfit is worth {worst} gp");
  65. }
  66. private static MonsterBoss ParseFile(string[] args)
  67. {
  68. int hp = 0, atk = 0, ac = 0;
  69. using (var file = File.OpenText(args[0]))
  70. {
  71. hp = int.Parse(file.ReadLine().Split(": ")[1]);
  72. atk = int.Parse(file.ReadLine().Split(": ")[1]);
  73. ac = int.Parse(file.ReadLine().Split(": ")[1]);
  74. }
  75. var boss = new MonsterBoss(hp)
  76. {
  77. Damage = atk,
  78. Armor = ac
  79. };
  80. return boss;
  81. }
  82. private static Dictionary<Item, int> BuildArmory()
  83. {
  84. return new Dictionary<Item, int>
  85. {
  86. { new Weapon() { Name = "Dagger", Damage = 4 }, 8 },
  87. { new Weapon() { Name = "Shortsword", Damage = 5 }, 10 },
  88. { new Weapon() { Name = "Warhammer", Damage = 6 }, 25 },
  89. { new Weapon() { Name = "Longsword", Damage = 7 }, 40 },
  90. { new Weapon() { Name = "Greataxe", Damage = 8 }, 74 },
  91. { new Armor() { Name = "None" }, 0 },
  92. { new Armor() { Name = "Leather", Armor = 1 }, 13 },
  93. { new Armor() { Name = "Chainmail", Armor = 2 }, 31 },
  94. { new Armor() { Name = "Splintmail", Armor = 3 }, 53 },
  95. { new Armor() { Name = "Bandedmail", Armor = 4 }, 75 },
  96. { new Armor() { Name = "Platemail", Armor = 5 }, 102 },
  97. { new Ring() { Name = "Left Hand" }, 0 },
  98. { new Ring() { Name = "Right Hand" }, 0 },
  99. { new Ring() { Name = "Damage +1", Damage = 1 }, 25 },
  100. { new Ring() { Name = "Damage +2", Damage = 2 }, 50 },
  101. { new Ring() { Name = "Damage +3", Damage = 3 }, 100 },
  102. { new Ring() { Name = "Defense +1", Armor = 1 }, 20 },
  103. { new Ring() { Name = "Defense +2", Armor = 2 }, 40 },
  104. { new Ring() { Name = "Defense +3", Armor = 3 }, 80 },
  105. };
  106. }
  107. }
  108. }