Some optimizations

This commit is contained in:
Fabian Dill 2021-07-09 17:44:24 +02:00
parent 2600e9a805
commit 4c7ef593be
4 changed files with 105 additions and 89 deletions

View File

@ -672,11 +672,12 @@ def create_playthrough(world):
pathpairs = zip_longest(pathsiter, pathsiter)
return list(pathpairs)
world.spoiler.paths = dict()
for player in range(1, world.players + 1):
world.spoiler.paths = {}
topology_worlds = (player for player in world.player_ids if world.worlds[player].topology_present)
for player in topology_worlds:
world.spoiler.paths.update(
{str(location): get_path(state, location.parent_region) for sphere in collection_spheres for location in
sphere if location.player == player and world.worlds[player].topology_present})
sphere if location.player == player})
if player in world.alttp_player_ids:
for path in dict(world.spoiler.paths).values():
if any(exit == 'Pyramid Fairy' for (_, exit) in path):

142
Utils.py
View File

@ -69,6 +69,21 @@ def parse_player_names(names, players, teams):
return ret
def cache_argsless(function):
if function.__code__.co_argcount:
raise Exception("Can only cache 0 argument functions with this cache.")
result = sentinel = object()
def _wrap():
nonlocal result
if result is sentinel:
result = function()
return result
return _wrap
def is_bundled() -> bool:
return getattr(sys, 'frozen', False)
@ -132,7 +147,7 @@ def close_console():
parse_yaml = safe_load
unsafe_parse_yaml = functools.partial(load, Loader=Loader)
@cache_argsless
def get_public_ipv4() -> str:
import socket
import urllib.request
@ -148,7 +163,7 @@ def get_public_ipv4() -> str:
pass # we could be offline, in a local game, so no point in erroring out
return ip
@cache_argsless
def get_public_ipv6() -> str:
import socket
import urllib.request
@ -161,70 +176,68 @@ def get_public_ipv6() -> str:
pass # we could be offline, in a local game, or ipv6 may not be available
return ip
@cache_argsless
def get_default_options() -> dict:
if not hasattr(get_default_options, "options"):
# Refer to host.yaml for comments as to what all these options mean.
options = {
"general_options": {
"output_path": "output",
},
"factorio_options": {
"executable": "factorio\\bin\\x64\\factorio",
},
"lttp_options": {
"rom_file": "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc",
"sni": "SNI",
"rom_start": True,
# Refer to host.yaml for comments as to what all these options mean.
options = {
"general_options": {
"output_path": "output",
},
"factorio_options": {
"executable": "factorio\\bin\\x64\\factorio",
},
"lttp_options": {
"rom_file": "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc",
"sni": "SNI",
"rom_start": True,
},
"server_options": {
"host": None,
"port": 38281,
"password": None,
"multidata": None,
"savefile": None,
"disable_save": False,
"loglevel": "info",
"server_password": None,
"disable_item_cheat": False,
"location_check_points": 1,
"hint_cost": 10,
"forfeit_mode": "goal",
"remaining_mode": "goal",
"auto_shutdown": 0,
"compatibility": 2,
"log_network": 0
},
"multi_mystery_options": {
"teams": 1,
"enemizer_path": "EnemizerCLI/EnemizerCLI.Core.exe",
"player_files_path": "Players",
"players": 0,
"weights_file_path": "weights.yaml",
"meta_file_path": "meta.yaml",
"pre_roll": False,
"create_spoiler": 1,
"zip_roms": 0,
"zip_diffs": 2,
"zip_apmcs": 1,
"zip_spoiler": 0,
"zip_multidata": 1,
"zip_format": 1,
"glitch_triforce_room": 1,
"race": 0,
"cpu_threads": 0,
"max_attempts": 0,
"take_first_working": False,
"keep_all_seeds": False,
"log_output_path": "Output Logs",
"log_level": None,
"plando_options": "bosses",
}
},
"server_options": {
"host": None,
"port": 38281,
"password": None,
"multidata": None,
"savefile": None,
"disable_save": False,
"loglevel": "info",
"server_password": None,
"disable_item_cheat": False,
"location_check_points": 1,
"hint_cost": 10,
"forfeit_mode": "goal",
"remaining_mode": "goal",
"auto_shutdown": 0,
"compatibility": 2,
"log_network": 0
},
"multi_mystery_options": {
"teams": 1,
"enemizer_path": "EnemizerCLI/EnemizerCLI.Core.exe",
"player_files_path": "Players",
"players": 0,
"weights_file_path": "weights.yaml",
"meta_file_path": "meta.yaml",
"pre_roll": False,
"create_spoiler": 1,
"zip_roms": 0,
"zip_diffs": 2,
"zip_apmcs": 1,
"zip_spoiler": 0,
"zip_multidata": 1,
"zip_format": 1,
"glitch_triforce_room": 1,
"race": 0,
"cpu_threads": 0,
"max_attempts": 0,
"take_first_working": False,
"keep_all_seeds": False,
"log_output_path": "Output Logs",
"log_level": None,
"plando_options": "bosses",
}
}
get_default_options.options = options
return get_default_options.options
return options
blacklisted_options = {"multi_mystery_options.cpu_threads",
@ -254,7 +267,7 @@ def update_options(src: dict, dest: dict, filename: str, keys: list) -> dict:
dest[key] = update_options(value, dest[key], filename, new_keys)
return dest
@cache_argsless
def get_options() -> dict:
if not hasattr(get_options, "options"):
locations = ("options.yaml", "host.yaml",
@ -368,7 +381,7 @@ def get_adjuster_settings(romfile: str) -> typing.Tuple[str, bool]:
return romfile, adjusted
return romfile, False
@cache_argsless
def get_unique_identifier():
uuid = persistent_load().get("client", {}).get("uuid", None)
if uuid:
@ -407,6 +420,7 @@ def restricted_loads(s):
"""Helper function analogous to pickle.loads()."""
return RestrictedUnpickler(io.BytesIO(s)).load()
class KeyedDefaultDict(collections.defaultdict):
def __missing__(self, key):
self[key] = value = self.default_factory(key)

View File

@ -393,27 +393,27 @@ rel_cost = {
blacklist = all_ingredient_names | {"rocket-part", "crude-oil", "water", "sulfuric-acid", "petroleum-gas", "light-oil",
"heavy-oil", "lubricant", "steam"}
@Utils.cache_argsless
def get_science_pack_pools() -> Dict[str, Set[str]]:
def get_estimated_difficulty(recipe: Recipe):
base_ingredients = recipe.base_cost
cost = 0
def get_estimated_difficulty(recipe: Recipe):
base_ingredients = recipe.base_cost
cost = 0
for ingredient_name, amount in base_ingredients.items():
if ingredient_name not in rel_cost:
raise Exception((recipe.name, ingredient_name))
cost += rel_cost.get(ingredient_name, 1) * amount
return cost
for ingredient_name, amount in base_ingredients.items():
cost += rel_cost.get(ingredient_name, 1) * amount
return cost
science_pack_pools = {}
already_taken = blacklist.copy()
current_difficulty = 5
for science_pack in Options.MaxSciencePack.get_ordered_science_packs():
current = science_pack_pools[science_pack] = set()
for name, recipe in recipes.items():
if (science_pack != "automation-science-pack" or not recipe.recursive_unlocking_technologies) \
and get_estimated_difficulty(recipe) < current_difficulty:
current |= set(recipe.products)
current -= already_taken
already_taken |= current
current_difficulty *= 2
science_pack_pools = {}
already_taken = blacklist.copy()
current_difficulty = 5
for science_pack in Options.MaxSciencePack.get_ordered_science_packs():
current = science_pack_pools[science_pack] = set()
for name, recipe in recipes.items():
if (science_pack != "automation-science-pack" or not recipe.recursive_unlocking_technologies) \
and get_estimated_difficulty(recipe) < current_difficulty:
current |= set(recipe.products)
current -= already_taken
already_taken |= current
current_difficulty *= 2
return science_pack_pools

View File

@ -4,7 +4,7 @@ from BaseClasses import Region, Entrance, Location, Item
from .Technologies import base_tech_table, recipe_sources, base_technology_table, advancement_technologies, \
all_ingredient_names, required_technologies, get_rocket_requirements, rocket_recipes, \
progressive_technology_table, common_tech_table, tech_to_progressive_lookup, progressive_tech_table, \
science_pack_pools, Recipe, recipes, technology_table
get_science_pack_pools, Recipe, recipes, technology_table
from .Shapes import get_shapes
from .Mod import generate_mod
from .Options import factorio_options
@ -127,6 +127,7 @@ class Factorio(World):
def set_custom_recipes(self):
original_rocket_part = recipes["rocket-part"]
science_pack_pools = get_science_pack_pools()
valid_pool = sorted(science_pack_pools[self.world.max_science_pack[self.player].get_max_pack()])
self.world.random.shuffle(valid_pool)
self.custom_recipes = {"rocket-part": Recipe("rocket-part", original_rocket_part.category,