Replace world exploration with a faster algorithm - use BFS and keep track of all entrances that are currently blocked by progression items.

New algorithm also obsoletes sweep_for_crystal_access
Set up door and entrance caches in advance
Replace CrystalBarrier with FastEnum for bitfield arithmetic
This commit is contained in:
compiling
2020-05-10 19:27:13 +10:00
parent cf70210ed1
commit 1217236621
8 changed files with 157 additions and 154 deletions

View File

@@ -370,7 +370,6 @@ def copy_world(world):
create_inverted_regions(ret, player)
create_dungeon_regions(ret, player)
create_shops(ret, player)
create_doors(ret, player)
create_rooms(ret, player)
create_dungeons(ret, player)
@@ -417,6 +416,10 @@ def copy_world(world):
ret.state.stale = {player: True for player in range(1, world.players + 1)}
ret.doors = world.doors
for door in ret.doors:
entrance = ret.check_for_entrance(door.name, door.player)
if entrance is not None:
entrance.door = door
ret.paired_doors = world.paired_doors
ret.rooms = world.rooms
ret.inaccessible_regions = world.inaccessible_regions
@@ -468,7 +471,6 @@ def create_playthrough(world):
logging.getLogger('').debug(world.fish.translate("cli","cli","building.collection.spheres"))
while sphere_candidates:
state.sweep_for_events(key_only=True)
state.sweep_for_crystal_access()
sphere = []
# build up spheres of collection radius. Everything in each sphere is independent from each other in dependencies and only depends on lower spheres
@@ -486,7 +488,7 @@ def create_playthrough(world):
logging.getLogger('').debug(world.fish.translate("cli","cli","building.calculating.spheres"), len(collection_spheres), len(sphere), len(prog_locations))
if not sphere:
logging.getLogger('').debug(world.fish.translate("cli","cli","cannot.reach.items"), [world.fish.translate("cli","cli","cannot.reach.item") % (location.item.name, location.item.player, location.name, location.player) for location in sphere_candidates])
logging.getLogger('').error(world.fish.translate("cli","cli","cannot.reach.items"), [world.fish.translate("cli","cli","cannot.reach.item") % (location.item.name, location.item.player, location.name, location.player) for location in sphere_candidates])
if any([world.accessibility[location.item.player] != 'none' for location in sphere_candidates]):
raise RuntimeError(world.fish.translate("cli","cli","cannot.reach.progression"))
else:
@@ -530,7 +532,6 @@ def create_playthrough(world):
collection_spheres = []
while required_locations:
state.sweep_for_events(key_only=True)
state.sweep_for_crystal_access()
sphere = list(filter(lambda loc: state.can_reach(loc) and state.not_flooding_a_key(world, loc), required_locations))