From 07866bbd3c046d20aff6d49873efbd66af71f226 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Wed, 3 Feb 2021 06:55:08 +0100 Subject: [PATCH] Speed up Playthrough creation --- Main.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/Main.py b/Main.py index f38e7992..a2c69a62 100644 --- a/Main.py +++ b/Main.py @@ -605,11 +605,11 @@ def create_playthrough(world): while sphere_candidates: state.sweep_for_events(key_only=True) - sphere = [] + sphere = set() # build up spheres of collection radius. Everything in each sphere is independent from each other in dependencies and only depends on lower spheres for location in sphere_candidates: if state.can_reach(location): - sphere.append(location) + sphere.add(location) for location in sphere: sphere_candidates.remove(location) @@ -634,21 +634,20 @@ def create_playthrough(world): # in the second phase, we cull each sphere such that the game is still beatable, reducing each range of influence to the bare minimum required inside it for num, sphere in reversed(list(enumerate(collection_spheres))): - to_delete = [] + to_delete = set() for location in sphere: # we remove the item at location and check if game is still beatable logging.getLogger('').debug('Checking if %s (Player %d) is required to beat the game.', location.item.name, location.item.player) old_item = location.item location.item = None if world.can_beat_game(state_cache[num]): - to_delete.append(location) + to_delete.add(location) else: # still required, got to keep it around location.item = old_item # cull entries in spheres for spoiler walkthrough at end - for location in to_delete: - sphere.remove(location) + sphere -= to_delete # second phase, sphere 0 for item in [i for i in world.precollected_items if i.advancement]: @@ -664,7 +663,7 @@ def create_playthrough(world): # used to access it was deemed not required.) So we need to do one final sphere collection pass # to build up the correct spheres - required_locations = [item for sphere in collection_spheres for item in sphere] + required_locations = {item for sphere in collection_spheres for item in sphere} state = CollectionState(world) collection_spheres = [] while required_locations: @@ -682,9 +681,6 @@ def create_playthrough(world): if not sphere: raise RuntimeError('Not all required items reachable. Something went terribly wrong here.') - # store the required locations for statistical analysis - old_world.required_locations = [(location.name, location.player) for sphere in collection_spheres for location in sphere] - def flist_to_iter(node): while node: value, node = node @@ -701,7 +697,7 @@ def create_playthrough(world): old_world.spoiler.paths = dict() for player in range(1, world.players + 1): old_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}) - for _, path in dict(old_world.spoiler.paths).items(): + for path in dict(old_world.spoiler.paths).values(): if any(exit == 'Pyramid Fairy' for (_, exit) in path): if world.mode[player] != 'inverted': old_world.spoiler.paths[str(world.get_region('Big Bomb Shop', player))] = get_path(state, world.get_region('Big Bomb Shop', player)) @@ -709,6 +705,6 @@ def create_playthrough(world): old_world.spoiler.paths[str(world.get_region('Inverted Big Bomb Shop', player))] = get_path(state, world.get_region('Inverted Big Bomb Shop', player)) # we can finally output our playthrough - old_world.spoiler.playthrough = OrderedDict([("0", [str(item) for item in world.precollected_items if item.advancement])]) + old_world.spoiler.playthrough = {"0": {str(item) for item in world.precollected_items if item.advancement}} for i, sphere in enumerate(collection_spheres): old_world.spoiler.playthrough[str(i + 1)] = {str(location): str(location.item) for location in sphere}