diff --git a/src/main/satisfactory/Database.java b/src/main/satisfactory/Database.java index a114186..309a90d 100644 --- a/src/main/satisfactory/Database.java +++ b/src/main/satisfactory/Database.java @@ -7,396 +7,397 @@ import satisfactory.items.type.*; import java.util.*; public class Database { - // dirty! private static final Collection items = new HashSet<>(); public static final Map preferences = new HashMap<>(); - // Items & recipes - public static final Item IronOre = new Ore("Iron Ore"); - public static final Item IronIngot = new Ingot("Iron Ingot", new Recipe(2, IronOre, 1)); - public static final Item CopperOre = new Ore("Copper Ore"); - public static final Item CopperIngot = new Ingot("Copper Ingot", new Recipe(2, CopperOre, 1)); - public static final Item Coal = new Ore("Coal"); - public static final Item SteelIngot = new Ingot("Steel Ingot"); - public static final Item CateriumOre = new Ore("Caterium Ore"); - public static final Item CateriumIngot = new Ingot("Caterium Ingot", new Recipe(4, CateriumOre, 3)); - public static final Item IronPlate = new Part("Iron Plate"); - public static final Item IronRod = new Part("IronRod", new Recipe(4, IronIngot, 1)); - public static final Item Screw = new Part("Screw"); - public static final Item ReinforcedIronPlate = new Part("Reinforced Iron Plate"); - public static final Item ModularFrame = new Part("Modular Frame"); - public static final Item SteelBeam = new Part("Steel Beam", new Recipe(4, SteelIngot, 4)); - public static final Item SteelPipe = new Part("Steel Pipe"); - public static final Item Limestone = new Ore("Limestone"); - public static final Item Concrete = new Part("Concrete", new Recipe(4, Limestone, 3)); - public static final Item EncasedIndustrialBeam = new Part("Encased Industrial Beam"); - public static final Item HeavyModularFrame = new Part("HeavyModularFrame"); - public static final Item CopperSheet = new Part("CopperSheet", new Recipe(6, CopperIngot, 2)); - public static final Item Wire = new Part("Wire"); - public static final Item Cable = new Part("Cable", new Recipe(2, Wire, 2)); - public static final Item Quickwire = new Part("Quickwire"); - public static final Item CircuitBoard = new Part("CircuitBoard"); - public static final Item AILimiter = new Part("A.I. Limiter"); - public static final Item HighSpeedConnector = new Part("High-Speed Connector"); - public static final Item Biomass = new Part("Biomass"); - public static final Item SolidBiofuel = new Part("Solid Biofuel"); - public static final Item Mycelia = new Pickup("Mycelia"); - public static final Item Leaves = new Pickup("Leaves"); - public static final Item Wood = new Pickup("Wood"); - public static final Item AlienCarapace = new Pickup("Alien Carapace"); - public static final Item AlienOrgans = new Pickup("Alien Organs"); - public static final Item Fabric = new Part("Fabric"); - public static final Item Rotor = new Part("Rotor"); - public static final Item Stator = new Part("Stator"); - public static final Item Motor = new Part("Motor"); - public static final Item GreenPowerSlug = new Pickup("Green Power Slug"); - public static final Item YellowPowerSlug = new Pickup("Yellow Power Slug"); - public static final Item PurplePowerSlug = new Pickup("Purple Power Slug"); - public static final Item PowerShard = new Pickup("PowerShard"); - public static final Item Sulfur = new Ore("Sulfur"); - public static final Item BlackPowder = new Part("Black powder"); - public static final Item SpikedRebar = new Part("SpikedRebar", new Recipe(4, IronRod, 1)); - public static final Item FlowerPetals = new Pickup("Flower Petals"); - public static final Item ColorCatridge = new Part("Color Catridge"); - public static final Item Beacon = new Tool("Beacon"); - public static final Item Rubber = new Part("Rubber"); - public static final Item RifleCatridge = new Part("RifleCatridge"); - public static final Item GasFilter = new Tool("Gas Filter"); - public static final Item Plastic = new Part("Plastic"); - public static final Item Computer = new Part("Computer"); - public static final Item SuperComputer = new Part("SuperComputer"); - public static final Item EmptyCanister = new Part("Empty Canister"); - public static final Item ModularEngine = new Part("Modular Engine"); - public static final Item AdaptiveControlUnit = new Part("Adaptive Control Unit"); - public static final Item SmartPlating = new Part("Smart Plating"); - public static final Item AutomatedWiring = new Part("Automated Wiring"); - public static final Item VersatileFrameWork = new Part("Versatile Framework"); - public static final Item Nobelisk = new Part("Nobelisk"); - public static final Item Water = new RawFluid("Water"); - public static final Item CrudeOil = new RawFluid("Crude Oil"); - public static final Item HeavyOilResidue = new ProcessedFluid("Heavy Oil Residue"); - public static final Item Fuel = new ProcessedFluid("Fuel"); - public static final Item LiquidBiofuel = new ProcessedFluid("Liquid Biofuel"); - public static final Item PetroleumCoke = new Part("Petroleum Coke"); - public static final Item PolymerResin = new Part("Polymer Resin"); + // Items & recipes + public static final Item IronOre = new Ore("Iron Ore"); + public static final Item IronIngot = new Ingot("Iron Ingot", new Recipe(2, IronOre, 1)); + public static final Item CopperOre = new Ore("Copper Ore"); + public static final Item CopperIngot = new Ingot("Copper Ingot", new Recipe(2, CopperOre, 1)); + public static final Item Coal = new Ore("Coal"); + public static final Item SteelIngot = new Ingot("Steel Ingot"); + public static final Item CateriumOre = new Ore("Caterium Ore"); + public static final Item CateriumIngot = new Ingot("Caterium Ingot", new Recipe(4, CateriumOre, 3)); + public static final Item IronPlate = new Part("Iron Plate"); + public static final Item IronRod = new Part("Iron Rod", new Recipe(4, IronIngot, 1)); + public static final Item Screw = new Part("Screw"); + public static final Item ReinforcedIronPlate = new Part("Reinforced Iron Plate"); + public static final Item ModularFrame = new Part("Modular Frame"); + public static final Item SteelBeam = new Part("Steel Beam", new Recipe(4, SteelIngot, 4)); + public static final Item SteelPipe = new Part("Steel Pipe"); + public static final Item Limestone = new Ore("Limestone"); + public static final Item Concrete = new Part("Concrete", new Recipe(4, Limestone, 3)); + public static final Item EncasedIndustrialBeam = new Part("Encased Industrial Beam"); + public static final Item HeavyModularFrame = new Part("Heavy Modular Frame"); + public static final Item CopperSheet = new Part("Copper Sheet", new Recipe(6, CopperIngot, 2)); + public static final Item Wire = new Part("Wire"); + public static final Item Cable = new Part("Cable", new Recipe(2, Wire, 2)); + public static final Item Quickwire = new Part("Quickwire"); + public static final Item CircuitBoard = new Part("Circuit Board"); + public static final Item AILimiter = new Part("A.I. Limiter"); + public static final Item HighSpeedConnector = new Part("High-Speed Connector"); + public static final Item Biomass = new Part("Biomass"); + public static final Item SolidBiofuel = new Part("Solid Biofuel"); + public static final Item Mycelia = new Pickup("Mycelia"); + public static final Item Leaves = new Pickup("Leaves"); + public static final Item Wood = new Pickup("Wood"); + public static final Item AlienCarapace = new Pickup("Alien Carapace"); + public static final Item AlienOrgans = new Pickup("Alien Organs"); + public static final Item Fabric = new Part("Fabric"); + public static final Item Rotor = new Part("Rotor"); + public static final Item Stator = new Part("Stator"); + public static final Item Motor = new Part("Motor"); + public static final Item GreenPowerSlug = new Pickup("Green Power Slug"); + public static final Item YellowPowerSlug = new Pickup("Yellow Power Slug"); + public static final Item PurplePowerSlug = new Pickup("Purple Power Slug"); + public static final Item PowerShard = new Pickup("PowerShard"); + public static final Item Sulfur = new Ore("Sulfur"); + public static final Item BlackPowder = new Part("Black powder"); + public static final Item SpikedRebar = new Part("Spiked Rebar", new Recipe(4, IronRod, 1)); + public static final Item FlowerPetals = new Pickup("Flower Petals"); + public static final Item ColorCatridge = new Part("Color Catridge"); + public static final Item Beacon = new Tool("Beacon"); + public static final Item Rubber = new Part("Rubber"); + public static final Item RifleCatridge = new Part("Rifle Catridge"); + public static final Item GasFilter = new Tool("Gas Filter"); + public static final Item Plastic = new Part("Plastic"); + public static final Item Computer = new Part("Computer"); + public static final Item SuperComputer = new Part("Super Computer"); + public static final Item EmptyCanister = new Part("Empty Canister"); + public static final Item ModularEngine = new Part("Modular Engine"); + public static final Item AdaptiveControlUnit = new Part("Adaptive Control Unit"); + public static final Item SmartPlating = new Part("Smart Plating"); + public static final Item AutomatedWiring = new Part("Automated Wiring"); + public static final Item VersatileFrameWork = new Part("Versatile Framework"); + public static final Item Nobelisk = new Part("Nobelisk"); + public static final Item Water = new RawFluid("Water"); + public static final Item CrudeOil = new RawFluid("Crude Oil"); + public static final Item HeavyOilResidue = new ProcessedFluid("Heavy Oil Residue"); + public static final Item Fuel = new ProcessedFluid("Fuel"); + public static final Item LiquidBiofuel = new ProcessedFluid("Liquid Biofuel"); + public static final Item PetroleumCoke = new Part("Petroleum Coke"); + public static final Item PolymerResin = new Part("Polymer Resin"); - static { - { - Set ores = new HashSet<>(Arrays.asList(IronOre, Coal, Limestone, CopperOre, CateriumOre, Sulfur)); - for (Item ore : ores) { - Recipe mk1 = new Recipe(1, "Miner MK 1", false); - ore.add(mk1, 1); - Recipe mk2 = new Recipe(1, "Miner MK2", false); - ore.add(mk2, 2); - } + static { + { + Set ores = new HashSet<>(Arrays.asList(IronOre, Coal, Limestone, CopperOre, CateriumOre, Sulfur)); + for (Item ore : ores) { + Recipe mk1 = new Recipe(1, "Miner MK 1", false); + ore.add(mk1, 1); + Recipe mk2 = new Recipe(1, "Miner MK2", false); + ore.add(mk2, 2); + ore.setPreference(mk2); + } - Set rawFluids = new HashSet<>(Arrays.asList(CrudeOil, Water)); - // no common well yet - CrudeOil.add(new Recipe(1, "Oil extracting thingy", false), 2); - Water.add(new Recipe(1, "water pump thingy", false), 2); - } - { - // Steel Ingot - Recipe recipe = new Recipe(4); - recipe.addInput(IronOre, 3); - recipe.addInput(Coal, 3); - SteelIngot.add(recipe, 3); - } - { - // Iron Plate - Recipe recipe = new Recipe(6, IronIngot, 3); - IronPlate.add(recipe, 2); - } - { - // Screw - Screw.add(new Recipe(6, IronRod, 1), 4); - } - { - // Reinforced Iron Plate - Recipe recipe = new Recipe(12); - recipe.addInput(IronPlate, 6); - recipe.addInput(Screw, 12); - ReinforcedIronPlate.add(recipe); - Recipe bolted = new Recipe(12, "Bolted Iron Plate", false); - bolted.addInput(IronPlate, 18); - bolted.addInput(Screw, 50); - ReinforcedIronPlate.add(bolted, 3); + Set rawFluids = new HashSet<>(Arrays.asList(CrudeOil, Water)); + // no common well yet + CrudeOil.add(new Recipe(1, "Oil extracting thingy", false), 2); + Water.add(new Recipe(1, "water pump thingy", false), 2); + } + { + // Steel Ingot + Recipe recipe = new Recipe(4); + recipe.addInput(IronOre, 3); + recipe.addInput(Coal, 3); + SteelIngot.add(recipe, 3); + } + { + // Iron Plate + Recipe recipe = new Recipe(6, IronIngot, 3); + IronPlate.add(recipe, 2); + } + { + // Screw + Screw.add(new Recipe(6, IronRod, 1), 4); + } + { + // Reinforced Iron Plate + Recipe recipe = new Recipe(12); + recipe.addInput(IronPlate, 6); + recipe.addInput(Screw, 12); + ReinforcedIronPlate.add(recipe); + Recipe bolted = new Recipe(12, "Bolted Iron Plate", false); + bolted.addInput(IronPlate, 18); + bolted.addInput(Screw, 50); + ReinforcedIronPlate.add(bolted, 3); - ReinforcedIronPlate.setPreference(recipe); - } - { - // Modular Frame - Recipe recipe = new Recipe(60); - recipe.addInput(ReinforcedIronPlate, 3); - recipe.addInput(IronRod, 12); - ModularFrame.add(recipe, 2); - } - { - // Steel Pipe - Recipe recipe = new Recipe(6); - recipe.addInput(SteelIngot, 3); - SteelPipe.add(recipe, 2); - } - { - // Encased Industrial Beam - Recipe recipe = new Recipe(10); - recipe.addInput(SteelBeam, 4); - recipe.addInput(Concrete, 5); - EncasedIndustrialBeam.add(recipe); - } - { - // Heavy Modular Frame - Recipe recipe = new Recipe(30); - recipe.addInput(ModularFrame, 5); - recipe.addInput(SteelPipe, 15); - recipe.addInput(EncasedIndustrialBeam, 5); - recipe.addInput(Screw, 100); - HeavyModularFrame.add(recipe); - } - { - // Wire - Wire.add(new Recipe(4, CopperIngot, 1), 2); - } - { - // Quickwire - Quickwire.add(new Recipe(5, CateriumIngot, 1), 5); - } - { - // Circuit Board - Recipe recipe = new Recipe(8); - recipe.addInput(CopperSheet, 2); - recipe.addInput(Plastic, 4); - CircuitBoard.add(recipe); - } - { - // A.I. Limiter - Recipe recipe = new Recipe(12); - recipe.addInput(CopperSheet, 5); - recipe.addInput(Quickwire, 20); - AILimiter.add(recipe); - } - { - // High Speed Connector - Recipe recipe = new Recipe(16); - recipe.addInput(Quickwire, 56); - recipe.addInput(Cable, 10); - recipe.addInput(CircuitBoard, 1); - HighSpeedConnector.add(recipe); - } - { - // Biomass - Biomass.add(new Recipe(5, Leaves, 10), 5); - Biomass.add(new Recipe(4, Wood, 4), 20); - Biomass.add(new Recipe(4, Mycelia, 10), 10); - Biomass.add(new Recipe(4, AlienCarapace, 1), 100); - Biomass.add(new Recipe(8, AlienOrgans, 1), 200); - } - { - // Fabric - Recipe recipe = new Recipe(4); - recipe.addInput(Mycelia); - recipe.addInput(Biomass, 5); - Fabric.add(recipe); - } - { - // Solid Biofuel - SolidBiofuel.add(new Recipe(4, Biomass, 8), 4); - } - { - // Rotator - Recipe recipe = new Recipe(15); - recipe.addInput(IronRod, 5); - recipe.addInput(Screw, 25); - Rotor.add(recipe); - } - { - // Stator - Recipe recipe = new Recipe(12); - recipe.addInput(SteelPipe, 3); - recipe.addInput(Wire, 8); - Stator.add(recipe); - } - { - // Motor - Recipe recipe = new Recipe(12); - recipe.addInput(Rotor, 2); - recipe.addInput(Stator, 2); - Motor.add(recipe); - } - { - // Power Shard - PowerShard.add(new Recipe(8, GreenPowerSlug, 1)); - PowerShard.add(new Recipe(12, YellowPowerSlug, 1), 2); - PowerShard.add(new Recipe(24, PurplePowerSlug, 1), 5); - } - { - // Black Powder - Recipe recipe = new Recipe(8); - recipe.addInput(Coal); - recipe.addInput(Sulfur, 2); - BlackPowder.add(recipe); - } - { - // Color Catridge - ColorCatridge.add(new Recipe(8, FlowerPetals, 5), 10); - } - { - // Rifle Catridge - Recipe recipe = new Recipe(20); - recipe.addInput(Beacon, 1); - recipe.addInput(SteelPipe, 10); - recipe.addInput(BlackPowder, 10); - recipe.addInput(Rubber, 10); - RifleCatridge.add(recipe, 5); - } - { - // Gas Filter - Recipe recipe = new Recipe(8); - recipe.addInput(Coal, 5); - recipe.addInput(Rubber, 2); - recipe.addInput(Fabric, 2); - GasFilter.add(recipe); - } - { - // Computer - Recipe recipe = new Recipe(24); - recipe.addInput(CircuitBoard, 10); - recipe.addInput(Cable, 9); - recipe.addInput(Plastic, 18); - recipe.addInput(Screw, 52); - Computer.add(recipe); - Recipe alternative = new Recipe(16, "Caterium Computer", false); - alternative.addInput(CircuitBoard, 7); - alternative.addInput(Quickwire, 28); - alternative.addInput(Rubber, 12); - Computer.add(alternative); + ReinforcedIronPlate.setPreference(recipe); + } + { + // Modular Frame + Recipe recipe = new Recipe(60); + recipe.addInput(ReinforcedIronPlate, 3); + recipe.addInput(IronRod, 12); + ModularFrame.add(recipe, 2); + } + { + // Steel Pipe + Recipe recipe = new Recipe(6); + recipe.addInput(SteelIngot, 3); + SteelPipe.add(recipe, 2); + } + { + // Encased Industrial Beam + Recipe recipe = new Recipe(10); + recipe.addInput(SteelBeam, 4); + recipe.addInput(Concrete, 5); + EncasedIndustrialBeam.add(recipe); + } + { + // Heavy Modular Frame + Recipe recipe = new Recipe(30); + recipe.addInput(ModularFrame, 5); + recipe.addInput(SteelPipe, 15); + recipe.addInput(EncasedIndustrialBeam, 5); + recipe.addInput(Screw, 100); + HeavyModularFrame.add(recipe); + } + { + // Wire + Wire.add(new Recipe(4, CopperIngot, 1), 2); + } + { + // Quickwire + Quickwire.add(new Recipe(5, CateriumIngot, 1), 5); + } + { + // Circuit Board + Recipe recipe = new Recipe(8); + recipe.addInput(CopperSheet, 2); + recipe.addInput(Plastic, 4); + CircuitBoard.add(recipe); + // TODO: alternative + } + { + // A.I. Limiter + Recipe recipe = new Recipe(12); + recipe.addInput(CopperSheet, 5); + recipe.addInput(Quickwire, 20); + AILimiter.add(recipe); + } + { + // High Speed Connector + Recipe recipe = new Recipe(16); + recipe.addInput(Quickwire, 56); + recipe.addInput(Cable, 10); + recipe.addInput(CircuitBoard, 1); + HighSpeedConnector.add(recipe); + } + { + // Biomass + Biomass.add(new Recipe(5, Leaves, 10), 5); + Biomass.add(new Recipe(4, Wood, 4), 20); + Biomass.add(new Recipe(4, Mycelia, 10), 10); + Biomass.add(new Recipe(4, AlienCarapace, 1), 100); + Biomass.add(new Recipe(8, AlienOrgans, 1), 200); + } + { + // Fabric + Recipe recipe = new Recipe(4); + recipe.addInput(Mycelia); + recipe.addInput(Biomass, 5); + Fabric.add(recipe); + } + { + // Solid Biofuel + SolidBiofuel.add(new Recipe(4, Biomass, 8), 4); + } + { + // Rotator + Recipe recipe = new Recipe(15); + recipe.addInput(IronRod, 5); + recipe.addInput(Screw, 25); + Rotor.add(recipe); + } + { + // Stator + Recipe recipe = new Recipe(12); + recipe.addInput(SteelPipe, 3); + recipe.addInput(Wire, 8); + Stator.add(recipe); + } + { + // Motor + Recipe recipe = new Recipe(12); + recipe.addInput(Rotor, 2); + recipe.addInput(Stator, 2); + Motor.add(recipe); + } + { + // Power Shard + PowerShard.add(new Recipe(8, GreenPowerSlug, 1)); + PowerShard.add(new Recipe(12, YellowPowerSlug, 1), 2); + PowerShard.add(new Recipe(24, PurplePowerSlug, 1), 5); + } + { + // Black Powder + Recipe recipe = new Recipe(8); + recipe.addInput(Coal); + recipe.addInput(Sulfur, 2); + BlackPowder.add(recipe); + } + { + // Color Catridge + ColorCatridge.add(new Recipe(8, FlowerPetals, 5), 10); + } + { + // Rifle Catridge + Recipe recipe = new Recipe(20); + recipe.addInput(Beacon, 1); + recipe.addInput(SteelPipe, 10); + recipe.addInput(BlackPowder, 10); + recipe.addInput(Rubber, 10); + RifleCatridge.add(recipe, 5); + } + { + // Gas Filter + Recipe recipe = new Recipe(8); + recipe.addInput(Coal, 5); + recipe.addInput(Rubber, 2); + recipe.addInput(Fabric, 2); + GasFilter.add(recipe); + } + { + // Computer + Recipe recipe = new Recipe(24); + recipe.addInput(CircuitBoard, 10); + recipe.addInput(Cable, 9); + recipe.addInput(Plastic, 18); + recipe.addInput(Screw, 52); + Computer.add(recipe); + Recipe alternative = new Recipe(16, "Caterium Computer", false); + alternative.addInput(CircuitBoard, 7); + alternative.addInput(Quickwire, 28); + alternative.addInput(Rubber, 12); + Computer.add(alternative); - Computer.setPreference(recipe); - } - { - // Super Computer - Recipe recipe = new Recipe(32); - recipe.addInput(Computer, 2); - recipe.addInput(AILimiter, 2); - recipe.addInput(HighSpeedConnector, 3); - recipe.addInput(Plastic, 28); - SuperComputer.add(recipe); - } - { - // Empty Canister - EmptyCanister.add(new Recipe(4, Plastic, 2), 4); - } - { - // Beacon - Recipe recipe = new Recipe(8); - recipe.addInput(IronPlate, 3); - recipe.addInput(IronRod); - recipe.addInput(Wire, 15); - recipe.addInput(Cable, 2); - Beacon.add(recipe); - } - { - // Modular Engine - Recipe recipe = new Recipe(60, false); - recipe.addInput(Motor, 2); - recipe.addInput(Rubber, 15); - recipe.addInput(SmartPlating, 2); - ModularEngine.add(recipe); - } - { - // Adaptive Control Unit - Recipe recipe = new Recipe(120, false); - recipe.addInput(AutomatedWiring, 15); - recipe.addInput(CircuitBoard, 10); - recipe.addInput(HeavyModularFrame, 2); - recipe.addInput(Computer, 2); - AdaptiveControlUnit.add(recipe, 2); - } - { - // Nobelisk - Recipe recipe = new Recipe(20, false); - recipe.addInput(BlackPowder, 5); - recipe.addInput(SteelPipe, 10); - Nobelisk.add(recipe); - } - { - // Smart Plating - Recipe recipe = new Recipe(30, false); - recipe.addInput(ReinforcedIronPlate); - recipe.addInput(Rotor); - SmartPlating.add(recipe); - } - { - // Automated Wiring - Recipe recipe = new Recipe(24, false); - recipe.addInput(Stator); - recipe.addInput(Cable, 20); - AutomatedWiring.add(recipe); - } - { - // Versatile Framework - Recipe recipe = new Recipe(24, false); - recipe.addInput(ModularFrame); - recipe.addInput(SteelBeam, 12); - VersatileFrameWork.add(recipe, 2); - } - { - // Fuel - Recipe residualFuel = new Recipe(6, "Residual Fuel", false); - residualFuel.addInput(HeavyOilResidue, 6); - Fuel.add(residualFuel, 4); - Recipe recipe = new Recipe(6, false); - recipe.addInput(CrudeOil, 6); - recipe.addOutput(PolymerResin, 3); - Fuel.add(recipe, 4); + Computer.setPreference(recipe); + } + { + // Super Computer + Recipe recipe = new Recipe(32); + recipe.addInput(Computer, 2); + recipe.addInput(AILimiter, 2); + recipe.addInput(HighSpeedConnector, 3); + recipe.addInput(Plastic, 28); + SuperComputer.add(recipe); + } + { + // Empty Canister + EmptyCanister.add(new Recipe(4, Plastic, 2), 4); + } + { + // Beacon + Recipe recipe = new Recipe(8); + recipe.addInput(IronPlate, 3); + recipe.addInput(IronRod); + recipe.addInput(Wire, 15); + recipe.addInput(Cable, 2); + Beacon.add(recipe); + } + { + // Modular Engine + Recipe recipe = new Recipe(60, false); + recipe.addInput(Motor, 2); + recipe.addInput(Rubber, 15); + recipe.addInput(SmartPlating, 2); + ModularEngine.add(recipe); + } + { + // Adaptive Control Unit + Recipe recipe = new Recipe(120, false); + recipe.addInput(AutomatedWiring, 15); + recipe.addInput(CircuitBoard, 10); + recipe.addInput(HeavyModularFrame, 2); + recipe.addInput(Computer, 2); + AdaptiveControlUnit.add(recipe, 2); + } + { + // Nobelisk + Recipe recipe = new Recipe(20, false); + recipe.addInput(BlackPowder, 5); + recipe.addInput(SteelPipe, 10); + Nobelisk.add(recipe); + } + { + // Smart Plating + Recipe recipe = new Recipe(30, false); + recipe.addInput(ReinforcedIronPlate); + recipe.addInput(Rotor); + SmartPlating.add(recipe); + } + { + // Automated Wiring + Recipe recipe = new Recipe(24, false); + recipe.addInput(Stator); + recipe.addInput(Cable, 20); + AutomatedWiring.add(recipe); + } + { + // Versatile Framework + Recipe recipe = new Recipe(24, false); + recipe.addInput(ModularFrame); + recipe.addInput(SteelBeam, 12); + VersatileFrameWork.add(recipe, 2); + } + { + // Fuel + Recipe residualFuel = new Recipe(6, "Residual Fuel", false); + residualFuel.addInput(HeavyOilResidue, 6); + Fuel.add(residualFuel, 4); + Recipe recipe = new Recipe(6, false); + recipe.addInput(CrudeOil, 6); + recipe.addOutput(PolymerResin, 3); + Fuel.add(recipe, 4); - Fuel.setPreference(recipe); - } - { - // Liquid Biofuel - Recipe recipe = new Recipe(4, false); - recipe.addInput(SolidBiofuel, 6); - recipe.addInput(Water, 3); - LiquidBiofuel.add(recipe, 4); - } - { - // Plastic - Recipe recipe = new Recipe(6, false); - recipe.addInput(CrudeOil, 3); - recipe.addOutput(HeavyOilResidue, 1); - Plastic.add(recipe, 2); - Recipe residualPlastic = new Recipe(6, "Residual Plastic", false); - residualPlastic.addInput(PolymerResin, 6); - residualPlastic.addInput(Water, 2); - Plastic.add(residualPlastic, 2); + Fuel.setPreference(recipe); + } + { + // Liquid Biofuel + Recipe recipe = new Recipe(4, false); + recipe.addInput(SolidBiofuel, 6); + recipe.addInput(Water, 3); + LiquidBiofuel.add(recipe, 4); + } + { + // Plastic + Recipe recipe = new Recipe(6, false); + recipe.addInput(CrudeOil, 3); + recipe.addOutput(HeavyOilResidue, 1); + Plastic.add(recipe, 2); + Recipe residualPlastic = new Recipe(6, "Residual Plastic", false); + residualPlastic.addInput(PolymerResin, 6); + residualPlastic.addInput(Water, 2); + Plastic.add(residualPlastic, 2); - Plastic.setPreference(recipe); + Plastic.setPreference(recipe); - HeavyOilResidue.add(recipe); - HeavyOilResidue.setPreference(recipe); - } - { - // Rubber - Recipe recipe = new Recipe(6, false); - recipe.addInput(CrudeOil, 3); - recipe.addOutput(HeavyOilResidue, 2); - Rubber.add(recipe, 2); - Recipe residualRubber = new Recipe(6, "Residual Rubber", false); - residualRubber.addInput(PolymerResin, 6); - residualRubber.addInput(Water, 4); - Rubber.add(residualRubber, 2); + HeavyOilResidue.add(recipe); + HeavyOilResidue.setPreference(recipe); + } + { + // Rubber + Recipe recipe = new Recipe(6, false); + recipe.addInput(CrudeOil, 3); + recipe.addOutput(HeavyOilResidue, 2); + Rubber.add(recipe, 2); + Recipe residualRubber = new Recipe(6, "Residual Rubber", false); + residualRubber.addInput(PolymerResin, 6); + residualRubber.addInput(Water, 4); + Rubber.add(residualRubber, 2); - Rubber.setPreference(recipe); + Rubber.setPreference(recipe); - HeavyOilResidue.add(recipe); - } - { - // Petroleum Coke - Recipe recipe = new Recipe(6, false); - recipe.addInput(HeavyOilResidue, 4); - PetroleumCoke.add(recipe, 12); - } - } + HeavyOilResidue.add(recipe); + } + { + // Petroleum Coke + Recipe recipe = new Recipe(6, false); + recipe.addInput(HeavyOilResidue, 4); + PetroleumCoke.add(recipe, 12); + } + } public static void add(Item i) { items.add(i); diff --git a/src/main/satisfactory/Test.java b/src/main/satisfactory/Test.java index 0c073df..1fb1434 100644 --- a/src/main/satisfactory/Test.java +++ b/src/main/satisfactory/Test.java @@ -67,28 +67,30 @@ public class Test { System.out.println("\nSUM_reif"); Database.ReinforcedIronPlate.getRecipe().sum(Database.ReinforcedIronPlate, 100); System.out.println("\nSUM_screw"); - Graph screws100 = Database.Screw.getRecipe().sum(Database.Screw, 100); - Graph computers100 = Database.Computer.getRecipe().sum(Database.Computer, 100); + Graph screws100 = Database.Screw.getRecipe().sum(Database.Screw, 100).getProduction(); + Graph computers100 = Database.Computer.getRecipe().sum(Database.Computer, 100).getProduction(); plot2(screws100, "screw_sum"); System.out.println("\nSUM_ACU"); - plot2(Database.AdaptiveControlUnit.getRecipe().sum(Database.AdaptiveControlUnit, 1), "acu4"); + plot2(Database.AdaptiveControlUnit.getRecipe().sum(Database.AdaptiveControlUnit, 1).getProduction(), "acu4"); - plot2(Utils.merge(screws100, computers100), "merged"); + //plot2(SumResult.merge(screws100, computers100), "merged"); System.out.println("\n\nPHASE 3"); Graph phase3; //phase3 = Utils.sum(Database.VersatileFrameWork, 2500); //phase3 = Utils.merge(phase3, Utils.sum(Database.ModularEngine,500)); - phase3 = Utils.sum(Database.ModularEngine,5); - phase3 = Utils.merge(phase3, Utils.sum(Database.AdaptiveControlUnit, 1)); + //phase3 = SumResult.sum(Database.ModularEngine,5); + //phase3 = SumResult.merge(phase3, SumResult.sum(Database.AdaptiveControlUnit, 1)); + + phase3 = SumResult.sum(new Production(Database.ModularEngine,5), new Production(Database.AdaptiveControlUnit,1)).getProduction(); plot2(phase3, "phase3"); System.out.println("\nrubber"); - plot2(Utils.sum(Database.Rubber, 75),"rubber"); + plot2(SumResult.sum(Database.Rubber, 75),"rubber"); System.out.println("\ntest"); - Utils.sum(Database.Plastic, 4); + SumResult.sum(Database.Plastic, 4); } diff --git a/src/main/satisfactory/Utils.java b/src/main/satisfactory/Utils.java index 4801dc6..6e1b6e3 100644 --- a/src/main/satisfactory/Utils.java +++ b/src/main/satisfactory/Utils.java @@ -15,6 +15,7 @@ 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.File; import java.util.HashMap; @@ -23,112 +24,83 @@ import java.util.Map; import java.util.stream.Collectors; public class Utils { - public static Map getRawOnly(Map totals) { - Map raws = new HashMap<>(); - for (Item item : totals.keySet().stream().filter(Item::isRaw).collect(Collectors.toList())) { - raws.put(item, totals.get(item)); - } - return raws; - } + public static Map getRawOnly(Map totals) { + Map raws = new HashMap<>(); + for (Item item : totals.keySet().stream().filter(Item::isRaw).collect(Collectors.toList())) { + raws.put(item, totals.get(item)); + } + return raws; + } - public static Map shorten(Map totals) { - Map shortend = new HashMap<>(); - totals.forEach((item, e) -> shortend.put(item.getName(), e)); - return shortend; - } + public static Map shorten(Map totals) { + Map shortend = new HashMap<>(); + totals.forEach((item, e) -> shortend.put(item.getName(), e)); + return shortend; + } - public static String dotID(Item item) { - String name = item.getName() + "_" + item.sum + "__" + (String.valueOf(item.getProductionRate()).replace(".", "_")); - name = name.replace(" ", "").replace(".", ""); - return name; - } + public static String dotID(Item item) { + String name = item.getName() + "_" + item.sum + "__" + (String.valueOf(item.getProductionRate()).replace(".", "_")); + name = name.replace(" ", "").replace(".", ""); + return name; + } - public static void fixSums(Item target, Graph graph) { - System.err.println(target); - EdgeReversedGraph inverse = new EdgeReversedGraph<>(graph); + public static void fixSums(Item target, Graph graph) { + System.err.println(target); + EdgeReversedGraph inverse = new EdgeReversedGraph<>(graph); - GraphIterator iterator = new DepthFirstIterator<>(inverse, target); - iterator.addTraversalListener(new TraversalListener() { - @Override - public void connectedComponentFinished(ConnectedComponentTraversalEvent e) { - System.out.println("\tconnectedComponentFinished: " + e); - } + GraphIterator iterator = new DepthFirstIterator<>(inverse, target); + iterator.addTraversalListener(new TraversalListener() { + @Override + public void connectedComponentFinished(ConnectedComponentTraversalEvent e) { + System.out.println("\tconnectedComponentFinished: " + e); + } - @Override - public void connectedComponentStarted(ConnectedComponentTraversalEvent e) { - System.out.println("\tconnectedComponentStarted: " + e); + @Override + public void connectedComponentStarted(ConnectedComponentTraversalEvent e) { + System.out.println("\tconnectedComponentStarted: " + e); - } + } - @Override - public void edgeTraversed(EdgeTraversalEvent e) { - System.out.println("\tedgeTraversed: " + e + "---> " + e.getEdge()); + @Override + public void edgeTraversed(EdgeTraversalEvent e) { + System.out.println("\tedgeTraversed: " + e + "---> " + e.getEdge()); - } + } - @Override - public void vertexTraversed(VertexTraversalEvent e) { - System.out.println("\tvertexTraversed: " + e + "---> " + e.getVertex().getName()); + @Override + public void vertexTraversed(VertexTraversalEvent e) { + System.out.println("\tvertexTraversed: " + e + "---> " + e.getVertex().getName()); - } + } - @Override - public void vertexFinished(VertexTraversalEvent e) { - System.out.println("\tvertexFinished: " + e); + @Override + public void vertexFinished(VertexTraversalEvent e) { + System.out.println("\tvertexFinished: " + e); - } - }); - while (iterator.hasNext()) { - Item i = iterator.next(); - System.out.println(i.getName()); - } - } + } + }); + while (iterator.hasNext()) { + Item i = iterator.next(); + System.out.println(i.getName()); + } + } - public static Graph merge(Graph graph0, Graph graph1) { - Graph result = new DefaultDirectedWeightedGraph<>(ProductionEdge.class); + public static void plot2(Graph sum, String filename) { + DOTExporter de = new DOTExporter<>(Item::ID); + de.setEdgeAttributeProvider(productionEdge -> { + Map m = new HashMap<>(); + m.put("label", DefaultAttribute.createAttribute(productionEdge.label())); + return m; + }); + de.setVertexAttributeProvider(item -> { + Map m = new HashMap<>(); + if (item.isRaw()) { + m.put("peripheries", DefaultAttribute.createAttribute(2)); + } + m.put("label", DefaultAttribute.createAttribute(item.getName())); + return m; + }); + de.exportGraph(sum, new File(filename + ".dot")); + } - graph0.vertexSet().forEach(result::addVertex); - graph0.edgeSet().forEach(productionEdge -> result.addEdge(graph0.getEdgeSource(productionEdge), graph0.getEdgeTarget(productionEdge), productionEdge)); - - graph1.vertexSet().forEach(result::addVertex); - graph1.edgeSet().forEach(productionEdge -> { - List collect = result.edgeSet().stream().filter(productionEdge1 -> productionEdge1.hasTarget(productionEdge.getTarget())).collect(Collectors.toList()); - collect.forEach(edge -> { - Item src = result.getEdgeSource(edge); - Item target = result.getEdgeTarget(edge); - Item target2 = graph1.getEdgeTarget(productionEdge); - if (target != target2) { - result.addEdge(src, target2, productionEdge); - } else { - result.removeEdge(edge); - result.addEdge(src, target, edge); - } - }); - if (collect.isEmpty()) { - result.addEdge(graph1.getEdgeSource(productionEdge), graph1.getEdgeTarget(productionEdge), productionEdge); - } - }); - return result; - } - - public static Graph sum(Item item, int amount) { - return item.getRecipe().sum(item,amount); - } - - public static void plot2(Graph sum, String filename) { - DOTExporter de = new DOTExporter<>(Item::ID); - de.setEdgeAttributeProvider(productionEdge -> { - Map m = new HashMap<>(); - m.put("label", DefaultAttribute.createAttribute(productionEdge.label())); - return m; - }); - de.setVertexAttributeProvider(item -> { - Map m = new HashMap<>(); - if (item.isRaw()) { - m.put("peripheries", DefaultAttribute.createAttribute(2)); - } - return m; - }); - de.exportGraph(sum, new File(filename+".dot")); - } } diff --git a/src/main/satisfactory/items/Production.java b/src/main/satisfactory/items/Production.java new file mode 100644 index 0000000..15f518b --- /dev/null +++ b/src/main/satisfactory/items/Production.java @@ -0,0 +1,19 @@ +package satisfactory.items; + +public class Production { + private final Item item; + private final int amount; + + public Production(Item item, int amount) { + this.item = item; + this.amount = amount; + } + + public Item getItem() { + return item; + } + + public int getAmount() { + return amount; + } +} diff --git a/src/main/satisfactory/items/ProductionEdge.java b/src/main/satisfactory/items/ProductionEdge.java index b3d6c69..317932c 100644 --- a/src/main/satisfactory/items/ProductionEdge.java +++ b/src/main/satisfactory/items/ProductionEdge.java @@ -3,62 +3,77 @@ package satisfactory.items; import java.util.Objects; public class ProductionEdge { - private Item source; - private double totalRequired; - private double instances; + private final Item source; + private final Item target; + 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); - } + public ProductionEdge(Item source, Item target, double totalRequired, double productionRate) { + this.source = source; + this.target = target; + this.totalRequired = totalRequired; + this.instances = productionRate; + } - public double getTotalRequired() { - return totalRequired; - } + public String label() { + //return "(" + totalRequired + "||" + instances + ")"; + return "(%.2f||%.2f)".formatted(totalRequired, instances); + } - public void setTotalRequired(double totalRequired) { - this.totalRequired = totalRequired; - } + public void merge(ProductionEdge other) { + if (source.equals(other.getSource())) { + totalRequired += other.getTotalRequired(); + instances += other.getInstances(); + } + } - public double getInstances() { - return instances; - } + public double getTotalRequired() { + return totalRequired; + } - public void setInstances(double instances) { - this.instances = instances; - } + public void setTotalRequired(double totalRequired) { + this.totalRequired = totalRequired; + } - public boolean hasTarget(Item t){ - return source.equals(t); - } + public double getInstances() { + return 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); - } + public void setInstances(double instances) { + this.instances = instances; + } - @Override - public int hashCode() { - return Objects.hash(source, totalRequired, instances); - } + public boolean hasSource(Item t) { + return source.equals(t); + } - @Override - public String toString() { - return "ProductionEdge{" + - "totalRequired=" + totalRequired + - ", instances=" + 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 Objects.equals(source, that.source) && Objects.equals(target, that.target); + } - public Item getTarget() { - return source; - } + @Override + public int hashCode() { + return Objects.hash(source, target); + } + + @Override + public String toString() { + return "ProductionEdge{" + + "source=" + source.getName() + + ", totalRequired=" + totalRequired + + ", instances=" + instances + + '}'; + } + + public Item getSource() { + return source; + } + + public Item getTarget() { + return target; + } } diff --git a/src/main/satisfactory/items/Recipe.java b/src/main/satisfactory/items/Recipe.java index 588df45..3bdd0f2 100644 --- a/src/main/satisfactory/items/Recipe.java +++ b/src/main/satisfactory/items/Recipe.java @@ -1,239 +1,240 @@ package satisfactory.items; -import satisfactory.items.requirements.RateAccumulator; -import satisfactory.items.requirements.TotalAccumulator; import org.jgrapht.Graph; import org.jgrapht.Graphs; import org.jgrapht.graph.DefaultDirectedWeightedGraph; import org.jgrapht.graph.DefaultWeightedEdge; +import satisfactory.items.requirements.RateAccumulator; +import satisfactory.items.requirements.TotalAccumulator; import java.util.*; import java.util.stream.Collectors; public class Recipe { - private final Map inputs; - private final Map outputs; - private boolean isHandCraftable = true; - private String name; - private final int duration; + private final Map inputs; + private final Map outputs; + private boolean isHandCraftable = true; + private String name; + private final int duration; - public Recipe(int duration) { - inputs = new HashMap<>(); - outputs = new HashMap<>(); - this.duration = duration; - } + public Recipe(int duration) { + inputs = new HashMap<>(); + outputs = new HashMap<>(); + this.duration = duration; + } - public Recipe(int duration, boolean isHandCraftable) { - this(duration); - this.isHandCraftable = isHandCraftable; - } + public Recipe(int duration, boolean isHandCraftable) { + this(duration); + this.isHandCraftable = isHandCraftable; + } - public Recipe(int duration, Item item, int input) { - this(duration); - addInput(item, input); - } + public Recipe(int duration, Item item, int input) { + this(duration); + addInput(item, input); + } - public Recipe(int duration, Map inputs, Map outputs) { - this.duration = duration; - this.inputs = inputs; - this.outputs = outputs; - } + public Recipe(int duration, Map inputs, Map outputs) { + this.duration = duration; + this.inputs = inputs; + this.outputs = outputs; + } - public Recipe(int duration, String name, boolean isHandCraftable) { - this(duration); - this.name = name; - this.isHandCraftable = isHandCraftable; - } + public Recipe(int duration, String name, boolean isHandCraftable) { + this(duration); + this.name = name; + this.isHandCraftable = isHandCraftable; + } - public static Map getInputs(Map values) { - Map names = new HashMap<>(); - for (Item item : values.keySet()) { - names.put(item.getName(), values.get(item)); - } - return names; - } + public static Map getInputs(Map values) { + Map names = new HashMap<>(); + for (Item item : values.keySet()) { + names.put(item.getName(), values.get(item)); + } + return names; + } - public void addInput(Item item, int amount) { - inputs.put(item, amount); - } + public void addInput(Item item, int amount) { + inputs.put(item, amount); + } - @Override - public String toString() { - return "Recipe{" + - "inputs=" + inputs + - ", outputs=" + formatIO(outputs) + - ", isHandCraftable=" + isHandCraftable + - ", name='" + name + '\'' + - ", duration=" + duration + - '}'; - } + @Override + public String toString() { + return "Recipe{" + + "inputs=" + inputs + + ", outputs=" + formatIO(outputs) + + ", isHandCraftable=" + isHandCraftable + + ", name='" + name + '\'' + + ", duration=" + duration + + '}'; + } - public void addInput(Item input) { - addInput(input, 1); - } + public void addInput(Item input) { + addInput(input, 1); + } - public void addOutput(Item item, int amount) { - this.outputs.put(item, amount); - } + public void addOutput(Item item, int amount) { + this.outputs.put(item, amount); + } - public void checkOutput(Item item, int amount) { - if (!(outputs.containsKey(item) && outputs.get(item) == amount)) { - outputs.put(item, amount); - } - } + public void checkOutput(Item item, int amount) { + if (!(outputs.containsKey(item) && outputs.get(item) == amount)) { + outputs.put(item, amount); + } + } - private String formatIO(Map map) { - StringBuilder sb = new StringBuilder("{"); - map.forEach((item, integer) -> sb.append(item.getName()).append(": ").append(integer).append(", ")); - return sb.append("}").toString(); - } + private String formatIO(Map map) { + StringBuilder sb = new StringBuilder("{"); + map.forEach((item, integer) -> sb.append(item.getName()).append(": ").append(integer).append(", ")); + return sb.append("}").toString(); + } - public Map getTotalRequirements() { - return new TotalAccumulator(inputs).accumulate(); - } + public Map getTotalRequirements() { + return new TotalAccumulator(inputs).accumulate(); + } - public float getProductionRate(Item item) { - float production = outputs.get(item); - return (float) (production / (duration / 60.0)); - } + public float getProductionRate(Item item) { + float production = outputs.get(item); + return (float) (production / (duration / 60.0)); + } - public Map getRequirementRates(Item item) { - float rate = getProductionRate(item); - return new RateAccumulator(this, item).accumulate(); - } + public Map getRequirementRates(Item item) { + float rate = getProductionRate(item); + return new RateAccumulator(this, item).accumulate(); + } - public Map getInputs() { - return inputs; - } + public Map getInputs() { + return inputs; + } - public Graph buildGraph(Item target) { - Graph graph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class); - graph.addVertex(target); - target.sum += 1; - 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); - }); - inputs.forEach((item, integer) -> { - graph.addVertex(item); - graph.addEdge(item, target); - graph.setEdgeWeight(item, target, integer); + public Graph buildGraph(Item target) { + Graph graph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class); + graph.addVertex(target); + target.sum += 1; + 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); + }); + inputs.forEach((item, integer) -> { + graph.addVertex(item); + graph.addEdge(item, target); + graph.setEdgeWeight(item, target, integer); - Recipe recipe = item.getRecipe(); - if (recipe != null) { - Graph g = recipe.buildGraph(item); - Graphs.addGraph(graph, g); - } - }); + Recipe recipe = item.getRecipe(); + if (recipe != null) { + Graph g = recipe.buildGraph(item); + Graphs.addGraph(graph, g); + } + }); - return graph; - } + return graph; + } - private float getLoad(Item target, float amount) { - return getUsage(target, amount) * duration; - } + private float getLoad(Item target, float amount) { + return getUsage(target, amount) * duration; + } - private float getUsage(Item target, float amount) { - return amount / outputs.get(target); - } + 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); + 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); - } - }); + Recipe recipe = item.getRecipe(); + if (recipe != null) { + Graph g = recipe.buildGraph(item, rate); + Graphs.addGraph(graph, g); + } + }); - return graph; - } + return graph; + } - private double processesNeeded(Item target, double n) { - Recipe r = target.getRecipe(); - return n / r.getProductionRate(target); - } + private double processesNeeded(Item target, double n) { + Recipe r = target.getRecipe(); + return n / r.getProductionRate(target); + } - public Graph sum(Item target, int prodPerMinute) { - Graph buildGraph = buildGraph(target); - Graph production = new DefaultDirectedWeightedGraph<>(ProductionEdge.class); - Map map = new HashMap<>(); - Queue queue = new LinkedList<>(); - queue.add(target); - map.put(target, (double) prodPerMinute); - production.addVertex(target); - production.addEdge(target, target, new ProductionEdge(target, prodPerMinute, processesNeeded(target, prodPerMinute))); - while (!queue.isEmpty()) { - Item item = queue.remove(); - // next satisfactory.items - buildGraph.incomingEdgesOf(item) - .stream() - .map(buildGraph::getEdgeSource) - .forEach(queue::add); - // *this* item - double sum = 0; - Set byProducts = new HashSet<>(); - for (DefaultWeightedEdge edge : buildGraph.outgoingEdgesOf(item)) { - Item product = buildGraph.getEdgeTarget(edge); - Double productWantedPerMinute = map.get(product); - if (item.getRecipe().outputs.containsKey(product)){ - // product is by-product, no forward dependency - byProducts.add(product); - continue; - } - if (productWantedPerMinute == null) { - sum = 0; - break; - } - double amountNeeded = buildGraph.getEdgeWeight(edge); - int productPerProcess = product.getRecipe().outputs.get(product); - double requiredProcesRuns = productWantedPerMinute / productPerProcess; - double requiredInput = amountNeeded * requiredProcesRuns; - sum += requiredInput; + public SumResult sum(Item target, int prodPerMinute) { + Graph buildGraph = buildGraph(target); + Graph production = new DefaultDirectedWeightedGraph<>(ProductionEdge.class); + Map map = new HashMap<>(); + Queue queue = new LinkedList<>(); + queue.add(target); + map.put(target, (double) prodPerMinute); + production.addVertex(target); + production.addEdge(target, target, new ProductionEdge(target, target, prodPerMinute, processesNeeded(target, prodPerMinute))); + while (!queue.isEmpty()) { + Item item = queue.remove(); + // next items + buildGraph.incomingEdgesOf(item) + .stream() + .map(buildGraph::getEdgeSource) + .forEach(queue::add); + // *this* item + double sum = 0; + Set byProducts = new HashSet<>(); + for (DefaultWeightedEdge edge : buildGraph.outgoingEdgesOf(item)) { + Item product = buildGraph.getEdgeTarget(edge); + Double productWantedPerMinute = map.get(product); + if (item.getRecipe().outputs.containsKey(product)) { + // product is by-product, no forward dependency + byProducts.add(product); + continue; + } + if (productWantedPerMinute == null) { + sum = 0; + break; + } + double amountNeeded = buildGraph.getEdgeWeight(edge); + int productPerProcess = product.getRecipe().outputs.get(product); + double requiredProcesRuns = productWantedPerMinute / productPerProcess; + double requiredInput = amountNeeded * requiredProcesRuns; + sum += requiredInput; + + production.addVertex(item); + production.addEdge(item, product, new ProductionEdge(item, product, requiredInput, processesNeeded(item, requiredInput))); + } + if (!map.containsKey(item) && sum > 0) { + map.put(item, sum); + } + if (!byProducts.isEmpty()) { + byProducts.forEach(item1 -> { + production.addVertex(item1); + // TODO: calculate produced amount + production.addEdge(item, item1, new ProductionEdge(item, item1, 0, 0)); + }); + } + } + map.forEach((item, aDouble) -> { + System.out.println(item.getName() + ": " + aDouble); + }); + return new SumResult(production, map); + } - production.addVertex(item); - production.addEdge(item, product, new ProductionEdge(item, requiredInput, processesNeeded(item, requiredInput))); - } - if (!map.containsKey(item) && sum > 0) { - map.put(item, sum); - } - if (!byProducts.isEmpty()) { - byProducts.forEach(item1 -> { - production.addVertex(item1); - // TODO: calculate produced amount - production.addEdge(item, item1, new ProductionEdge(item, 0,0)); - }); - } - } - map.forEach((item, aDouble) -> { - System.out.println(item.getName() + ": " + aDouble); - }); - return production; - } } diff --git a/src/main/satisfactory/items/SumResult.java b/src/main/satisfactory/items/SumResult.java new file mode 100644 index 0000000..111768e --- /dev/null +++ b/src/main/satisfactory/items/SumResult.java @@ -0,0 +1,81 @@ +package satisfactory.items; + +import org.jgrapht.Graph; +import org.jgrapht.graph.DefaultDirectedWeightedGraph; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class SumResult { + private final Graph production; + private final Map map; + + public SumResult(Graph production, Map map) { + this.production = production; + this.map = map; + } + + public SumResult() { + production = new DefaultDirectedWeightedGraph<>(ProductionEdge.class); + map = new HashMap<>(); + } + + public Graph getProduction() { + return production; + } + + public Map getMap() { + return map; + } + + public SumResult merge(SumResult other){ + HashMap map = new HashMap<>(); + this.map.forEach(map::put); + other.map.forEach((item, aDouble) -> map.merge(item,aDouble,Double::sum)); + return new SumResult(merge(production, other.getProduction()), map); + } + + public static Graph sum(Item item, int amount) { + return item.getRecipe().sum(item, amount).getProduction(); + } + + public static SumResult sum(Production... productions) { + return Arrays.stream(productions) + .map(prod -> prod.getItem().getRecipe().sum(prod.getItem(), prod.getAmount())) + .reduce(SumResult::merge).orElse(new SumResult()); + } + + public static Graph merge(Graph graph0, Graph graph1) { + // ToDo: test! + Graph result = new DefaultDirectedWeightedGraph<>(ProductionEdge.class); + + graph0.vertexSet().forEach(result::addVertex); + graph0.edgeSet().forEach(productionEdge -> result.addEdge(graph0.getEdgeSource(productionEdge), graph0.getEdgeTarget(productionEdge), productionEdge)); + + graph1.vertexSet().forEach(result::addVertex); + graph1.edgeSet().forEach(productionEdge -> { + List collect = result.edgeSet().stream() + .filter(productionEdge1 -> productionEdge1.hasSource(productionEdge.getSource())) + .collect(Collectors.toList()); + collect.forEach(edge -> { + Item src = result.getEdgeSource(edge); + Item target = result.getEdgeTarget(edge); + Item target2 = graph1.getEdgeTarget(productionEdge); + if (target != target2) { + result.addEdge(src, target2, productionEdge); + } else { + /*result.removeEdge(edge); + result.addEdge(src, target, edge);*/ + edge.merge(productionEdge); + } + }); + if (collect.isEmpty()) { + result.addEdge(graph1.getEdgeSource(productionEdge), graph1.getEdgeTarget(productionEdge), productionEdge); + } + }); + return result; + } +} diff --git a/src/test/satisfactory/items/ItemTest.java b/src/test/satisfactory/items/ItemTest.java index 6f0b534..80c5073 100644 --- a/src/test/satisfactory/items/ItemTest.java +++ b/src/test/satisfactory/items/ItemTest.java @@ -1,27 +1,28 @@ package satisfactory.items; +import org.jgrapht.Graph; import org.junit.jupiter.api.Test; +import satisfactory.Database; +import satisfactory.Utils; +import java.util.HashMap; import java.util.Map; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; - -import satisfactory.Database; +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 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 productionScrews2() { + @Test + void productionScrews2() { /*Map production = Database.Screw.getRecipe().sum(Database.Screw, 100); assertEquals(100, production.get(Database.Screw), "Screws (output)"); assertEquals(25, production.get(Database.IronRod), "IronRod"); @@ -29,23 +30,71 @@ class ItemTest { assertEquals(25, production.get(Database.IronOre), "IronOre"); */ - fail("TODO: migrate"); - } + fail("TODO: migrate"); + } - @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"); - } + @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"); + } - @Test - void testScrewProd(){ - float productionRate = Database.Screw.getRecipe().getProductionRate(Database.Screw); - assertEquals(40, productionRate); - } + @Test + void testScrewProd() { + float productionRate = Database.Screw.getRecipe().getProductionRate(Database.Screw); + assertEquals(40, productionRate); + } + + @Test + void testPhase3_ME_ACU() { + // references + Map ref = new HashMap<>(); + ref.put(Database.CircuitBoard, 15.0); + ref.put(Database.Computer, 1.0); + ref.put(Database.Limestone,75.0); + ref.put(Database.Concrete,25.0); + ref.put(Database.SteelBeam,20.0); + ref.put(Database.EncasedIndustrialBeam, 5.0); + ref.put(Database.ModularFrame,5.0); + ref.put(Database.HeavyModularFrame,1.0); + ref.put(Database.Plastic, 78.0); + ref.put(Database.CopperSheet, 30.0); + ref.put(Database.Coal,226.25); + ref.put(Database.Cable,159.0); + ref.put(Database.CopperOre,329.0); + ref.put(Database.AutomatedWiring, 7.5); + ref.put(Database.AdaptiveControlUnit, 1.0); + ref.put(Database.CrudeOil, 229.5); + ref.put(Database.ReinforcedIronPlate, 17.5); + ref.put(Database.CopperIngot, 329.0); + ref.put(Database.SteelIngot, 226.25); + ref.put(Database.IronPlate, 105.0); + ref.put(Database.SmartPlating, 10.0); + //ref.put(Database.HeavyOilResidue, 114.0); // TODO: implement calculation + ref.put(Database.Rubber, 75.0); + ref.put(Database.Wire, 538.0); + ref.put(Database.SteelPipe, 97.5); + ref.put(Database.Stator, 27.5); + ref.put(Database.Screw, 1112.0); + ref.put(Database.IronOre, 841.75); + ref.put(Database.IronIngot, 615.5); + ref.put(Database.IronRod, 458.0); + ref.put(Database.Rotor, 30.0); + ref.put(Database.Motor, 10.0); + ref.put(Database.ModularEngine, 5.0); + + // calculate + Map calculations = SumResult.sum(new Production(Database.ModularEngine, 5), new Production(Database.AdaptiveControlUnit, 1)).getMap(); + + // assert + ref.forEach((item, amount) -> { + assertTrue(calculations.containsKey(item), "exists? " + item.getName()); + assertEquals(amount, calculations.get(item), 0.01, item.getName()); + }); + } } \ No newline at end of file