Compare commits
3 Commits
6d778d16aa
...
0ab1f7b330
| Author | SHA1 | Date |
|---|---|---|
|
|
0ab1f7b330 | |
|
|
f8bdb9902b | |
|
|
a2db6b7765 |
|
|
@ -128,6 +128,7 @@ public class Test {
|
|||
new Production(Database.IronPlate, 1));
|
||||
planFor("p3_acu", new Production(Database.AdaptiveControlUnit, 1));
|
||||
planFor("p3_me", new Production(Database.ModularEngine, 1));
|
||||
planFor("p3_me_acu", new Production(Database.ModularEngine, 1), new Production(Database.AdaptiveControlUnit, 1));
|
||||
planFor("p3_vf", new Production(Database.VersatileFrameWork, 1));
|
||||
planFor("screw", new Production(Database.ReinforcedIronPlate, 1));
|
||||
planFor("rotor", new Production(Database.Rotor, 1));
|
||||
|
|
|
|||
|
|
@ -106,8 +106,15 @@ public class Utils {
|
|||
if (item.isRaw()) {
|
||||
m.put("peripheries", DefaultAttribute.createAttribute(2));
|
||||
}
|
||||
|
||||
String label = item.getName();
|
||||
double required = sum.outgoingEdgesOf(item).stream().map(ProductionEdge::getTotalRequired).reduce(Double::sum).orElseGet(() -> Double.NaN);
|
||||
double instances = sum.outgoingEdgesOf(item).stream().map(ProductionEdge::getInstances).reduce(Double::sum).orElseGet(() -> Double.NaN);
|
||||
String buildingName = item.getRecipe().getBuilding().getName();
|
||||
if (Double.isNaN(required) || Double.isNaN(instances)) {
|
||||
required = -sum.incomingEdgesOf(item).stream().map(ProductionEdge::getTotalProduced).reduce(Double::sum).orElseGet(() -> Double.NaN);
|
||||
instances = 0;
|
||||
buildingName = "";
|
||||
}
|
||||
String label = "%s \n(%.1f||%.1f)\n%s".formatted(item.getName(), required, instances,buildingName);
|
||||
m.put("label", DefaultAttribute.createAttribute(label));
|
||||
return m;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,6 +7,12 @@ public class ProductionEdge {
|
|||
private final Item target;
|
||||
private double totalRequired;
|
||||
private double instances;
|
||||
private boolean ignoreUpstream;
|
||||
|
||||
public ProductionEdge(Item source, Item target, double totalRequired, double productionRate, boolean ignoreUpstream) {
|
||||
this(source, target, totalRequired, productionRate);
|
||||
this.ignoreUpstream = ignoreUpstream;
|
||||
}
|
||||
|
||||
public ProductionEdge(Item source, Item target, double totalRequired, double productionRate) {
|
||||
this.source = source;
|
||||
|
|
@ -28,6 +34,13 @@ public class ProductionEdge {
|
|||
}
|
||||
|
||||
public double getTotalRequired() {
|
||||
if (ignoreUpstream){
|
||||
return 0.0;
|
||||
}
|
||||
return totalRequired;
|
||||
}
|
||||
public double getTotalProduced(){
|
||||
// for byproducts
|
||||
return totalRequired;
|
||||
}
|
||||
|
||||
|
|
@ -36,6 +49,9 @@ public class ProductionEdge {
|
|||
}
|
||||
|
||||
public double getInstances() {
|
||||
if (ignoreUpstream){
|
||||
return 0.0;
|
||||
}
|
||||
return instances;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -179,7 +179,11 @@ public class Recipe {
|
|||
|
||||
private double getByproductRate(Item main, Item product, double production) {
|
||||
double runs = getRequiredProcessRuns(main, production);
|
||||
return product.getRecipe().outputs.get(product) * runs;
|
||||
System.out.printf("BY-RATE: %s -> %s%n", main.getName(), product.getName());
|
||||
if (!main.getRecipe().outputs.containsKey(product)){
|
||||
return Double.NaN;
|
||||
}
|
||||
return main.getRecipe().outputs.get(product) * runs;
|
||||
}
|
||||
|
||||
public SumResult sum(Item target, double prodPerMinute) {
|
||||
|
|
@ -192,6 +196,7 @@ public class Recipe {
|
|||
production.addVertex(target);
|
||||
production.addEdge(target, target, new ProductionEdge(target, target, prodPerMinute, processesNeeded(target, prodPerMinute)));
|
||||
Set<Item> visited = new HashSet<>(); // keep track of which items are already expanded fully into the graph
|
||||
Set<Item> by = new HashSet<>(); // keep track of which items are already expanded fully into the graph
|
||||
while (!queue.isEmpty()) {
|
||||
Item item = queue.remove();
|
||||
if (!visited.contains(item)) {
|
||||
|
|
@ -199,6 +204,7 @@ public class Recipe {
|
|||
buildGraph.incomingEdgesOf(item)
|
||||
.stream()
|
||||
.map(buildGraph::getEdgeSource)
|
||||
//.filter(item1 -> !item.getRecipe().isByProduct(item1))
|
||||
.forEach(queue::add);
|
||||
}
|
||||
// *this* item
|
||||
|
|
@ -211,13 +217,15 @@ public class Recipe {
|
|||
// product is by-product, no forward dependency
|
||||
System.out.println("BY-PRODUCT " + item.getName() + " -> " + product.getName() + "... " + queue);
|
||||
byProducts.add(product);
|
||||
//visited.add(product);
|
||||
continue;
|
||||
}
|
||||
if (queue.contains(product) || productWantedPerMinute == null) {
|
||||
// defer update, no all usages are expanded yet
|
||||
System.err.println("product still queued or productWantedPerMinute null for '" + product.getName() + "' from '" + item.getName() + "'");
|
||||
sum = 0;
|
||||
queue.add(item);
|
||||
//if (!item.getRecipe().isByProduct(product)){
|
||||
queue.add(item);//}
|
||||
break;
|
||||
}
|
||||
double amountNeeded = buildGraph.getEdgeWeight(edge);
|
||||
|
|
@ -233,15 +241,22 @@ public class Recipe {
|
|||
}
|
||||
if (!byProducts.isEmpty()) {
|
||||
double finalSum = sum;
|
||||
byProducts.forEach(item1 -> {
|
||||
production.addVertex(item1);
|
||||
byProducts.forEach(byproduct -> {
|
||||
production.addVertex(byproduct);
|
||||
// TODO: calculate produced amount
|
||||
double byproductRate = getByproductRate(item, item1, finalSum);
|
||||
production.addEdge(item, item1, new ProductionEdge(item, item1, byproductRate, processesNeeded(item, finalSum)));
|
||||
double byproductRate = getByproductRate(item, byproduct, finalSum);
|
||||
production.addEdge(item, byproduct, new ProductionEdge(item, byproduct, byproductRate, processesNeeded(item, finalSum), true));
|
||||
});
|
||||
by.addAll(byProducts);
|
||||
}
|
||||
visited.add(item);
|
||||
}
|
||||
by.forEach(item -> {production.incomingEdgesOf(item).forEach(productionEdge -> {
|
||||
Item source = productionEdge.getSource();
|
||||
double sourceRate = map.get(source);
|
||||
double byProductRate = getByproductRate(source, item, sourceRate);
|
||||
map.put(item, byProductRate + map.getOrDefault(item,0.0));
|
||||
});});
|
||||
map.forEach((item, aDouble) -> System.out.println(item.getName() + ": " + aDouble));
|
||||
return new SumResult(production, map);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ public class SumResult {
|
|||
.map(prod -> prod.getItem().getRecipe().sum(prod.getItem(), prod.getAmount()))
|
||||
.reduce(SumResult::merge).orElse(new SumResult());
|
||||
}
|
||||
public static SumResult sum(List<Production> productions) {
|
||||
return productions.stream()
|
||||
.map(prod -> prod.getItem().getRecipe().sum(prod.getItem(), prod.getAmount()))
|
||||
.reduce(SumResult::merge).orElse(new SumResult());
|
||||
}
|
||||
|
||||
public static Graph<Item, ProductionEdge> merge(Graph<Item, ProductionEdge> graph0, Graph<Item, ProductionEdge> graph1) {
|
||||
// ToDo: test!
|
||||
|
|
@ -69,8 +74,7 @@ public class SumResult {
|
|||
}
|
||||
|
||||
public SumResult merge(SumResult other) {
|
||||
HashMap<Item, Double> map = new HashMap<>();
|
||||
map.putAll(this.map);
|
||||
HashMap<Item, Double> map = new HashMap<>(this.map);
|
||||
other.map.forEach((item, aDouble) -> map.merge(item, aDouble, Double::sum));
|
||||
return new SumResult(merge(production, other.getProduction()), map);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,21 @@ class ItemTest {
|
|||
|
||||
@Test
|
||||
void productionUraniumFuelRod(){
|
||||
test(Database.UraniumFuelRod, "uranium_fuel_rod");
|
||||
//test(Database.UraniumFuelRod, "uranium_fuel_rod");
|
||||
fail();
|
||||
}
|
||||
|
||||
@Test
|
||||
void productionPlastic(){
|
||||
test(Database.Plastic,"plastic");
|
||||
}
|
||||
@Test
|
||||
void productionRubber(){
|
||||
test(Database.Rubber,"rubber");
|
||||
}
|
||||
@Test
|
||||
void productionRubberAndPlastic(){
|
||||
test("rubberAndPlastic",Database.Rubber, Database.Plastic);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -3,23 +3,21 @@ package satisfactory.items;
|
|||
import org.junit.jupiter.api.Test;
|
||||
import satisfactory.Database;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static satisfactory.items.TestHelper.*;
|
||||
import static satisfactory.items.TestHelper.test;
|
||||
|
||||
class Phase3Test {
|
||||
|
||||
@Test
|
||||
void testPhase3_ACU() {
|
||||
Item item = Database.AdaptiveControlUnit;
|
||||
test(item);
|
||||
test(item, "p3_acu");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testPhase3_ME() {
|
||||
Item item = Database.ModularEngine;
|
||||
test(item);
|
||||
test(item, "p3_me");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -31,70 +29,21 @@ class Phase3Test {
|
|||
|
||||
@Test
|
||||
void testPhase3_ME_ACU_VF() {
|
||||
// references
|
||||
Map<Item, Double> ref = merge(
|
||||
ValidatedValues.get(Database.ModularEngine),
|
||||
ValidatedValues.get(Database.AdaptiveControlUnit),
|
||||
ValidatedValues.get(Database.VersatileFrameWork));
|
||||
ref.forEach((item, aDouble) -> System.out.println(aDouble + "\t" + item.getName()));
|
||||
|
||||
// calculate
|
||||
Map<Item, Double> calculations = SumResult.sum(
|
||||
new Production(Database.ModularEngine, 1),
|
||||
new Production(Database.AdaptiveControlUnit, 1),
|
||||
new Production(Database.VersatileFrameWork, 1)
|
||||
).getMap();
|
||||
|
||||
// assert
|
||||
assertMap(ref, calculations);
|
||||
test(Database.ModularEngine, Database.AdaptiveControlUnit, Database.VersatileFrameWork);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPhase3_ME_ACU() {
|
||||
// references
|
||||
Map<Item, Double> ref1 = merge(
|
||||
ValidatedValues.get(Database.ModularEngine),
|
||||
ValidatedValues.get(Database.AdaptiveControlUnit)
|
||||
);
|
||||
|
||||
// calculate
|
||||
Map<Item, Double> calculations1 = SumResult.sum(
|
||||
new Production(Database.ModularEngine, 1),
|
||||
new Production(Database.AdaptiveControlUnit, 1)
|
||||
).getMap();
|
||||
|
||||
// assert
|
||||
assertMap(ref1, calculations1);
|
||||
test(Database.ModularEngine, Database.AdaptiveControlUnit);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPhase3_ACU_VF() {
|
||||
// references
|
||||
Map<Item, Double> ref1 = merge(
|
||||
ValidatedValues.get(Database.AdaptiveControlUnit),
|
||||
ValidatedValues.get(Database.VersatileFrameWork));
|
||||
|
||||
// calculate
|
||||
Map<Item, Double> calculations1 = SumResult.sum(
|
||||
new Production(Database.AdaptiveControlUnit, 1),
|
||||
new Production(Database.VersatileFrameWork, 1)
|
||||
).getMap();
|
||||
|
||||
// assert
|
||||
assertMap(ref1, calculations1);
|
||||
test(Database.AdaptiveControlUnit, Database.VersatileFrameWork);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPhase3_ME_VF() {
|
||||
// references
|
||||
Map<Item, Double> ref1 = merge(
|
||||
ValidatedValues.get(Database.ModularEngine),
|
||||
ValidatedValues.get(Database.VersatileFrameWork));
|
||||
|
||||
// calculate
|
||||
Map<Item, Double> calculations1 = SumResult.sum(
|
||||
new Production(Database.ModularEngine, 1),
|
||||
new Production(Database.VersatileFrameWork, 1)
|
||||
).getMap();
|
||||
test(Database.ModularEngine, Database.VersatileFrameWork);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,9 @@ package satisfactory.items;
|
|||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
|
@ -38,12 +40,37 @@ public class TestHelper {
|
|||
assertMap(ref, calculations.getMap());
|
||||
}
|
||||
|
||||
public static void test(String name, Item... items) {
|
||||
|
||||
// references
|
||||
Map<Item, Double> ref1 = merge(Arrays.stream(items).map(ValidatedValues::get).toList());
|
||||
|
||||
// calculate
|
||||
SumResult sumResult = SumResult.sum(Arrays.stream(items).map(item -> new Production(item, 1.0)).toList());
|
||||
Map<Item, Double> calculations = sumResult.getMap();
|
||||
|
||||
// plot
|
||||
if (name != null) {
|
||||
name = "test_" + name;
|
||||
plot2(sumResult.getProduction(), name);
|
||||
javaPlot(name);
|
||||
list(sumResult, name);
|
||||
}
|
||||
|
||||
// assert
|
||||
assertMap(ref1, calculations);
|
||||
}
|
||||
|
||||
public static void test(Item... items) {
|
||||
test(null, items);
|
||||
}
|
||||
|
||||
private static SumResult calculate(Item item) {
|
||||
// calculate
|
||||
return SumResult.sum(new Production(item, 1));
|
||||
}
|
||||
|
||||
public static <K> Map<K, Double> merge(Map<K, Double>... single_refs) {
|
||||
public static <K> Map<K, Double> merge(List<Map<K, Double>> single_refs) {
|
||||
Map<K, Double> ref = new HashMap<>();
|
||||
for (Map<K, Double> singleRef : single_refs) {
|
||||
singleRef.forEach((singleItem, singleValue) -> ref.compute(singleItem, (refItem, refValue) -> singleValue + check(refValue)));
|
||||
|
|
@ -77,7 +104,7 @@ public class TestHelper {
|
|||
//c.put("b", 4.0);
|
||||
e.put("b", 3.);
|
||||
}
|
||||
Map<String, Double> m = merge(a, b, c);
|
||||
Map<String, Double> m = merge(Arrays.asList(a, b, c));
|
||||
e.forEach((s, aDouble) -> {
|
||||
assertEquals(aDouble, m.get(s));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -78,6 +78,22 @@ public class ValidatedValues {
|
|||
ref.put(item, 1.);
|
||||
values.put(item, ref);
|
||||
}
|
||||
{
|
||||
Item item = Database.Plastic;
|
||||
Map<Item, Double> ref = new HashMap<>();
|
||||
ref.put(Database.CrudeOil, 1.5);
|
||||
ref.put(Database.Plastic, 1.);
|
||||
ref.put(Database.HeavyOilResidue, 0.5);
|
||||
values.put(item, ref);
|
||||
}
|
||||
{
|
||||
Item item = Database.Rubber;
|
||||
Map<Item, Double> ref = new HashMap<>();
|
||||
ref.put(Database.CrudeOil, 1.5);
|
||||
ref.put(Database.HeavyOilResidue, 1.);
|
||||
ref.put(item, 1.);
|
||||
values.put(item, ref);
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<Item, Double> get(Item item) {
|
||||
|
|
@ -113,7 +129,7 @@ public class ValidatedValues {
|
|||
ref.put(Database.CopperIngot, 249.0);
|
||||
ref.put(Database.IronRod, 90.5);
|
||||
ref.put(Database.IronIngot, 158.0);
|
||||
//ref.put(Database.HeavyOilResidue, 39.0); // FIXME byproduct
|
||||
ref.put(Database.HeavyOilResidue, 39.0); // FIXME byproduct
|
||||
ref.put(Database.CopperSheet, 30.0);
|
||||
return ref;
|
||||
}
|
||||
|
|
@ -140,7 +156,7 @@ public class ValidatedValues {
|
|||
ref.put(Database.SmartPlating, 2.0);
|
||||
ref.put(Database.ReinforcedIronPlate, 2.0);
|
||||
ref.put(Database.Rubber, 15.0);
|
||||
//ref.put(Database.HeavyOilResidue, 15.0); // FIXME byproduct
|
||||
ref.put(Database.HeavyOilResidue, 15.0); // FIXME byproduct
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue