calculate necessary production amounts, add buildings base

master
agp8x 2021-05-10 01:00:51 +02:00
parent 0d95b9b25a
commit 4ffc73e56d
19 changed files with 162 additions and 11 deletions

View File

@ -1,10 +1,7 @@
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializationFeature;
import items.Database; import items.*;
import items.Item;
import items.Recipe;
import items.Utils;
import org.jgrapht.Graph; import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultWeightedEdge; import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.EdgeReversedGraph; import org.jgrapht.graph.EdgeReversedGraph;
@ -66,12 +63,22 @@ public class Test {
System.out.println("\nSUM_reif"); System.out.println("\nSUM_reif");
Database.ReinforcedIronPlate.getRecipe().sum(Database.ReinforcedIronPlate, 100); Database.ReinforcedIronPlate.getRecipe().sum(Database.ReinforcedIronPlate, 100);
System.out.println("\nSUM_screw"); System.out.println("\nSUM_screw");
Database.Screw.getRecipe().sum(Database.Screw, 100); plot2(Database.Screw.getRecipe().sum(Database.Screw, 100), "screw_sum");
System.out.println("\nSUM_ACU"); System.out.println("\nSUM_ACU");
Database.AdaptiveControlUnit.getRecipe().sum(Database.AdaptiveControlUnit, 100); plot2(Database.AdaptiveControlUnit.getRecipe().sum(Database.AdaptiveControlUnit, 1), "acu4");
} }
private static void plot2(Graph<Item, ProductionEdge> sum, String filename) {
DOTExporter<Item,ProductionEdge> de = new DOTExporter<>(Item::ID);
de.setEdgeAttributeProvider(productionEdge -> {
Map<String, Attribute> m = new HashMap<>();
m.put("label", DefaultAttribute.createAttribute(productionEdge.label()));
return m;
});
de.exportGraph(sum, new File(filename+".dot"));
}
private static void plot(Item target, String name, int amount, DOTExporter<Item, DefaultWeightedEdge> de) { private static void plot(Item target, String name, int amount, DOTExporter<Item, DefaultWeightedEdge> de) {
Graph<Item, DefaultWeightedEdge> screws = target.productionHierarchy(amount); Graph<Item, DefaultWeightedEdge> screws = target.productionHierarchy(amount);
de.exportGraph(screws, new File(name + ".dot")); de.exportGraph(screws, new File(name + ".dot"));

View File

@ -0,0 +1,4 @@
package buildings;
public abstract class Building {
}

View File

@ -0,0 +1,6 @@
package buildings.production;
import buildings.Building;
public class Assembler extends Building {
}

View File

@ -0,0 +1,6 @@
package buildings.production;
import buildings.Building;
public class Constructor extends Building {
}

View File

@ -0,0 +1,6 @@
package buildings.production;
import buildings.Building;
public class CraftBench extends Building {
}

View File

@ -0,0 +1,6 @@
package buildings.production;
import buildings.Building;
public class EquipmentWorkshop extends Building {
}

View File

@ -0,0 +1,6 @@
package buildings.production;
import buildings.Building;
public class Foundry extends Building {
}

View File

@ -0,0 +1,6 @@
package buildings.production;
import buildings.Building;
public class Manufacturer extends Building {
}

View File

@ -0,0 +1,6 @@
package buildings.production;
import buildings.Building;
public class Miner extends Building {
}

View File

@ -0,0 +1,6 @@
package buildings.production;
import buildings.Building;
public class OilExtractor extends Building {
}

View File

@ -0,0 +1,6 @@
package buildings.production;
import buildings.Building;
public class Packager extends Building {
}

View File

@ -0,0 +1,6 @@
package buildings.production;
import buildings.Building;
public class Refinery extends Building {
}

View File

@ -0,0 +1,6 @@
package buildings.production;
import buildings.Building;
public class Smelter extends Building {
}

View File

@ -0,0 +1,6 @@
package buildings.production;
import buildings.Building;
public class WaterExtractor extends Building {
}

View File

@ -308,7 +308,7 @@ public class Database {
recipe.addInput(CircuitBoard, 10); recipe.addInput(CircuitBoard, 10);
recipe.addInput(HeavyModularFrame, 2); recipe.addInput(HeavyModularFrame, 2);
recipe.addInput(Computer, 2); recipe.addInput(Computer, 2);
AdaptiveControlUnit.add(recipe); AdaptiveControlUnit.add(recipe, 2);
} }
{ {
// Nobelisk // Nobelisk

View File

@ -118,4 +118,8 @@ public abstract class Item {
public Graph<Item, DefaultWeightedEdge> hierarchy(){ public Graph<Item, DefaultWeightedEdge> hierarchy(){
return getRecipe().buildGraph(this); return getRecipe().buildGraph(this);
} }
public String ID(){
return getName().replace(" ","");
}
} }

View File

@ -0,0 +1,41 @@
package items;
import java.util.Objects;
public class ProductionEdge {
private Item source;
private double totalRequired;
private double instances;
public ProductionEdge(Item source,double totalRequired, double productionRate) {
this.source=source;
this.totalRequired = totalRequired;
this.instances = productionRate;
}
public String label(){
//return "(" + totalRequired + "||" + instances + ")";
return "(%.2f||%.2f)".formatted(totalRequired,instances);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ProductionEdge that = (ProductionEdge) o;
return Double.compare(that.totalRequired, totalRequired) == 0 && instances == that.instances && Objects.equals(source, that.source);
}
@Override
public int hashCode() {
return Objects.hash(source, totalRequired, instances);
}
@Override
public String toString() {
return "ProductionEdge{" +
"totalRequired=" + totalRequired +
", instances=" + instances +
'}';
}
}

View File

@ -97,7 +97,7 @@ public class Recipe {
public float getProductionRate(Item item) { public float getProductionRate(Item item) {
float production = outputs.get(item); float production = outputs.get(item);
return production / duration; return (float) (production / (duration / 60.0));
} }
public Map<Item, Float> getRequirementRates(Item item) { public Map<Item, Float> getRequirementRates(Item item) {
@ -177,12 +177,21 @@ public class Recipe {
return graph; return graph;
} }
public Map<Item, Double> sum(Item target, int prodPerMinute) {
private double processesNeeded(Item target, double n) {
Recipe r = target.getRecipe();
return n / r.getProductionRate(target);
}
public Graph<Item, ProductionEdge> sum(Item target, int prodPerMinute) {
Graph<Item, DefaultWeightedEdge> buildGraph = buildGraph(target); Graph<Item, DefaultWeightedEdge> buildGraph = buildGraph(target);
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, (double) prodPerMinute);
production.addVertex(target);
production.addEdge(target, target, new ProductionEdge(target, prodPerMinute, processesNeeded(target, prodPerMinute)));
while (!queue.isEmpty()) { while (!queue.isEmpty()) {
Item item = queue.remove(); Item item = queue.remove();
// next items // next items
@ -204,6 +213,10 @@ public class Recipe {
double requiredProcesRuns = productWantedPerMinute / productPerProcess; double requiredProcesRuns = productWantedPerMinute / productPerProcess;
double requiredInput = amountNeeded * requiredProcesRuns; double requiredInput = amountNeeded * requiredProcesRuns;
sum += requiredInput; sum += requiredInput;
production.addVertex(item);
production.addEdge(item, product, new ProductionEdge(item, requiredInput, processesNeeded(item, requiredInput)));
} }
if (!map.containsKey(item) && sum > 0) { if (!map.containsKey(item) && sum > 0) {
map.put(item, sum); map.put(item, sum);
@ -212,6 +225,6 @@ public class Recipe {
map.forEach((item, aDouble) -> { map.forEach((item, aDouble) -> {
System.out.println(item.getName() + ": " + aDouble); System.out.println(item.getName() + ": " + aDouble);
}); });
return map; return production;
} }
} }

View File

@ -5,6 +5,7 @@ import org.junit.jupiter.api.Test;
import java.util.Map; import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
class ItemTest { class ItemTest {
@ -19,11 +20,14 @@ class ItemTest {
@Test @Test
void productionScrews2() { void productionScrews2() {
Map<Item, Double> production = Database.Screw.getRecipe().sum(Database.Screw, 100); /*Map<Item, Double> production = Database.Screw.getRecipe().sum(Database.Screw, 100);
assertEquals(100, production.get(Database.Screw), "Screws (output)"); assertEquals(100, production.get(Database.Screw), "Screws (output)");
assertEquals(25, production.get(Database.IronRod), "IronRod"); assertEquals(25, production.get(Database.IronRod), "IronRod");
assertEquals(25, production.get(Database.IronIngot), "IronIngot"); assertEquals(25, production.get(Database.IronIngot), "IronIngot");
assertEquals(25, production.get(Database.IronOre), "IronOre"); assertEquals(25, production.get(Database.IronOre), "IronOre");
*/
fail("TODO: migrate");
} }
@Test @Test
@ -36,4 +40,10 @@ class ItemTest {
assertEquals(1200, production.get(Database.IronOre), "IronOre"); assertEquals(1200, production.get(Database.IronOre), "IronOre");
assertEquals(600, production.get(Database.IronPlate), "IronPlate"); assertEquals(600, production.get(Database.IronPlate), "IronPlate");
} }
@Test
void testScrewProd(){
float productionRate = Database.Screw.getRecipe().getProductionRate(Database.Screw);
assertEquals(40, productionRate);
}
} }