Merge branch 'master' of git.clkl.de:agp8x/satisfactory

master
agp8x 2023-04-09 11:15:24 +02:00
commit 25b4444a73
12 changed files with 147 additions and 152 deletions

View File

@ -10,13 +10,13 @@ repositories {
} }
dependencies { dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.2' implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3'
implementation 'org.jgrapht:jgrapht-io:1.5.1' implementation 'org.jgrapht:jgrapht-io:1.5.1'
implementation 'guru.nidi:graphviz-java:0.18.1' implementation 'guru.nidi:graphviz-java:0.18.1'
implementation 'org.graalvm.js:js:20.0.0' implementation 'org.graalvm.js:js:22.1.0.1'
implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.13.0' implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.17.2'
} }
test { test {

View File

@ -12,7 +12,7 @@ public class Database {
public static final Map<Item, Recipe> preferences = new HashMap<>(); public static final Map<Item, Recipe> preferences = new HashMap<>();
// Items & recipes // Items & recipes
public static final Item IronOre = add(new Ore("Iron Ore")); public static final Item IronOre = new Ore("Iron Ore");
public static final Item IronIngot = new Ingot("Iron Ingot"); public static final Item IronIngot = new Ingot("Iron Ingot");
public static final Item CopperOre = new Ore("Copper Ore"); public static final Item CopperOre = new Ore("Copper Ore");
public static final Item CopperIngot = new Ingot("Copper Ingot"); public static final Item CopperIngot = new Ingot("Copper Ingot");
@ -129,10 +129,10 @@ public class Database {
public static final Item ExplosiveRebar = new Part("Explosive Rebar"); public static final Item ExplosiveRebar = new Part("Explosive Rebar");
public static final Item SmokelessPowder = new Part("Smokeless Powder"); public static final Item SmokelessPowder = new Part("Smokeless Powder");
public static final Item HomingRifleAmmo = new Part("Homing Rifle Ammo"); public static final Item HomingRifleAmmo = new Part("Homing Rifle Ammo");
public static final Item GasNobelisk = new Part("Gas Nobelisk"); public static final Item GasNobelisk = new Part("Gas Nobelisk");
public static final Item ClusterNobelisk = new Part("Cluster Nobelisk"); public static final Item ClusterNobelisk = new Part("Cluster Nobelisk");
public static final Item ObjectScanner = new Tool("Object Scanner"); public static final Item ObjectScanner = new Tool("Object Scanner");
public static final Item NobeliskDetonator = new Tool("Nobelisk Detonator"); public static final Item NobeliskDetonator = new Tool("Nobelisk Detonator");
static { static {
{ {
@ -329,10 +329,10 @@ public class Database {
} }
{ {
// Alien Protein // Alien Protein
AlienProtein.add(new Recipe(3,HogRemains,1, Constructor.class)); // TODO CraftBench AlienProtein.add(new Recipe(3, HogRemains, 1, Constructor.class)); // TODO CraftBench
AlienProtein.add(new Recipe(3,PlasmaSpitterRemains,1, Constructor.class)); // TODO CraftBench AlienProtein.add(new Recipe(3, PlasmaSpitterRemains, 1, Constructor.class)); // TODO CraftBench
AlienProtein.add(new Recipe(3, StingerRemains,1, Constructor.class)); // TODO CraftBench AlienProtein.add(new Recipe(3, StingerRemains, 1, Constructor.class)); // TODO CraftBench
AlienProtein.add(new Recipe(3,HatcherRemains,1, Constructor.class)); // TODO CraftBench AlienProtein.add(new Recipe(3, HatcherRemains, 1, Constructor.class)); // TODO CraftBench
} }
{ {
// Fabric // Fabric
@ -341,9 +341,9 @@ public class Database {
recipe.addInput(Biomass, 5); recipe.addInput(Biomass, 5);
Fabric.add(recipe); Fabric.add(recipe);
Recipe alt = new Recipe(2, Refinery.class); Recipe alt = new Recipe(2, Refinery.class);
recipe.addInput(PolymerResin,1); recipe.addInput(PolymerResin, 1);
recipe.addInput(Water,1); recipe.addInput(Water, 1);
recipe.addOutput(Fabric,1); recipe.addOutput(Fabric, 1);
} }
{ {
// Solid Biofuel // Solid Biofuel
@ -467,16 +467,16 @@ public class Database {
{ {
// Gas Nobelisk // Gas Nobelisk
Recipe recipe = new Recipe(12, Assembler.class); //TODO EquipmentWorkshop Recipe recipe = new Recipe(12, Assembler.class); //TODO EquipmentWorkshop
recipe.addInput(Nobelisk,1); recipe.addInput(Nobelisk, 1);
recipe.addInput(Biomass,10); recipe.addInput(Biomass, 10);
recipe.addOutput(GasNobelisk, 1); recipe.addOutput(GasNobelisk, 1);
GasNobelisk.add(recipe); GasNobelisk.add(recipe);
} }
{ {
// Cluster Nobelisk // Cluster Nobelisk
Recipe recipe = new Recipe(24, Assembler.class); //TODO EquipmentWorkshop Recipe recipe = new Recipe(24, Assembler.class); //TODO EquipmentWorkshop
recipe.addInput(Nobelisk,3); recipe.addInput(Nobelisk, 3);
recipe.addInput(SmokelessPowder,4); recipe.addInput(SmokelessPowder, 4);
recipe.addOutput(ClusterNobelisk, 1); recipe.addOutput(ClusterNobelisk, 1);
ClusterNobelisk.add(recipe); ClusterNobelisk.add(recipe);
@ -485,9 +485,9 @@ public class Database {
// NobeliskDetonator // NobeliskDetonator
Recipe recipe = new Recipe(80, EquipmentWorkshop.class); Recipe recipe = new Recipe(80, EquipmentWorkshop.class);
recipe.addInput(ObjectScanner, 1); recipe.addInput(ObjectScanner, 1);
recipe.addInput(SteelBeam,10); recipe.addInput(SteelBeam, 10);
recipe.addInput(Cable,50); recipe.addInput(Cable, 50);
recipe.addOutput(NobeliskDetonator,1); recipe.addOutput(NobeliskDetonator, 1);
NobeliskDetonator.add(recipe); NobeliskDetonator.add(recipe);
} }
{ {
@ -543,7 +543,7 @@ public class Database {
Recipe unpack = new Recipe(2, Packager.class); Recipe unpack = new Recipe(2, Packager.class);
recipe.addInput(PackagedLiquidBiofuel, 2); recipe.addInput(PackagedLiquidBiofuel, 2);
recipe.addOutput(LiquidBiofuel, 2); recipe.addOutput(LiquidBiofuel, 2);
recipe.addOutput(EmptyCanister,2); recipe.addOutput(EmptyCanister, 2);
LiquidBiofuel.add(unpack); LiquidBiofuel.add(unpack);
} }
{ {
@ -746,61 +746,61 @@ public class Database {
{ {
// Stun Rebar // Stun Rebar
Recipe recipe = new Recipe(6, Assembler.class);//TODO , EquipmentWorkshop.class) Recipe recipe = new Recipe(6, Assembler.class);//TODO , EquipmentWorkshop.class)
recipe.addInput(IronRebar,1); recipe.addInput(IronRebar, 1);
recipe.addInput(Quickwire,5); recipe.addInput(Quickwire, 5);
recipe.addOutput(StunRebar, 1); recipe.addOutput(StunRebar, 1);
StunRebar.add(recipe); StunRebar.add(recipe);
} }
{ {
// Explosive Rebar // Explosive Rebar
Recipe recipe = new Recipe(12, Manufacturer.class);//TODO , EquipmentWorkshop.class) Recipe recipe = new Recipe(12, Manufacturer.class);//TODO , EquipmentWorkshop.class)
recipe.addInput(IronRebar,1); recipe.addInput(IronRebar, 1);
recipe.addInput(SmokelessPowder,2); recipe.addInput(SmokelessPowder, 2);
recipe.addInput(SteelPipe,2); recipe.addInput(SteelPipe, 2);
recipe.addOutput(ExplosiveRebar, 1); recipe.addOutput(ExplosiveRebar, 1);
ExplosiveRebar.add(recipe); ExplosiveRebar.add(recipe);
} }
{ {
// Rebar Gun // Rebar Gun
Recipe recipe = new Recipe(60, EquipmentWorkshop.class); Recipe recipe = new Recipe(60, EquipmentWorkshop.class);
recipe.addInput(ReinforcedIronPlate,6); recipe.addInput(ReinforcedIronPlate, 6);
recipe.addInput(IronRod,16); recipe.addInput(IronRod, 16);
recipe.addInput(Screw,100); recipe.addInput(Screw, 100);
recipe.addOutput(RebarGun, 1); recipe.addOutput(RebarGun, 1);
RebarGun.add(recipe); RebarGun.add(recipe);
} }
{ {
// Rifle Ammo // Rifle Ammo
Recipe recipe=new Recipe(12, Assembler.class);//TODO , EquipmentWorkshop.class) Recipe recipe = new Recipe(12, Assembler.class);//TODO , EquipmentWorkshop.class)
recipe.addInput(CopperSheet,3); recipe.addInput(CopperSheet, 3);
recipe.addInput(SmokelessPowder, 2); recipe.addInput(SmokelessPowder, 2);
recipe.addOutput(RifleAmmo,15); recipe.addOutput(RifleAmmo, 15);
RifleAmmo.add(recipe); RifleAmmo.add(recipe);
} }
{ {
// Homing Rifle Ammo // Homing Rifle Ammo
Recipe recipe=new Recipe(12, Assembler.class);//TODO , EquipmentWorkshop.class) Recipe recipe = new Recipe(12, Assembler.class);//TODO , EquipmentWorkshop.class)
recipe.addInput(RifleAmmo,20); recipe.addInput(RifleAmmo, 20);
recipe.addInput(HighSpeedConnector,1); recipe.addInput(HighSpeedConnector, 1);
recipe.addOutput(HomingRifleAmmo,10); recipe.addOutput(HomingRifleAmmo, 10);
HomingRifleAmmo.add(recipe); HomingRifleAmmo.add(recipe);
} }
{ {
// Rifle // Rifle
Recipe recipe=new Recipe(120, EquipmentWorkshop.class); Recipe recipe = new Recipe(120, EquipmentWorkshop.class);
recipe.addInput(Motor,2); recipe.addInput(Motor, 2);
recipe.addInput(Rubber,10); recipe.addInput(Rubber, 10);
recipe.addInput(SteelPipe,25); recipe.addInput(SteelPipe, 25);
recipe.addInput(Screw,250); recipe.addInput(Screw, 250);
recipe.addOutput(Rifle,1); recipe.addOutput(Rifle, 1);
Rifle.add(recipe); Rifle.add(recipe);
} }
{ {
// Smokeless Powder // Smokeless Powder
Recipe recipe=new Recipe(6, Refinery.class); Recipe recipe = new Recipe(6, Refinery.class);
recipe.addInput(BlackPowder,2); recipe.addInput(BlackPowder, 2);
recipe.addInput(HeavyOilResidue,1); recipe.addInput(HeavyOilResidue, 1);
recipe.addOutput(SmokelessPowder,2); recipe.addOutput(SmokelessPowder, 2);
SmokelessPowder.add(recipe); SmokelessPowder.add(recipe);
} }
} }

View File

@ -5,7 +5,6 @@ import org.jgrapht.event.ConnectedComponentTraversalEvent;
import org.jgrapht.event.EdgeTraversalEvent; import org.jgrapht.event.EdgeTraversalEvent;
import org.jgrapht.event.TraversalListener; import org.jgrapht.event.TraversalListener;
import org.jgrapht.event.VertexTraversalEvent; import org.jgrapht.event.VertexTraversalEvent;
import org.jgrapht.graph.DefaultDirectedWeightedGraph;
import org.jgrapht.graph.DefaultWeightedEdge; import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.EdgeReversedGraph; import org.jgrapht.graph.EdgeReversedGraph;
import org.jgrapht.nio.Attribute; import org.jgrapht.nio.Attribute;
@ -15,11 +14,9 @@ import org.jgrapht.traverse.DepthFirstIterator;
import org.jgrapht.traverse.GraphIterator; import org.jgrapht.traverse.GraphIterator;
import satisfactory.items.Item; import satisfactory.items.Item;
import satisfactory.items.ProductionEdge; import satisfactory.items.ProductionEdge;
import satisfactory.items.SumResult;
import java.io.File; import java.io.File;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -30,7 +27,7 @@ public class Utils {
public static Map<Item, Integer> getRawOnly(Map<Item, Integer> totals) { public static Map<Item, Integer> getRawOnly(Map<Item, Integer> totals) {
Map<Item, Integer> raws = new HashMap<>(); Map<Item, Integer> raws = new HashMap<>();
for (Item item : totals.keySet().stream().filter(Item::isRaw).collect(Collectors.toList())) { for (Item item : totals.keySet().stream().filter(Item::isRaw).toList()) {
raws.put(item, totals.get(item)); raws.put(item, totals.get(item));
} }
return raws; return raws;
@ -53,7 +50,7 @@ public class Utils {
EdgeReversedGraph<Item, DefaultWeightedEdge> inverse = new EdgeReversedGraph<>(graph); EdgeReversedGraph<Item, DefaultWeightedEdge> inverse = new EdgeReversedGraph<>(graph);
GraphIterator<Item, DefaultWeightedEdge> iterator = new DepthFirstIterator<>(inverse, target); GraphIterator<Item, DefaultWeightedEdge> iterator = new DepthFirstIterator<>(inverse, target);
iterator.addTraversalListener(new TraversalListener<Item, DefaultWeightedEdge>() { iterator.addTraversalListener(new TraversalListener<>() {
@Override @Override
public void connectedComponentFinished(ConnectedComponentTraversalEvent e) { public void connectedComponentFinished(ConnectedComponentTraversalEvent e) {
System.out.println("\tconnectedComponentFinished: " + e); System.out.println("\tconnectedComponentFinished: " + e);
@ -106,7 +103,7 @@ public class Utils {
m.put("label", DefaultAttribute.createAttribute(label)); m.put("label", DefaultAttribute.createAttribute(label));
return m; return m;
}); });
de.exportGraph(sum, new File(PLOTS +filename + ".dot")); de.exportGraph(sum, new File(PLOTS + filename + ".dot"));
} }
} }

View File

@ -9,8 +9,8 @@ import java.util.*;
public abstract class Item { public abstract class Item {
protected boolean isRaw = false; protected boolean isRaw = false;
private String name; private final String name;
private Set<Recipe> recipes; private final Set<Recipe> recipes;
private Recipe preference = null; private Recipe preference = null;
public int sum = 0; public int sum = 0;

View File

@ -2,9 +2,9 @@ package satisfactory.items;
public class Production { public class Production {
private final Item item; private final Item item;
private final int amount; private final double amount;
public Production(Item item, int amount) { public Production(Item item, double amount) {
this.item = item; this.item = item;
this.amount = amount; this.amount = amount;
} }
@ -13,7 +13,7 @@ public class Production {
return item; return item;
} }
public int getAmount() { public double getAmount() {
return amount; return amount;
} }
} }

View File

@ -5,7 +5,6 @@ import org.jgrapht.Graphs;
import org.jgrapht.graph.DefaultDirectedWeightedGraph; import org.jgrapht.graph.DefaultDirectedWeightedGraph;
import org.jgrapht.graph.DefaultWeightedEdge; import org.jgrapht.graph.DefaultWeightedEdge;
import satisfactory.buildings.Building; import satisfactory.buildings.Building;
import satisfactory.buildings.production.Assembler;
import satisfactory.items.requirements.RateAccumulator; import satisfactory.items.requirements.RateAccumulator;
import satisfactory.items.requirements.TotalAccumulator; import satisfactory.items.requirements.TotalAccumulator;
@ -122,18 +121,19 @@ public class Recipe {
return inputs; return inputs;
} }
public Map<Item,Double> getByProducts(Item reference){ public Map<Item, Double> getByProducts(Item reference) {
if (!outputs.containsKey(reference)){ if (!outputs.containsKey(reference)) {
return null; return null;
} }
return outputs.entrySet().stream().filter(itemIntegerEntry -> isByProduct(reference, itemIntegerEntry.getKey())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); 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){
public boolean isByProduct(Item reference, Item test) {
return !reference.equals(test) && outputs.containsKey(reference) && outputs.containsKey(test); return !reference.equals(test) && outputs.containsKey(reference) && outputs.containsKey(test);
} }
public Graph<Item, DefaultWeightedEdge> buildGraph(Item target) { public Graph<Item, DefaultWeightedEdge> buildGraph(Item target) {
System.out.println("buildGraph(" + target.getName() + ") @ "+ name); System.out.println("buildGraph(" + target.getName() + ") @ " + name);
Graph<Item, DefaultWeightedEdge> graph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class); Graph<Item, DefaultWeightedEdge> graph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class);
graph.addVertex(target); graph.addVertex(target);
target.sum += 1; target.sum += 1;
@ -169,25 +169,25 @@ public class Recipe {
return productWantedPerMinute / productPerProcess; return productWantedPerMinute / productPerProcess;
} }
private double getByproductRate(Item main, Item product, double production){ private double getByproductRate(Item main, Item product, double production) {
double runs = getRequiredProcessRuns(main, production); double runs = getRequiredProcessRuns(main, production);
return product.getRecipe().outputs.get(product) * runs; return product.getRecipe().outputs.get(product) * runs;
} }
public SumResult sum(Item target, int prodPerMinute) { public SumResult sum(Item target, double prodPerMinute) {
Graph<Item, DefaultWeightedEdge> buildGraph = buildGraph(target); Graph<Item, DefaultWeightedEdge> buildGraph = buildGraph(target);
Graph<Item, ProductionEdge> production = new DefaultDirectedWeightedGraph<>(ProductionEdge.class); Graph<Item, ProductionEdge> production = new DefaultDirectedWeightedGraph<>(ProductionEdge.class);
Map<Item, Double> map = new HashMap<>(); Map<Item, Double> map = new HashMap<>();
Queue<Item> queue = new LinkedList<>(); Queue<Item> queue = new LinkedList<>();
queue.add(target); queue.add(target);
map.put(target, (double) prodPerMinute); map.put(target, prodPerMinute);
production.addVertex(target); production.addVertex(target);
production.addEdge(target, target, new ProductionEdge(target, target, prodPerMinute, processesNeeded(target, prodPerMinute))); production.addEdge(target, target, new ProductionEdge(target, target, prodPerMinute, processesNeeded(target, prodPerMinute)));
Set<Item> visited = new HashSet<>(); Set<Item> visited = new HashSet<>();
while (!queue.isEmpty()) { while (!queue.isEmpty()) {
Item item = queue.remove(); Item item = queue.remove();
if (visited.contains(item)){ if (visited.contains(item)) {
System.out.println("hint: already processed " + item.getName()+ "! Skip!"); System.out.println("hint: already processed " + item.getName() + "! Skip!");
//continue; //continue;
} else { } else {
// next items // next items
@ -205,7 +205,7 @@ public class Recipe {
System.out.println(item.getName()); System.out.println(item.getName());
if (item.getRecipe().outputs.containsKey(product)) { // TODO: method isByProduct if (item.getRecipe().outputs.containsKey(product)) { // TODO: method isByProduct
// product is by-product, no forward dependency // product is by-product, no forward dependency
System.out.println("BY-PRODUCT " + item.getName() + " -> " + product.getName() + "... "+ queue); System.out.println("BY-PRODUCT " + item.getName() + " -> " + product.getName() + "... " + queue);
byProducts.add(product); byProducts.add(product);
continue; continue;
} }
@ -235,9 +235,7 @@ public class Recipe {
} }
visited.add(item); visited.add(item);
} }
map.forEach((item, aDouble) -> { map.forEach((item, aDouble) -> System.out.println(item.getName() + ": " + aDouble));
System.out.println(item.getName() + ": " + aDouble);
});
return new SumResult(production, map); return new SumResult(production, map);
} }

View File

@ -31,10 +31,10 @@ public class SumResult {
return map; return map;
} }
public SumResult merge(SumResult other){ public SumResult merge(SumResult other) {
HashMap<Item, Double> map = new HashMap<>(); HashMap<Item, Double> map = new HashMap<>();
this.map.forEach(map::put); map.putAll(this.map);
other.map.forEach((item, aDouble) -> map.merge(item,aDouble,Double::sum)); other.map.forEach((item, aDouble) -> map.merge(item, aDouble, Double::sum));
return new SumResult(merge(production, other.getProduction()), map); return new SumResult(merge(production, other.getProduction()), map);
} }
@ -58,8 +58,7 @@ public class SumResult {
graph1.vertexSet().forEach(result::addVertex); graph1.vertexSet().forEach(result::addVertex);
graph1.edgeSet().forEach(productionEdge -> { graph1.edgeSet().forEach(productionEdge -> {
List<ProductionEdge> collect = result.edgeSet().stream() List<ProductionEdge> collect = result.edgeSet().stream()
.filter(productionEdge1 -> productionEdge1.hasSource(productionEdge.getSource())) .filter(productionEdge1 -> productionEdge1.hasSource(productionEdge.getSource())).toList();
.collect(Collectors.toList());
collect.forEach(edge -> { collect.forEach(edge -> {
Item src = result.getEdgeSource(edge); Item src = result.getEdgeSource(edge);
Item target = result.getEdgeTarget(edge); Item target = result.getEdgeTarget(edge);

View File

@ -6,43 +6,43 @@ import satisfactory.items.Recipe;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public abstract class Accumulator<E extends Number> implements RequirementAccumulator<E>{ public abstract class Accumulator<E extends Number> implements RequirementAccumulator<E> {
protected Map<Item, E> inputs; protected Map<Item, E> inputs;
public Accumulator(Map<Item, E> inputs) { public Accumulator(Map<Item, E> inputs) {
this.inputs = inputs; this.inputs = inputs;
} }
protected abstract E calculate(Item i, E subAmount, E amount, Map<Item, E> total); protected abstract E calculate(Item i, E subAmount, E amount, Map<Item, E> total);
protected abstract E dequeue(Item item, E amount, Map<Item, E> totals); protected abstract E dequeue(Item item, E amount, Map<Item, E> totals);
@Override @Override
public Map<Item, E> accumulate() { public Map<Item, E> accumulate() {
Map<Item, E> total = new HashMap<>(); Map<Item, E> total = new HashMap<>();
Map<Item, E> queue = new HashMap<>(); Map<Item, E> queue = new HashMap<>();
for (Item i : inputs.keySet()) { for (Item i : inputs.keySet()) {
queue.put(i, inputs.get(i)); queue.put(i, inputs.get(i));
} }
while (!queue.isEmpty()) { while (!queue.isEmpty()) {
Item i = queue.keySet().iterator().next(); Item i = queue.keySet().iterator().next();
E amount = queue.remove(i); E amount = queue.remove(i);
E newTotal = dequeue(i, amount, total); E newTotal = dequeue(i, amount, total);
total.put(i,newTotal); total.put(i, newTotal);
if (i.getRecipes().isEmpty()) { if (i.getRecipes().isEmpty()) {
continue; continue;
} }
Recipe r = i.getRecipes().iterator().next(); Recipe r = i.getRecipes().iterator().next();
Map<Item, E> subRequirements = getRequirements(r, i); Map<Item, E> subRequirements = getRequirements(r, i);
for (Item subItem : subRequirements.keySet()) { for (Item subItem : subRequirements.keySet()) {
E subAmount = subRequirements.get(subItem); E subAmount = subRequirements.get(subItem);
E newSubTotal = calculate(subItem, subAmount, amount, total); E newSubTotal = calculate(subItem, subAmount, amount, total);
total.put(subItem, newSubTotal); total.put(subItem, newSubTotal);
} }
} }
return total; return total;
} }
protected abstract Map<Item,E> getRequirements(Recipe r, Item i);// r.getTotalRequirements() protected abstract Map<Item, E> getRequirements(Recipe r, Item i);// r.getTotalRequirements()
} }

View File

@ -7,28 +7,28 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class RateAccumulator extends Accumulator<Double> { public class RateAccumulator extends Accumulator<Double> {
private Item item; private final Item item;
public RateAccumulator(Recipe recipe, Item item) { public RateAccumulator(Recipe recipe, Item item) {
super(new HashMap<>()); super(new HashMap<>());
recipe.getInputs().forEach((item1, integer) -> inputs.put(item1, integer)); inputs.putAll(recipe.getInputs());
this.item = item; this.item = item;
} }
@Override @Override
protected Double calculate(Item i, Double subAmount, Double amount, Map<Item, Double> total) { protected Double calculate(Item i, Double subAmount, Double amount, Map<Item, Double> total) {
Double base = total.getOrDefault(i, 0.0); Double base = total.getOrDefault(i, 0.0);
double additional = subAmount * amount * i.getProductionRate(); double additional = subAmount * amount * i.getProductionRate();
return base + additional; return base + additional;
} }
@Override @Override
protected Double dequeue(Item item, Double amount, Map<Item, Double> totals) { protected Double dequeue(Item item, Double amount, Map<Item, Double> totals) {
return totals.getOrDefault(item, 0.0) + amount; return totals.getOrDefault(item, 0.0) + amount;
} }
@Override @Override
protected Map<Item, Double> getRequirements(Recipe r, Item i) { protected Map<Item, Double> getRequirements(Recipe r, Item i) {
return r.getRequirementRates(i); return r.getRequirementRates(i);
} }
} }

View File

@ -4,6 +4,6 @@ import satisfactory.items.Item;
import java.util.Map; import java.util.Map;
public interface RequirementAccumulator<E extends Number> { public interface RequirementAccumulator<E extends Number> {
Map<Item, E> accumulate(); Map<Item, E> accumulate();
} }

View File

@ -5,25 +5,25 @@ import satisfactory.items.Recipe;
import java.util.Map; import java.util.Map;
public class TotalAccumulator extends Accumulator<Double>{ public class TotalAccumulator extends Accumulator<Double> {
public TotalAccumulator(Map<Item, Double> inputs) { public TotalAccumulator(Map<Item, Double> inputs) {
super(inputs); super(inputs);
} }
@Override @Override
protected Double calculate(Item i, Double subAmount, Double amount, Map<Item, Double> total) { protected Double calculate(Item i, Double subAmount, Double amount, Map<Item, Double> total) {
return total.getOrDefault(i, 0.0) + subAmount * amount; return total.getOrDefault(i, 0.0) + subAmount * amount;
} }
@Override @Override
protected Double dequeue(Item item, Double amount, Map<Item, Double> totals) { protected Double dequeue(Item item, Double amount, Map<Item, Double> totals) {
return totals.getOrDefault(item, 0.0) + amount; return totals.getOrDefault(item, 0.0) + amount;
} }
@Override @Override
protected Map<Item, Double> getRequirements(Recipe r, Item i) { protected Map<Item, Double> getRequirements(Recipe r, Item i) {
return r.getTotalRequirements(); return r.getTotalRequirements();
} }
} }

View File

@ -2,6 +2,7 @@ package satisfactory.items;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import satisfactory.Database; import satisfactory.Database;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
public class DatabaseTest { public class DatabaseTest {
@ -9,7 +10,7 @@ public class DatabaseTest {
void testWaterPreference() { void testWaterPreference() {
Item i = Database.Water; Item i = Database.Water;
assertSame(i.getPreference(), i.getRecipe()); assertSame(i.getPreference(), i.getRecipe());
assertTrue(i.getPreference() == i.getRecipe()); assertSame(i.getPreference(), i.getRecipe());
assertTrue(i.getRecipe().toString().contains("water pump thingy")); assertTrue(i.getRecipe().toString().contains("water pump thingy"));
} }
} }