NeoGriever

Untitled

Nov 5th, 2024 (edited)
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.70 KB | None | 0 0
  1. simulationResults = {}
  2. round_robin = false
  3.  
  4. function loadRecipes(filename)
  5.     local recipes = {}
  6.     for line in io.lines(filename) do
  7.         local name, inputs, outputs = line:match("([^/]+)/(.+)/(.+)")
  8.         if name and inputs and outputs then
  9.             local recipe = {name = name, inputs = {}, outputs = {}}
  10.             for input in inputs:gmatch("[^;]+") do
  11.                 local item, count = input:match("([^,]+),(%d+)")
  12.                 table.insert(recipe.inputs, {name = item, count = tonumber(count)})
  13.             end
  14.             for output in outputs:gmatch("[^;]+") do
  15.                 local item, count = output:match("([^,]+),(%d+)")
  16.                 table.insert(recipe.outputs, {name = item, count = tonumber(count)})
  17.             end
  18.             table.insert(recipes, recipe)
  19.         end
  20.     end
  21.     return recipes
  22. end
  23. function calculateTotalItemCount(itemName, inventory)
  24.     local totalCount = 0
  25.     for slot, item in pairs(inventory) do
  26.         if item.name == itemName then
  27.             totalCount = totalCount + item.count
  28.         end
  29.     end
  30.     return totalCount
  31. end
  32. function createVirtualInventory()
  33.     virtualInventory = {}
  34.     for i = 1, chest.size() do
  35.         local item = chest.getItemDetail(i)
  36.         if item ~= nil then
  37.             virtualInventory[#virtualInventory + 1] = item
  38.         end
  39.     end
  40. end
  41. function takeVirtualItem(item_id, amount, remove)
  42.     local found_amount = 0
  43.     for i = 1, #virtualInventory do
  44.         if virtualInventory[i]["name"] == item_id then
  45.             found_amount = found_amount + virtualInventory[i]["count"]
  46.         end
  47.     end
  48.     if found_amount >= amount then
  49.         local required_amount = amount
  50.         if remove then
  51.             for i = 1, #virtualInventory do
  52.                 if virtualInventory[i]["name"] == item_id then
  53.                     if virtualInventory[i]["count"] >= amount then
  54.                         virtualInventory[i]["count"] = virtualInventory[i]["count"] - amount
  55.                         required_amount = 0
  56.                     elseif virtualInventory[i]["count"] > 0 then
  57.                         required_amount = required_amount - virtualInventory[i]["count"]
  58.                         virtualInventory[i]["count"] = 0
  59.                     end
  60.                     if virtualInventory[i]["count"] == 0 then
  61.                         virtualInventory[i] = nil
  62.                     end
  63.                     if required_amount == 0 then
  64.                         break
  65.                     end
  66.                 end
  67.             end
  68.         end
  69.         return true
  70.     else
  71.         return false
  72.     end
  73. end
  74.  
  75. function initializeSimulationResults(recipes)
  76.     for _, recipe in ipairs(recipes) do
  77.         simulationResults[recipe.name] = {executed = 0, max = 0}
  78.     end
  79.     printResults()
  80. end
  81.  
  82. function runSimulation(recipes)
  83.     createVirtualInventory()
  84.     local added_count = 1 -- Initial-wert, damit die schleife mindestens 1 mal durchläuft
  85.     while added_count > 0 do
  86.         added_count = 0 -- grundwert festlegen für round-robin-workaround
  87.         for _, recipe in ipairs(recipes) do
  88.             has_required_sources = true
  89.             while has_required_sources do
  90.                 for _, input in ipairs(recipe.inputs) do
  91.                     if takeVirtualItem(input.name, input.count, false) == false then
  92.                         has_required_sources = false
  93.                         break
  94.                     end
  95.                 end
  96.                 if has_required_sources then
  97.                     for _, input in ipairs(recipe.inputs) do
  98.                         takeVirtualItem(input.name, input.count, true)
  99.                     end
  100.                     simulationResults[recipe.name].max = simulationResults[recipe.name].max + 1
  101.                     printResults()
  102.                     added_count = added_count + 1
  103.                     if round_robin then
  104.                         break
  105.                     end
  106.                 end
  107.             end
  108.         end
  109.     end
  110. end
  111.  
  112. function executeRecipe(recipe)
  113.     -- Ressourcen von Chest zu Machine verschieben
  114.     for _, input in ipairs(recipe.inputs) do
  115.         local remaining = input.count
  116.         for i = 1, chest.size() do
  117.             local item = chest.getItemDetail(i)
  118.             if item and item.name == input.name then
  119.                 local transferAmount = math.min(item.count, remaining)
  120.                 chest.pushItems("left", i, transferAmount)
  121.                 remaining = remaining - transferAmount
  122.                 if remaining <= 0 then
  123.                     break
  124.                 end
  125.             end
  126.         end
  127.     end
  128. end
  129.  
  130. -- Funktion zur Überprüfung und Speicherung des Ausgabeelements
  131. function waitForAndStoreOutput(recipe, executed)
  132.     while true do
  133.         local slot1results = machine.getItemDetail(1)
  134.         if slot1results and slot1results.name == recipe.outputs[1].name and slot1results.count >= recipe.outputs[1].count then
  135.             -- Ergebnis-Item in die Kiste ziehen
  136.             chest.pullItems("left", 1, slot1results.count)
  137.             executed = executed + 1
  138.            
  139.             -- Aktualisierte Anzeige des ausgeführten Rezeptes
  140.             simulationResults[recipe.name].executed = executed
  141.             printResults()
  142.  
  143.             return executed  -- Aktualisierten Zähler zurückgeben
  144.         end
  145.         os.sleep(0.1)  -- Kurze Pause, bevor erneut geprüft wird
  146.     end
  147. end
  148.  
  149. -- Funktion zur formatierten Anzeige der Simulationsergebnisse
  150. function printResults()
  151.     term.setCursorPos(1, 1)
  152.     for name, result in pairs(simulationResults) do
  153.         print(name .. " " .. trail(4, result.executed) .. " / " .. trail(4, result.max))
  154.     end
  155. end
  156.  
  157. -- Hilfsfunktion zur Formatierung der Zahlen
  158. function trail(count, value)
  159.     local str = tostring(value)
  160.     return string.rep(" ", count - #str) .. str
  161. end
  162.  
  163. -- Hauptprogramm zur Durchführung der Simulation und Ausführung der Rezepte
  164. function main()
  165.     local recipes = loadRecipes("recipes.lst")
  166.  
  167.     -- Initialisierung der leeren Grundstruktur der Simulationsergebnisse
  168.     initializeSimulationResults(recipes)
  169.  
  170.     -- Durchführung der Simulation mit Live-Updates
  171.     runSimulation(recipes)
  172.  
  173.     -- Modus festlegen:
  174.     round_robin = false
  175.  
  176.     -- Rezepte tatsächlich ausführen
  177.     if round_robin ~= false then
  178.         -- Stack-Modus: Jedes Rezept vollständig ausführen, bevor das nächste Rezept gestartet wird
  179.         for _, recipe in ipairs(recipes) do
  180.             local maxExecutions = simulationResults[recipe.name].max
  181.             local executed = 0
  182.             for _ = 1, maxExecutions do
  183.                 executeRecipe(recipe)
  184.                 executed = waitForAndStoreOutput(recipe, executed)
  185.             end
  186.         end
  187.     elseif round_robin then
  188.         -- Round-Robin-Modus: Rezepte nacheinander einmal ausführen, bis keine weiteren Ausführungen möglich sind
  189.         local active = true
  190.         local executionCounts = {}
  191.        
  192.         -- Initialisiere Zähler für alle Rezepte
  193.         for _, recipe in ipairs(recipes) do
  194.             executionCounts[recipe.name] = 0
  195.         end
  196.        
  197.         while active do
  198.             active = false
  199.             for _, recipe in ipairs(recipes) do
  200.                 local maxExecutions = simulationResults[recipe.name].max
  201.                 if executionCounts[recipe.name] < maxExecutions then
  202.                     executeRecipe(recipe)
  203.                     executionCounts[recipe.name] = waitForAndStoreOutput(recipe, executionCounts[recipe.name])
  204.                     active = true
  205.                 end
  206.             end
  207.         end
  208.     end
  209. end
  210.  
  211. -- Initialisierung der Peripherie
  212. machine = peripheral.wrap("left")
  213. chest = peripheral.wrap("right")
  214.  
  215. -- Skript ausführen
  216. main()
  217.  
Advertisement
Add Comment
Please, Sign In to add comment