diff --git a/src/main/java/satisfactory/Test.java b/src/main/java/satisfactory/Test.java index b139876..4ce4530 100644 --- a/src/main/java/satisfactory/Test.java +++ b/src/main/java/satisfactory/Test.java @@ -99,7 +99,10 @@ public class Test { Recipe recipe = b.getRecipe(); System.out.println(recipe); //plot(Database.GasFilter, "rubber",1); - plot(Database.RadioControlUnit, "alu", 1); + plot(Database.AluminumCasing, "aluCase", 1); + SumResult ac = SumResult.sum(new Production(Database.AluminumCasing,1)); + plot2(ac.getProduction(), "aluCase_sum"); + //System.exit(128); Item i = Database.AluminumIngot; //plot2(SumResult.sum(i, 1),"rubber_"); //plot(i, "rcu_hierarchy",1); diff --git a/src/main/java/satisfactory/items/Item.java b/src/main/java/satisfactory/items/Item.java index 35d3637..fa909f7 100644 --- a/src/main/java/satisfactory/items/Item.java +++ b/src/main/java/satisfactory/items/Item.java @@ -105,4 +105,5 @@ public abstract class Item { public Recipe getPreference() { return preference; } + } diff --git a/src/main/java/satisfactory/items/Recipe.java b/src/main/java/satisfactory/items/Recipe.java index 0422311..0ed6520 100644 --- a/src/main/java/satisfactory/items/Recipe.java +++ b/src/main/java/satisfactory/items/Recipe.java @@ -107,6 +107,16 @@ public class Recipe { return inputs; } + public Map getByProducts(Item reference){ + if (!outputs.containsKey(reference)){ + return null; + } + return outputs.entrySet().stream().filter(itemIntegerEntry -> isByProduct(reference, itemIntegerEntry.getKey())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } + public boolean isByProduct(Item reference, Item test){ + return !reference.equals(test) && outputs.containsKey(reference) && outputs.containsKey(test); + } + public Graph buildGraph(Item target) { System.out.println("buildGraph(" + target.getName() + ") @ "+ name); Graph graph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class); @@ -139,6 +149,16 @@ public class Recipe { return n / r.getProductionRate(target); } + private double getRequiredProcessRuns(Item product, Double productWantedPerMinute) { + int productPerProcess = product.getRecipe().outputs.get(product); + return productWantedPerMinute / productPerProcess; + } + + private double getByproductRate(Item main, Item product, double production){ + double runs = getRequiredProcessRuns(main, production); + return product.getRecipe().outputs.get(product) * runs; + } + public SumResult sum(Item target, int prodPerMinute) { Graph buildGraph = buildGraph(target); Graph production = new DefaultDirectedWeightedGraph<>(ProductionEdge.class); @@ -148,13 +168,19 @@ public class Recipe { map.put(target, (double) prodPerMinute); production.addVertex(target); production.addEdge(target, target, new ProductionEdge(target, target, prodPerMinute, processesNeeded(target, prodPerMinute))); + Set visited = new HashSet<>(); while (!queue.isEmpty()) { Item item = queue.remove(); - // next items - buildGraph.incomingEdgesOf(item) - .stream() - .map(buildGraph::getEdgeSource) - .forEach(queue::add); + if (visited.contains(item)){ + System.out.println("hint: already processed " + item.getName()+ "! Skip!"); + //continue; + } else { + // next items + buildGraph.incomingEdgesOf(item) + .stream() + .map(buildGraph::getEdgeSource) + .forEach(queue::add); + } // *this* item double sum = 0; Set byProducts = new HashSet<>(); @@ -162,9 +188,9 @@ public class Recipe { Item product = buildGraph.getEdgeTarget(edge); Double productWantedPerMinute = map.get(product); System.out.println(item.getName()); - if (item.getRecipe().outputs.containsKey(product)) { + if (item.getRecipe().outputs.containsKey(product)) { // TODO: method isByProduct // product is by-product, no forward dependency - System.out.println("BY-PRODUCT " + item.getName() + " -> " + product.getName()); + System.out.println("BY-PRODUCT " + item.getName() + " -> " + product.getName() + "... "+ queue); byProducts.add(product); continue; } @@ -173,8 +199,7 @@ public class Recipe { break; } double amountNeeded = buildGraph.getEdgeWeight(edge); - int productPerProcess = product.getRecipe().outputs.get(product); - double requiredProcesRuns = productWantedPerMinute / productPerProcess; + double requiredProcesRuns = getRequiredProcessRuns(product, productWantedPerMinute); double requiredInput = amountNeeded * requiredProcesRuns; sum += requiredInput; @@ -185,12 +210,15 @@ public class Recipe { map.put(item, sum); } if (!byProducts.isEmpty()) { + double finalSum = sum; byProducts.forEach(item1 -> { production.addVertex(item1); // TODO: calculate produced amount - production.addEdge(item, item1, new ProductionEdge(item, item1, 0, 0)); + double byproductRate = getByproductRate(item, item1, finalSum); + production.addEdge(item, item1, new ProductionEdge(item, item1, byproductRate, processesNeeded(item, finalSum))); }); } + visited.add(item); } map.forEach((item, aDouble) -> { System.out.println(item.getName() + ": " + aDouble);