Factorio: cleanup and optimize some requirement graph functions
This commit is contained in:
parent
383d0f1a66
commit
8af5855af6
|
@ -131,6 +131,7 @@ class Recipe(FactorioElement):
|
||||||
base = {technology_table[tech_name] for tech_name in recipe_sources.get(self.name, ())}
|
base = {technology_table[tech_name] for tech_name in recipe_sources.get(self.name, ())}
|
||||||
for ingredient in self.ingredients:
|
for ingredient in self.ingredients:
|
||||||
base |= required_technologies[ingredient]
|
base |= required_technologies[ingredient]
|
||||||
|
base |= required_technologies[self.crafting_machine]
|
||||||
return base
|
return base
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -472,7 +473,7 @@ def get_science_pack_pools() -> Dict[str, Set[str]]:
|
||||||
cost += rel_cost.get(ingredient_name, 1) * amount
|
cost += rel_cost.get(ingredient_name, 1) * amount
|
||||||
return cost
|
return cost
|
||||||
|
|
||||||
science_pack_pools = {}
|
science_pack_pools: Dict[str, Set[str]] = {}
|
||||||
already_taken = blacklist.copy()
|
already_taken = blacklist.copy()
|
||||||
current_difficulty = 5
|
current_difficulty = 5
|
||||||
for science_pack in Options.MaxSciencePack.get_ordered_science_packs():
|
for science_pack in Options.MaxSciencePack.get_ordered_science_packs():
|
||||||
|
@ -483,7 +484,8 @@ def get_science_pack_pools() -> Dict[str, Set[str]]:
|
||||||
current |= set(recipe.products)
|
current |= set(recipe.products)
|
||||||
if science_pack == "automation-science-pack":
|
if science_pack == "automation-science-pack":
|
||||||
current |= {"iron-ore", "copper-ore", "coal", "stone"}
|
current |= {"iron-ore", "copper-ore", "coal", "stone"}
|
||||||
current -= liquids # Can't hand craft automation science if liquids end up in its recipe, making the seed impossible.
|
# Can't hand craft automation science if liquids end up in its recipe, making the seed impossible.
|
||||||
|
current -= liquids
|
||||||
elif science_pack == "logistic-science-pack":
|
elif science_pack == "logistic-science-pack":
|
||||||
current |= {"steam"}
|
current |= {"steam"}
|
||||||
current -= already_taken
|
current -= already_taken
|
||||||
|
|
|
@ -184,7 +184,8 @@ class Factorio(World):
|
||||||
for recipe in world.worlds[player].custom_recipes.values():
|
for recipe in world.worlds[player].custom_recipes.values():
|
||||||
spoiler_handle.write(f"\n{recipe.name} ({name}): {recipe.ingredients} -> {recipe.products}")
|
spoiler_handle.write(f"\n{recipe.name} ({name}): {recipe.ingredients} -> {recipe.products}")
|
||||||
|
|
||||||
def make_balanced_recipe(self, original: Recipe, pool: list, factor: float = 1) -> Recipe:
|
def make_balanced_recipe(self, original: Recipe, pool: list, factor: float = 1, allow_liquids: int = 2) -> \
|
||||||
|
Recipe:
|
||||||
"""Generate a recipe from pool with time and cost similar to original * factor"""
|
"""Generate a recipe from pool with time and cost similar to original * factor"""
|
||||||
new_ingredients = {}
|
new_ingredients = {}
|
||||||
self.world.random.shuffle(pool)
|
self.world.random.shuffle(pool)
|
||||||
|
@ -200,6 +201,17 @@ class Factorio(World):
|
||||||
|
|
||||||
# fill all but one slot with random ingredients, last with a good match
|
# fill all but one slot with random ingredients, last with a good match
|
||||||
while remaining_num_ingredients > 0 and pool:
|
while remaining_num_ingredients > 0 and pool:
|
||||||
|
ingredient = pool.pop()
|
||||||
|
if liquids_used == allow_liquids and ingredient in liquids:
|
||||||
|
continue # can't use this ingredient as we already have maximum liquid in our recipe.
|
||||||
|
if ingredient in all_product_sources:
|
||||||
|
ingredient_recipe = min(all_product_sources[ingredient], key=lambda recipe: recipe.rel_cost)
|
||||||
|
ingredient_raw = sum((count for ingredient, count in ingredient_recipe.base_cost.items()))
|
||||||
|
ingredient_energy = ingredient_recipe.total_energy
|
||||||
|
else:
|
||||||
|
# assume simple ore TODO: remove if tree when mining data is harvested from Factorio
|
||||||
|
ingredient_raw = 1
|
||||||
|
ingredient_energy = 2
|
||||||
if remaining_num_ingredients == 1:
|
if remaining_num_ingredients == 1:
|
||||||
max_raw = 1.1 * remaining_raw
|
max_raw = 1.1 * remaining_raw
|
||||||
min_raw = 0.9 * remaining_raw
|
min_raw = 0.9 * remaining_raw
|
||||||
|
@ -210,15 +222,6 @@ class Factorio(World):
|
||||||
min_raw = (remaining_raw - max_raw) / remaining_num_ingredients
|
min_raw = (remaining_raw - max_raw) / remaining_num_ingredients
|
||||||
max_energy = remaining_energy * 0.75
|
max_energy = remaining_energy * 0.75
|
||||||
min_energy = (remaining_energy - max_energy) / remaining_num_ingredients
|
min_energy = (remaining_energy - max_energy) / remaining_num_ingredients
|
||||||
ingredient = pool.pop()
|
|
||||||
if ingredient in all_product_sources:
|
|
||||||
ingredient_recipe = min(all_product_sources[ingredient], key=lambda recipe: recipe.rel_cost)
|
|
||||||
ingredient_raw = sum((count for ingredient, count in ingredient_recipe.base_cost.items()))
|
|
||||||
ingredient_energy = ingredient_recipe.total_energy
|
|
||||||
else:
|
|
||||||
# assume simple ore TODO: remove if tree when mining data is harvested from Factorio
|
|
||||||
ingredient_raw = 1
|
|
||||||
ingredient_energy = 2
|
|
||||||
min_num_raw = min_raw / ingredient_raw
|
min_num_raw = min_raw / ingredient_raw
|
||||||
max_num_raw = max_raw / ingredient_raw
|
max_num_raw = max_raw / ingredient_raw
|
||||||
min_num_energy = min_energy / ingredient_energy
|
min_num_energy = min_energy / ingredient_energy
|
||||||
|
@ -228,8 +231,6 @@ class Factorio(World):
|
||||||
if min_num > max_num:
|
if min_num > max_num:
|
||||||
fallback_pool.append(ingredient)
|
fallback_pool.append(ingredient)
|
||||||
continue # can't use that ingredient
|
continue # can't use that ingredient
|
||||||
if liquids_used == 2 and ingredient in liquids:
|
|
||||||
continue # can't use this ingredient as we already have a liquid in our recipe.
|
|
||||||
num = self.world.random.randint(min_num, max_num)
|
num = self.world.random.randint(min_num, max_num)
|
||||||
new_ingredients[ingredient] = num
|
new_ingredients[ingredient] = num
|
||||||
remaining_raw -= num * ingredient_raw
|
remaining_raw -= num * ingredient_raw
|
||||||
|
@ -246,6 +247,9 @@ class Factorio(World):
|
||||||
pool = fallback_pool
|
pool = fallback_pool
|
||||||
while remaining_num_ingredients > 0 and pool:
|
while remaining_num_ingredients > 0 and pool:
|
||||||
ingredient = pool.pop()
|
ingredient = pool.pop()
|
||||||
|
if liquids_used == allow_liquids and ingredient in liquids:
|
||||||
|
continue # can't use this ingredient as we already have maximum liquid in our recipe.
|
||||||
|
|
||||||
ingredient_recipe = recipes.get(ingredient, None)
|
ingredient_recipe = recipes.get(ingredient, None)
|
||||||
if not ingredient_recipe and ingredient.endswith("-barrel"):
|
if not ingredient_recipe and ingredient.endswith("-barrel"):
|
||||||
ingredient_recipe = recipes.get(f"fill-{ingredient}", None)
|
ingredient_recipe = recipes.get(f"fill-{ingredient}", None)
|
||||||
|
@ -257,9 +261,9 @@ class Factorio(World):
|
||||||
num_raw = remaining_raw / ingredient_raw / remaining_num_ingredients
|
num_raw = remaining_raw / ingredient_raw / remaining_num_ingredients
|
||||||
num_energy = remaining_energy / ingredient_energy / remaining_num_ingredients
|
num_energy = remaining_energy / ingredient_energy / remaining_num_ingredients
|
||||||
num = int(min(num_raw, num_energy))
|
num = int(min(num_raw, num_energy))
|
||||||
if num < 1: continue
|
if num < 1:
|
||||||
if liquids_used == 2 and ingredient in liquids:
|
continue
|
||||||
continue # can't use this ingredient as we already have a liquid in our recipe.
|
|
||||||
new_ingredients[ingredient] = num
|
new_ingredients[ingredient] = num
|
||||||
remaining_raw -= num * ingredient_raw
|
remaining_raw -= num * ingredient_raw
|
||||||
remaining_energy -= num * ingredient_energy
|
remaining_energy -= num * ingredient_energy
|
||||||
|
@ -343,12 +347,8 @@ class Factorio(World):
|
||||||
if self.world.max_science_pack[self.player].value == MaxSciencePack.option_space_science_pack:
|
if self.world.max_science_pack[self.player].value == MaxSciencePack.option_space_science_pack:
|
||||||
needed_recipes |= {"satellite"}
|
needed_recipes |= {"satellite"}
|
||||||
|
|
||||||
if any([recipe.category == "chemistry" for _, recipe in self.custom_recipes.items()]):
|
|
||||||
needed_recipes |= {"chemical-plant"}
|
|
||||||
|
|
||||||
for recipe in needed_recipes:
|
for recipe in needed_recipes:
|
||||||
recipe = self.custom_recipes.get(recipe, recipes[recipe])
|
recipe = self.custom_recipes.get(recipe, recipes[recipe])
|
||||||
self.advancement_technologies |= {tech.name for tech in recipe.unlocking_technologies}
|
|
||||||
self.advancement_technologies |= {tech.name for tech in recipe.recursive_unlocking_technologies}
|
self.advancement_technologies |= {tech.name for tech in recipe.recursive_unlocking_technologies}
|
||||||
|
|
||||||
# handle marking progressive techs as advancement
|
# handle marking progressive techs as advancement
|
||||||
|
|
Loading…
Reference in New Issue