add summary for buildings, power and build resources

master
agp8x 2023-04-10 11:17:36 +02:00
parent c4cf7c9ec9
commit ee35fcf49b
7 changed files with 162 additions and 86 deletions

View File

@ -1,26 +1,11 @@
package satisfactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import guru.nidi.graphviz.engine.Format;
import guru.nidi.graphviz.engine.Graphviz;
import guru.nidi.graphviz.model.MutableGraph;
import guru.nidi.graphviz.parse.Parser;
import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.nio.Attribute;
import org.jgrapht.nio.DefaultAttribute;
import org.jgrapht.nio.dot.DOTExporter;
import satisfactory.items.Item;
import satisfactory.items.Production;
import satisfactory.items.Recipe;
import satisfactory.items.SumResult;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@ -162,64 +147,6 @@ public class Test {
list(plan, name);
}
private static void plot(Item target, String name, int amount) {
Graph<Item, DefaultWeightedEdge> screws = target.hierarchy();
DOTExporter<Item, DefaultWeightedEdge> de = new DOTExporter<>(Utils::dotID);
de.setEdgeAttributeProvider(defaultWeightedEdge -> {
Map<String, Attribute> m = new HashMap<>();
m.put("label", DefaultAttribute.createAttribute(screws.getEdgeWeight(defaultWeightedEdge)));
return m;
});
de.exportGraph(screws, new File(PLOTS + name + ".dot"));
System.out.println(name);
Item.production(screws).forEach((item, rate) -> {
System.out.println("\t" + item.getName() + "\t" + rate);
});
}
private static void javaPlot(String name) {
try {
MutableGraph dot = new Parser().read(new File(PLOTS + name + ".dot"));
Graphviz.fromGraph(dot).render(Format.PNG).toFile(new File(PLOTS + name + "_java.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
private static String name2(String name3) {
return Arrays.stream(Database.class.getFields()).filter(field -> {
try {
return field.getType().equals(Item.class) && ((Item) field.get(null)).getName().equals(name3);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}).findFirst().get().getName();
}
private static void list(SumResult plan, String name) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter(LISTS + name + ".txt"))) {
String list = plan.getMap().entrySet().stream().map(item -> item.getKey().getName() + ": " + item.getValue()).reduce("", (s, s2) -> s + "\n" + s2);
bw.write(list);
} catch (IOException e) {
throw new RuntimeException(e);
}
try (BufferedWriter bw = new BufferedWriter(new FileWriter(LISTS + name + "_java.txt"))) {
String list = plan.getMap().entrySet().stream().map(item ->
"ref.put(Database." + name2(item.getKey().getName()) + ", " + item.getValue() + ");"
).reduce("", (s, s2) -> s + "\n" + s2);
bw.write(list);
} catch (IOException e) {
throw new RuntimeException(e);
}
try (BufferedWriter bw = new BufferedWriter(new FileWriter(LISTS + name + "_buildings.txt"))) {
String list = SumResult.format(plan.getBuildings());
bw.write(list);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static Set<String> unlocks(String... unlock) {
return Set.of(unlock);
}

View File

@ -1,5 +1,9 @@
package satisfactory;
import guru.nidi.graphviz.engine.Format;
import guru.nidi.graphviz.engine.Graphviz;
import guru.nidi.graphviz.model.MutableGraph;
import guru.nidi.graphviz.parse.Parser;
import org.jgrapht.Graph;
import org.jgrapht.event.ConnectedComponentTraversalEvent;
import org.jgrapht.event.EdgeTraversalEvent;
@ -14,8 +18,13 @@ import org.jgrapht.traverse.DepthFirstIterator;
import org.jgrapht.traverse.GraphIterator;
import satisfactory.items.Item;
import satisfactory.items.ProductionEdge;
import satisfactory.items.SumResult;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@ -105,4 +114,60 @@ public class Utils {
de.exportGraph(sum, new File(PLOTS + filename + ".dot"));
}
public static void plot(Item target, String name, int amount) {
Graph<Item, DefaultWeightedEdge> screws = target.hierarchy();
DOTExporter<Item, DefaultWeightedEdge> de = new DOTExporter<>(Utils::dotID);
de.setEdgeAttributeProvider(defaultWeightedEdge -> {
Map<String, Attribute> m = new HashMap<>();
m.put("label", DefaultAttribute.createAttribute(screws.getEdgeWeight(defaultWeightedEdge)));
return m;
});
de.exportGraph(screws, new File(PLOTS + name + ".dot"));
System.out.println(name);
Item.production(screws).forEach((item, rate) -> {
System.out.println("\t" + item.getName() + "\t" + rate);
});
}
public static void javaPlot(String name) {
try {
MutableGraph dot = new Parser().read(new File(PLOTS + name + ".dot"));
Graphviz.fromGraph(dot).render(Format.PNG).toFile(new File(PLOTS + name + "_java.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
private static String reflectionFieldName(String name3) {
return Arrays.stream(Database.class.getFields()).filter(field -> {
try {
return field.getType().equals(Item.class) && ((Item) field.get(null)).getName().equals(name3);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}).findFirst().get().getName();
}
public static void list(SumResult plan, String name) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter(LISTS + name + ".txt"))) {
String list = plan.getMap().entrySet().stream().map(item -> item.getKey().getName() + ": " + item.getValue()).reduce("", (s, s2) -> s + "\n" + s2);
bw.write(list);
} catch (IOException e) {
throw new RuntimeException(e);
}
try (BufferedWriter bw = new BufferedWriter(new FileWriter(LISTS + name + "_java.txt"))) {
String list = plan.getMap().entrySet().stream().map(item -> "ref.put(Database." + reflectionFieldName(item.getKey().getName()) + ", " + item.getValue() + ");").reduce("", (s, s2) -> s + "\n" + s2);
bw.write(list);
} catch (IOException e) {
throw new RuntimeException(e);
}
try (BufferedWriter bw = new BufferedWriter(new FileWriter(LISTS + name + "_buildings.txt"))) {
String list = SumResult.format(plan.getBuildings());
bw.write(list);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -18,4 +18,19 @@ public abstract class Building {
public String getName() {
return name;
}
public Map<Item, Integer> getCost() {
return cost;
}
public Map<Item, Integer> getCost(int n) {
Map<Item, Integer> instances = new HashMap<>();
cost.forEach((item, integer) -> instances.put(item, n * integer));
return instances;
}
public Integer getPower() {
return power;
}
}

View File

@ -4,10 +4,7 @@ import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultDirectedWeightedGraph;
import satisfactory.buildings.Building;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
public class SumResult {
private final Graph<Item, ProductionEdge> production;
@ -78,7 +75,7 @@ public class SumResult {
return new SumResult(merge(production, other.getProduction()), map);
}
public Map< Building, Map<Recipe, Double>> getBuildings() {
public Map<Building, Map<Recipe, Double>> getBuildings() {
Map<Building, Map<Recipe, Double>> buildings = new HashMap<>();
for (Item item : production.vertexSet()) {
double n = 0.0;
@ -95,17 +92,37 @@ public class SumResult {
return buildings;
}
public static String format(Map< Building, Map<Recipe, Double>> buildings){
public static String format(Map<Building, Map<Recipe, Double>> buildings) {
StringBuilder sb = new StringBuilder();
for (Map.Entry< Building, Map<Recipe, Double>> entry : buildings.entrySet()) {
int total_sum = 0;
int total_power = 0;
Map<Item, Integer> total_cost = new HashMap<>();
for (Map.Entry<Building, Map<Recipe, Double>> entry : buildings.entrySet()) {
double sum = 0.0;
StringBuilder internal = new StringBuilder();
for (Map.Entry<Recipe, Double> recipes : entry.getValue().entrySet()) {
sum += Math.ceil(recipes.getValue());
internal.append("\t").append(recipes.getKey().formatName()).append("\t").append(recipes.getValue()).append("\n");
}
sb.append(entry.getKey().getName()). append("\t"). append(sum).append("\n").append(internal);
Map<Item, Integer> cost = entry.getKey().getCost((int) sum);
Integer power = entry.getKey().getPower() * (int) sum;
sb.append(entry.getKey().getName()).append("\tx").append((int) sum).append("\t => ").append(formatRequirements(cost, power)).append("\n").append(internal);
total_sum += (int) sum;
cost.forEach((item, integer) -> total_cost.merge(item, integer, Integer::sum));
total_power += power;
}
sb.append("\n=================\nTOTAL\n\n").append(total_sum).append(" buildings, consuming ").append(total_power).append(" MW\n\n");
total_cost.forEach((item, integer) -> sb.append(integer).append("\t").append(item.getName()).append("\n"));
return sb.toString();
}
public static String formatRequirements(Map<Item, Integer> cost, int power) {
StringBuilder sb = new StringBuilder();
sb.append(power).append(" Power; ");
StringJoiner sj = new StringJoiner(", ");
cost.forEach((item, integer) -> sj.add((integer) + " " + item.getName()));
sb.append(sj);
return sb.toString();
}
}

View File

@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test;
import satisfactory.Database;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import static satisfactory.items.TestHelper.test;
class ItemTest {
@ -35,7 +36,7 @@ class ItemTest {
@Test
void productionEncasedIndustrialBeam() {
test(Database.EncasedIndustrialBeam);
test(Database.EncasedIndustrialBeam,"enc_beam");
}
@Test
@ -44,4 +45,10 @@ class ItemTest {
assertEquals(40, productionRate);
}
@Test
void productionUraniumFuelRod(){
//test(Database.UraniumFuelRod, "uranium_fuel_rod");
fail();
}
}

View File

@ -7,6 +7,7 @@ import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static satisfactory.Utils.*;
public class TestHelper {
@ -21,12 +22,25 @@ public class TestHelper {
public static void test(Item item) {
Map<Item, Double> ref = ValidatedValues.get(item);
// calculate
Map<Item, Double> calculations = SumResult.sum(new Production(item, 1)).getMap();
Map<Item, Double> calculations = calculate(item).getMap();
assertMap(ref, calculations);
}
public static void test(Item item, String name) {
name = "test_" + name;
Map<Item, Double> ref = ValidatedValues.get(item);
SumResult calculations = calculate(item);
assertMap(ref, calculations.getMap());
plot2(calculations.getProduction(), name);
javaPlot(name);
list(calculations, name);
}
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) {
Map<K, Double> ref = new HashMap<>();
for (Map<K, Double> singleRef : single_refs) {

View File

@ -13,6 +13,7 @@ public class ValidatedValues {
values.put(Database.AdaptiveControlUnit, ACU());
values.put(Database.ModularEngine, ME());
values.put(Database.VersatileFrameWork, VF());
values.put(Database.UraniumFuelRod, UFR());
{
Item item = Database.Screw;
Map<Item, Double> ref = new HashMap<>();
@ -160,4 +161,34 @@ public class ValidatedValues {
return ref;
}
private static Map<Item, Double> UFR(){
// references, validated
Map<Item, Double> ref = new HashMap<>();
ref.put(Database.Limestone ,135.);
ref.put(Database.Uranium ,100.);
ref.put(Database.Quickwire ,100.);
ref.put(Database.SteelIngot ,81.75);
ref.put(Database.IronOre ,81.75);
ref.put(Database.Coal ,81.75);
ref.put(Database.SulfuricAcid ,80.);
ref.put(Database.CopperIngot ,80.);
ref.put(Database.CopperOre ,80.);
ref.put(Database.Wire ,60.);
ref.put(Database.CateriumOre ,60.);
//ref.put(Database.Sulfur ,60.);
//ref.put(Database.Water ,60.);
ref.put(Database.EncasedUraniumCell ,50.);
ref.put(Database.Concrete ,45.);
ref.put(Database.CopperSheet ,25.);
ref.put(Database.SteelPipe ,22.5);
ref.put(Database.CateriumIngot ,20.);
ref.put(Database.SteelBeam ,12.);
ref.put(Database.Stator ,7.5);
ref.put(Database.ElectromagneticControlRod ,5.);
ref.put(Database.AILimiter ,5.);
ref.put(Database.EncasedIndustrialBeam ,3.);
ref.put(Database.UraniumFuelRod ,1.);
return ref;
}
}