Some optimizations
This commit is contained in:
parent
2600e9a805
commit
4c7ef593be
7
Main.py
7
Main.py
|
@ -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
142
Utils.py
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue