Improve small key placement algorithm to be able to handle more world shuffles without falsly claiming impossible scenarios.

This commit is contained in:
LLCoolDave 2017-08-05 17:51:38 +02:00
parent 52835bba5c
commit 271571d01e
1 changed files with 19 additions and 8 deletions

View File

@ -25,13 +25,11 @@ def fill_dungeons(world):
world.get_location('[dungeon-D3-B1] Skull Woods - South of Big Chest').event = True world.get_location('[dungeon-D3-B1] Skull Woods - South of Big Chest').event = True
dungeons = [TR, ES, EP, DP, ToH, AT, PoD, TT, SW, IP, MM, GT, SP] dungeons = [TR, ES, EP, DP, ToH, AT, PoD, TT, SW, IP, MM, GT, SP]
for dungeon in dungeons:
if world.get_entrance('Ganons Tower').connected_region.name in dungeon[0]:
dungeons.pop(dungeons.index(dungeon))
dungeons.append(dungeon)
break
for dungeon_regions, big_key, small_keys, dungeon_items in dungeons: loopcnt = 0
while dungeons:
loopcnt += 1
dungeon_regions, big_key, small_keys, dungeon_items = dungeons.pop(0)
# this is what we need to fill # this is what we need to fill
dungeon_locations = [location for location in world.get_unfilled_locations() if location.parent_region.name in dungeon_regions] dungeon_locations = [location for location in world.get_unfilled_locations() if location.parent_region.name in dungeon_regions]
random.shuffle(dungeon_locations) random.shuffle(dungeon_locations)
@ -53,9 +51,11 @@ def fill_dungeons(world):
bk_location.event = True bk_location.event = True
dungeon_locations.remove(bk_location) dungeon_locations.remove(bk_location)
all_state._clear_cache() all_state._clear_cache()
big_key = None
# next place small keys # next place small keys
for small_key in small_keys: while small_keys:
small_key = small_keys.pop()
all_state.sweep_for_events() all_state.sweep_for_events()
sk_location = None sk_location = None
for location in dungeon_locations: for location in dungeon_locations:
@ -64,6 +64,13 @@ def fill_dungeons(world):
break break
if sk_location is None: if sk_location is None:
# need to retry this later
small_keys.append(small_key)
dungeons.append((dungeon_regions, big_key, small_keys, dungeon_items))
# infinite regression protection
if loopcnt < 30:
break
else:
raise RuntimeError('No suitable location for %s' % small_key) raise RuntimeError('No suitable location for %s' % small_key)
world.push_item(sk_location, small_key, False) world.push_item(sk_location, small_key, False)
@ -71,6 +78,10 @@ def fill_dungeons(world):
dungeon_locations.remove(sk_location) dungeon_locations.remove(sk_location)
all_state._clear_cache() all_state._clear_cache()
if small_keys:
# key placement not finished, loop again
continue
# next place dungeon items # next place dungeon items
if world.place_dungeon_items: if world.place_dungeon_items:
for dungeon_item in dungeon_items: for dungeon_item in dungeon_items: