ItemHandler.java 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. import java.io.File;
  2. import java.io.IOException;
  3. import java.nio.file.Files;
  4. import java.util.ArrayList;
  5. import java.util.Arrays;
  6. import java.util.HashMap;
  7. import java.util.HashSet;
  8. import java.util.Iterator;
  9. import java.util.List;
  10. import java.util.stream.Collectors;
  11. public class ItemHandler {
  12. private final List<String> collectableItems;
  13. private final List<Recipe> recipes;
  14. private final List<Shop> shops;
  15. private final List<Monster> monsters;
  16. private final List<String> filters;
  17. public ItemHandler(String folder) throws IOException {
  18. List<String> config = Files.readAllLines(new File(folder, "config").toPath());
  19. List<String> knownShops = split(config.get(0));
  20. NumberFilter nf = new NumberFilter(split(config.get(1)));
  21. collectableItems = split(config.get(2));
  22. filters = config.subList(3, config.size());
  23. recipes = readRecipes(folder);
  24. List<Shop> allShops = readShops(folder);
  25. knownShops.stream().filter(
  26. knownShop -> !allShops.stream().anyMatch(shop -> shop.getName().equals(knownShop)))
  27. .forEach(shop -> System.out.println(String.format("Unbekannter Shop: %s", shop)));
  28. shops = allShops.stream()
  29. .filter(shop -> knownShops.stream().anyMatch(s -> s.equals(shop.getName())))
  30. .collect(Collectors.toList());
  31. monsters = readMonster(folder).stream().filter(m -> nf.check(m.getNumber()))
  32. .collect(Collectors.toList());
  33. collectableItems.stream().filter(item -> !recipes.stream().anyMatch(r -> r.has(item)))
  34. .forEach(item -> {
  35. System.out.println(String.format("'%s' is in keinem Rezept verwendet.", item));
  36. });
  37. }
  38. public void execute(String[] args) {
  39. if(args.length > 0) {
  40. searchFor(args);
  41. } else {
  42. printRecipes();
  43. }
  44. }
  45. private static List<Shop> readShops(String folder) throws IOException {
  46. HashMap<String, Shop> shops = new HashMap<>();
  47. List<String> list = Files.readAllLines(new File(folder, "buyable").toPath());
  48. for(String s : list) {
  49. List<String> parts = split(s);
  50. Iterator<String> iter = parts.iterator();
  51. String itemName = iter.next();
  52. int cost = Integer.parseInt(iter.next());
  53. while(iter.hasNext()) {
  54. String shopName = iter.next();
  55. Shop shop = shops.get(shopName);
  56. if(shop == null) {
  57. shop = new Shop(shopName);
  58. shops.put(shopName, shop);
  59. }
  60. shop.addItem(itemName, cost);
  61. }
  62. }
  63. return shops.values().stream().collect(Collectors.toList());
  64. }
  65. private static List<Monster> readMonster(String folder) throws IOException {
  66. return Files.readAllLines(new File(folder, "monsters").toPath()).stream()
  67. .map(line -> new Monster(split(line).iterator())).collect(Collectors.toList());
  68. }
  69. private static List<Recipe> readRecipes(String folder) throws IOException {
  70. ArrayList<Recipe> recipes = new ArrayList<>();
  71. for(File f : new File(folder, "recipes").listFiles()) {
  72. Iterator<String> lineIter = Files.readAllLines(f.toPath()).iterator();
  73. String category = lineIter.next();
  74. while(lineIter.hasNext()) {
  75. List<String> parts = split(lineIter.next());
  76. Recipe r = new Recipe();
  77. r.setCategory(category);
  78. Iterator<String> iter = parts.iterator();
  79. r.setResult(iter.next());
  80. int c = 0;
  81. while(iter.hasNext()) {
  82. String itemName = iter.next();
  83. int amount = Integer.parseInt(iter.next());
  84. r.setItem(c, itemName, amount);
  85. c++;
  86. }
  87. recipes.add(r);
  88. }
  89. }
  90. return recipes;
  91. }
  92. private static List<String> split(String s) {
  93. ArrayList<String> parts = new ArrayList<>();
  94. int index = 0;
  95. int old = 0;
  96. while(index < s.length()) {
  97. char c = s.charAt(index);
  98. if(c == ',') {
  99. parts.add(trim(s.substring(old, index)));
  100. old = index + 1;
  101. } else if(c == '"') {
  102. index++;
  103. while(index < s.length() && s.charAt(index) != '"') {
  104. index++;
  105. }
  106. }
  107. index++;
  108. }
  109. parts.add(trim(s.substring(old, index)));
  110. parts.removeIf((f) -> f.isEmpty());
  111. return parts;
  112. }
  113. private static String trim(String s) {
  114. s = s.trim();
  115. if(!s.isEmpty() && s.charAt(0) == '"' && s.charAt(s.length() - 1) == '"') {
  116. s = s.substring(1, s.length() - 1);
  117. }
  118. return s;
  119. }
  120. private HashSet<Recipe> getPossibleRecipes() {
  121. HashSet<String> items = new HashSet<>();
  122. items.addAll(collectableItems);
  123. monsters.forEach(m -> {
  124. items.add(m.getFirstDrop());
  125. items.add(m.getSecondDrop());
  126. });
  127. shops.forEach(shop -> shop.addAllTo(items));
  128. // check for all possible recipes
  129. HashSet<Recipe> pRecipes = new HashSet<>();
  130. while(true) {
  131. int cRecipes = pRecipes.size();
  132. for(Recipe r : recipes) {
  133. if(r.check(items)) {
  134. pRecipes.add(r);
  135. items.add(r.getResult());
  136. }
  137. }
  138. if(cRecipes == pRecipes.size()) {
  139. break;
  140. }
  141. }
  142. return pRecipes;
  143. }
  144. private void printRecipes() {
  145. HashSet<Recipe> pRecipes = getPossibleRecipes();
  146. filters.forEach(filter -> pRecipes.removeIf(r -> r.getResult().equals(filter)));
  147. pRecipes.stream().sorted().forEach(r -> System.out.println(r));
  148. }
  149. private void searchFor(String[] search) {
  150. HashSet<Recipe> pRecipes = getPossibleRecipes();
  151. for(String s : search) {
  152. System.out.println(String.format("%s:", s));
  153. boolean recipeResult = printRecipesContaining(s, pRecipes);
  154. boolean shopResult = printShopsContaining(s);
  155. boolean monsterResult = printMonstersContaining(s);
  156. if(recipeResult && shopResult && monsterResult) {
  157. System.out.println("> Keine Ergebnisse");
  158. }
  159. System.out.println();
  160. }
  161. }
  162. private boolean printRecipesContaining(String s, HashSet<Recipe> pRecipes) {
  163. boolean once = true;
  164. for(Recipe r : pRecipes) {
  165. if(r.getResult().equals(s)) {
  166. if(once) {
  167. once = false;
  168. System.out.println("> Alchemie-Rezepte:");
  169. }
  170. System.out.print(">");
  171. System.out.println(r);
  172. }
  173. }
  174. return once;
  175. }
  176. private boolean printShopsContaining(String s) {
  177. boolean once = true;
  178. for(Shop shop : shops) {
  179. Shop.Item item = shop.search(s);
  180. if(item != null) {
  181. if(once) {
  182. once = false;
  183. System.out.print(String.format("> kaufbar um %d in: ", item.getCost()));
  184. System.out.print(shop.getName());
  185. } else {
  186. System.out.print(", ");
  187. System.out.print(shop.getName());
  188. }
  189. }
  190. }
  191. if(!once) {
  192. System.out.println();
  193. }
  194. return once;
  195. }
  196. private boolean printMonstersContaining(String s) {
  197. boolean once = true;
  198. for(Monster m : monsters) {
  199. if(m.getFirstDrop().equals(s)) {
  200. if(once) {
  201. once = false;
  202. System.out.println("> Monster: ");
  203. }
  204. System.out.println(m);
  205. }
  206. if(m.getSecondDrop().equals(s)) {
  207. if(once) {
  208. once = false;
  209. System.out.println("> Monster: ");
  210. }
  211. System.out.println(m);
  212. }
  213. }
  214. return once;
  215. }
  216. }