import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.stream.Collectors; public class ItemHandler { private final List collectableItems; private final List recipes; private final List shops; private final List monsters; private final List filters; public ItemHandler(String folder) throws IOException { List config = Files.readAllLines(new File(folder, "config").toPath()); List knownShops = split(config.get(0)); NumberFilter nf = new NumberFilter(split(config.get(1))); collectableItems = split(config.get(2)); filters = config.subList(3, config.size()); recipes = readRecipes(folder); List allShops = readShops(folder); knownShops.stream().filter( knownShop -> !allShops.stream().anyMatch(shop -> shop.getName().equals(knownShop))) .forEach(shop -> System.out.println(String.format("Unbekannter Shop: %s", shop))); shops = allShops.stream() .filter(shop -> knownShops.stream().anyMatch(s -> s.equals(shop.getName()))) .collect(Collectors.toList()); monsters = readMonster(folder).stream().filter(m -> nf.check(m.getNumber())) .collect(Collectors.toList()); collectableItems.stream().filter(item -> !recipes.stream().anyMatch(r -> r.has(item))) .forEach(item -> { System.out.println(String.format("'%s' is in keinem Rezept verwendet.", item)); }); } public void execute(String[] args) { if(args.length > 0) { searchFor(args); } else { printRecipes(); } } private static List readShops(String folder) throws IOException { HashMap shops = new HashMap<>(); List list = Files.readAllLines(new File(folder, "buyable").toPath()); for(String s : list) { List parts = split(s); Iterator iter = parts.iterator(); String itemName = iter.next(); int cost = Integer.parseInt(iter.next()); while(iter.hasNext()) { String shopName = iter.next(); Shop shop = shops.get(shopName); if(shop == null) { shop = new Shop(shopName); shops.put(shopName, shop); } shop.addItem(itemName, cost); } } return shops.values().stream().collect(Collectors.toList()); } private static List readMonster(String folder) throws IOException { return Files.readAllLines(new File(folder, "monsters").toPath()).stream() .map(line -> new Monster(split(line).iterator())).collect(Collectors.toList()); } private static List readRecipes(String folder) throws IOException { ArrayList recipes = new ArrayList<>(); for(File f : new File(folder, "recipes").listFiles()) { Iterator lineIter = Files.readAllLines(f.toPath()).iterator(); String category = lineIter.next(); while(lineIter.hasNext()) { List parts = split(lineIter.next()); Recipe r = new Recipe(); r.setCategory(category); Iterator iter = parts.iterator(); r.setResult(iter.next()); int c = 0; while(iter.hasNext()) { String itemName = iter.next(); int amount = Integer.parseInt(iter.next()); r.setItem(c, itemName, amount); c++; } recipes.add(r); } } return recipes; } private static List split(String s) { ArrayList parts = new ArrayList<>(); int index = 0; int old = 0; while(index < s.length()) { char c = s.charAt(index); if(c == ',') { parts.add(trim(s.substring(old, index))); old = index + 1; } else if(c == '"') { index++; while(index < s.length() && s.charAt(index) != '"') { index++; } } index++; } parts.add(trim(s.substring(old, index))); parts.removeIf((f) -> f.isEmpty()); return parts; } private static String trim(String s) { s = s.trim(); if(!s.isEmpty() && s.charAt(0) == '"' && s.charAt(s.length() - 1) == '"') { s = s.substring(1, s.length() - 1); } return s; } private HashSet getPossibleRecipes() { HashSet items = new HashSet<>(); items.addAll(collectableItems); monsters.forEach(m -> { items.add(m.getFirstDrop()); items.add(m.getSecondDrop()); }); shops.forEach(shop -> shop.addAllTo(items)); // check for all possible recipes HashSet pRecipes = new HashSet<>(); while(true) { int cRecipes = pRecipes.size(); for(Recipe r : recipes) { if(r.check(items)) { pRecipes.add(r); items.add(r.getResult()); } } if(cRecipes == pRecipes.size()) { break; } } return pRecipes; } private void printRecipes() { HashSet pRecipes = getPossibleRecipes(); filters.forEach(filter -> pRecipes.removeIf(r -> r.getResult().equals(filter))); pRecipes.stream().sorted().forEach(r -> System.out.println(r)); } private void searchFor(String[] search) { HashSet pRecipes = getPossibleRecipes(); for(String s : search) { System.out.println(String.format("%s:", s)); boolean recipeResult = printRecipesContaining(s, pRecipes); boolean shopResult = printShopsContaining(s); boolean monsterResult = printMonstersContaining(s); if(recipeResult && shopResult && monsterResult) { System.out.println("> Keine Ergebnisse"); } System.out.println(); } } private boolean printRecipesContaining(String s, HashSet pRecipes) { boolean once = true; for(Recipe r : pRecipes) { if(r.getResult().equals(s)) { if(once) { once = false; System.out.println("> Alchemie-Rezepte:"); } System.out.print(">"); System.out.println(r); } } return once; } private boolean printShopsContaining(String s) { boolean once = true; for(Shop shop : shops) { Shop.Item item = shop.search(s); if(item != null) { if(once) { once = false; System.out.print(String.format("> kaufbar um %d in: ", item.getCost())); System.out.print(shop.getName()); } else { System.out.print(", "); System.out.print(shop.getName()); } } } if(!once) { System.out.println(); } return once; } private boolean printMonstersContaining(String s) { boolean once = true; for(Monster m : monsters) { if(m.getFirstDrop().equals(s)) { if(once) { once = false; System.out.println("> Monster: "); } System.out.println(m); } if(m.getSecondDrop().equals(s)) { if(once) { once = false; System.out.println("> Monster: "); } System.out.println(m); } } return once; } }