plan: document the calculate_rates function

This commit is contained in:
Danny Robson 2019-07-14 11:49:49 +10:00
parent 2380faf59d
commit 07a37a4240

80
plan.py
View File

@ -4,42 +4,11 @@ import math
import collections import collections
from fractions import Fraction from fractions import Fraction
from typing import Dict, Iterable from typing import Dict, List
import satisfactory import satisfactory
def calculate_rates(recipes: Iterable[str], remain: Dict[str,Fraction]):
required_items = collections.defaultdict(Fraction)
while remain:
for dst_name, dst_rate in remain.pop().items():
required_items[dst_name] += dst_rate
dst = recipes[dst_name]
if not recipes.is_component(dst_name):
continue
dst_recipe = recipes[dst_name]['recipes'][0]
src_recipe = recipes[dst_name]['recipes'][0]
normal_rate = Fraction(
dst_recipe['output'][dst_name],
dst_recipe['crafting_time']
)
scale = dst_rate / normal_rate
for src_name, src_count in src_recipe['input'].items():
src_rate = Fraction(
src_count,
dst_recipe['crafting_time']
) * scale
remain.append({src_name: src_rate})
return required_items
def basic_rate(recipe: Dict) -> Fraction: def basic_rate(recipe: Dict) -> Fraction:
""" """
Calculate the rate at which the item is crafted with the default recipe. Calculate the rate at which the item is crafted with the default recipe.
@ -52,6 +21,49 @@ def basic_rate(recipe: Dict) -> Fraction:
) )
def calculate_rates(
recipes: satisfactory.Cookbook,
remain: List[Dict[str, Fraction]]
) -> Dict[str, Fraction]:
"""
Calculate the total production rates needed to produce items at the rates
listed in 'remain' using the provided recipes.
:param recipes: The source Cookbook
:param remain: A mapping from requested items to their desired rate.
:return: A mapping from all required items to their required output rates.
"""
# Iteratively accumulate a mapping from items to required rates
required_items = collections.defaultdict(Fraction)
while remain:
for dst_name, dst_rate in remain.pop().items():
# Append the requested item
required_items[dst_name] += dst_rate
# We can't craft resources, so just ignore them.
if not recipes.is_component(dst_name):
assert recipes.is_resource(dst_name)
continue
# Assume we're using the default recipe
dst_recipe = recipes[dst_name]['recipes'][0]
# Calculate the fraction of the base rate we need to satisfy, and
# append our (scaled) inputs to the request queue.
normal_rate = basic_rate(dst_recipe)
scale = dst_rate / normal_rate
for src_name, src_count in dst_recipe['input'].items():
src_rate = Fraction(
src_count,
dst_recipe['crafting_time']
) * scale
remain.append({src_name: src_rate})
return required_items
# The number of items per minute that each tier of conveyor can carry # The number of items per minute that each tier of conveyor can carry
conveyor_rates = [0, 60, 120, 270, 480, 780, 900] conveyor_rates = [0, 60, 120, 270, 480, 780, 900]
@ -59,10 +71,8 @@ conveyor_rates = [0, 60, 120, 270, 480, 780, 900]
def main(): def main():
recipes = satisfactory.Cookbook('data/recipes') recipes = satisfactory.Cookbook('data/recipes')
required_items = collections.defaultdict(Fraction)
# Create a list of items we want to make # Create a list of items we want to make
#targets = [ 'supercomputer' ] # targets = [ 'supercomputer' ]
targets = recipes.components() targets = recipes.components()
# Create an initial name:rate request for all of the target items, then # Create an initial name:rate request for all of the target items, then