From 4cb7b821a60d07c1da521a0a270e080bf23a13c4 Mon Sep 17 00:00:00 2001 From: agp8x Date: Sun, 9 May 2021 11:22:09 +0200 Subject: [PATCH] introduce testing, first wokring chain with screws --- build.gradle | 6 +++++ src/Test.java | 12 +++++++++ src/items/Item.java | 44 +++++++++++++++++++++++++------ src/items/Recipe.java | 41 +++++++++++++++++++++++++++- src/items/Utils.java | 2 +- src/test/java/items/ItemTest.java | 30 +++++++++++++++++++++ 6 files changed, 125 insertions(+), 10 deletions(-) create mode 100644 src/test/java/items/ItemTest.java diff --git a/build.gradle b/build.gradle index c0ce458..dabf1d7 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,13 @@ sourceSets { } } } + +test { + useJUnitPlatform() +} + dependencies{ + implementation 'org.junit.jupiter:junit-jupiter:5.7.0' compile 'com.fasterxml.jackson.core:jackson-core:2.12.2' compile 'com.fasterxml.jackson.core:jackson-databind:2.12.2' compile 'org.jgrapht:jgrapht-io:1.5.1' diff --git a/src/Test.java b/src/Test.java index 1bf6636..d525581 100644 --- a/src/Test.java +++ b/src/Test.java @@ -58,5 +58,17 @@ public class Test { Utils.fixSums(ACU, x); de.exportGraph(x, new File("acu3.dot")); + + plot(Database.Screw, "screws", 100, de); + plot(Database.ReinforcedIronPlate, "ReinforcedIronPlate", 100, de); + } + + private static void plot(Item target, String name, int amount, DOTExporter de) { + Graph screws = target.productionHierarchy(amount); + de.exportGraph(screws, new File(name + ".dot")); + System.out.println(name); + Item.production(screws).forEach((item, rate) -> { + System.out.println("\t" + item.getName() + "\t" + rate); + }); } } diff --git a/src/items/Item.java b/src/items/Item.java index ff7f518..86da71f 100644 --- a/src/items/Item.java +++ b/src/items/Item.java @@ -1,11 +1,12 @@ package items; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; +import org.jgrapht.Graph; +import org.jgrapht.graph.DefaultWeightedEdge; + +import java.util.*; -public class Item { +public abstract class Item { protected boolean isRaw = false; private String name; private Set recipes; @@ -61,11 +62,12 @@ public class Item { public Recipe getRecipe() { Recipe recipe = preference; if (recipe == null) { - recipe = recipes.stream().findFirst().orElse(null); + if (Database.preferences.containsKey(this)) { + recipe = Database.preferences.get(this); + } if (recipe == null) { - if (Database.preferences.containsKey(this)) { - recipe = Database.preferences.get(this); - } + recipe = recipes.stream().findFirst().orElse(null); + } } return recipe; @@ -83,4 +85,30 @@ public class Item { this.preference = preference; } + public Graph productionHierarchy() { + return productionHierarchy(1); + } + + public Graph productionHierarchy(int amount) { + + Graph graph = getRecipe().buildGraph(this, amount); + graph.addEdge(this,this); + graph.setEdgeWeight(this,this,amount); + return graph; + } + + public Map production(int amount){ + Graph graph = productionHierarchy(amount); + return production(graph); + } + + public static Map production(Graph graph){ + Map map = new HashMap<>(); + graph.vertexSet().forEach(item -> { + double rate = graph.outgoingEdgesOf(item).stream().mapToDouble(graph::getEdgeWeight).sum(); + map.put(item, rate); + }); + return map; + } + } diff --git a/src/items/Recipe.java b/src/items/Recipe.java index eea1af6..ee6d6af 100644 --- a/src/items/Recipe.java +++ b/src/items/Recipe.java @@ -92,7 +92,6 @@ public class Recipe { public Map getTotalRequirements() { return new TotalAccumulator(inputs).accumulate(); } - public float getProductionRate(Item item) { Integer integer = outputs.get(item); float production = integer; @@ -133,6 +132,46 @@ public class Recipe { }); + return graph; + } + + private float getLoad(Item target, float amount) { + return getUsage(target, amount) * duration; + } + + private float getUsage(Item target, float amount) { + return amount / outputs.get(target); + } + + public Graph buildGraph(Item target, float amountPerSecond) { + Graph graph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class); + graph.addVertex(target); + target.sum += 1; + float load = getLoad(target, amountPerSecond); + // byproducts + Map output = outputs.entrySet().stream() + .filter(itemIntegerEntry -> itemIntegerEntry.getKey() != target) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + output.forEach((item, integer) -> { + graph.addVertex(item); + graph.addEdge(target, item); + graph.setEdgeWeight(target, item, integer * load); + }); + // inputs + inputs.forEach((item, integer) -> { + graph.addVertex(item); + graph.addEdge(item, target); + float rate = (amountPerSecond / outputs.get(target))/integer; + graph.setEdgeWeight(item, target, rate); + + Recipe recipe = item.getRecipe(); + if (recipe != null) { + Graph g = recipe.buildGraph(item, rate); + Graphs.addGraph(graph, g); + } + }); + + return graph; } diff --git a/src/items/Utils.java b/src/items/Utils.java index 0428ee1..08c2250 100644 --- a/src/items/Utils.java +++ b/src/items/Utils.java @@ -30,7 +30,7 @@ public class Utils { } public static String dotID(Item item){ - String name = item.getName();// +"_"+item.sum+"__"+item.getProductionRate(); + String name = item.getName() +"_"+item.sum+"__"+(String.valueOf(item.getProductionRate()).replace(".","_")); name = name.replace(" ","").replace(".",""); return name; } diff --git a/src/test/java/items/ItemTest.java b/src/test/java/items/ItemTest.java new file mode 100644 index 0000000..b522334 --- /dev/null +++ b/src/test/java/items/ItemTest.java @@ -0,0 +1,30 @@ +package items; + +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +class ItemTest { + + @Test + void productionScrews() { + Map production = Database.Screw.production(100); + assertEquals(100, production.get(Database.Screw), "Screws (output)"); + assertEquals(25, production.get(Database.IronRod), "IronRod"); + assertEquals(25, production.get(Database.IronIngot), "IronIngot"); + assertEquals(25, production.get(Database.IronOre), "IronOre"); + } + + @Test + void productionReinforcedIronPlates() { + Map production = Database.ReinforcedIronPlate.production(100); + assertEquals(100, production.get(Database.ReinforcedIronPlate), "output"); + assertEquals(1200, production.get(Database.Screw), "Screws"); + assertEquals(300, production.get(Database.IronRod), "IronRod"); + assertEquals(1200, production.get(Database.IronIngot), "IronIngot"); + assertEquals(1200, production.get(Database.IronOre), "IronOre"); + assertEquals(600, production.get(Database.IronPlate), "IronPlate"); + } +} \ No newline at end of file