Speed up restrictive_fill a bit.
This also changes behaviour slightly; it used to fill beatable only players' items first, now it shuffles it all together. It is not documented why this was done, so hopefully this doesn't undo something intentional.
This commit is contained in:
parent
ae72fa1561
commit
bbe51c4cc7
32
Fill.py
32
Fill.py
|
@ -24,48 +24,46 @@ def fill_restrictive(world, base_state: CollectionState, locations, itempool, si
|
||||||
unplaced_items = []
|
unplaced_items = []
|
||||||
placements = []
|
placements = []
|
||||||
|
|
||||||
no_access_checks = {}
|
|
||||||
reachable_items = {}
|
reachable_items = {}
|
||||||
for item in itempool:
|
for item in itempool:
|
||||||
if world.accessibility[item.player] == 'none':
|
|
||||||
no_access_checks.setdefault(item.player, []).append(item)
|
|
||||||
else:
|
|
||||||
reachable_items.setdefault(item.player, []).append(item)
|
reachable_items.setdefault(item.player, []).append(item)
|
||||||
|
|
||||||
for player_items in [no_access_checks, reachable_items]:
|
while any(reachable_items.values()) and locations:
|
||||||
while any(player_items.values()) and locations:
|
items_to_place = [items.pop() for items in reachable_items.values() if items] # grab one item per player
|
||||||
items_to_place = [[itempool.remove(items[-1]), items.pop()][-1] for items in player_items.values() if items]
|
for item in items_to_place:
|
||||||
|
itempool.remove(item)
|
||||||
maximum_exploration_state = sweep_from_pool()
|
maximum_exploration_state = sweep_from_pool()
|
||||||
has_beaten_game = world.has_beaten_game(maximum_exploration_state)
|
has_beaten_game = world.has_beaten_game(maximum_exploration_state)
|
||||||
|
|
||||||
for item_to_place in items_to_place:
|
for item_to_place in items_to_place:
|
||||||
perform_access_check = True
|
|
||||||
if world.accessibility[item_to_place.player] == 'none':
|
if world.accessibility[item_to_place.player] == 'none':
|
||||||
perform_access_check = not world.has_beaten_game(maximum_exploration_state,
|
perform_access_check = not world.has_beaten_game(maximum_exploration_state,
|
||||||
item_to_place.player) if single_player_placement else not has_beaten_game
|
item_to_place.player) if single_player_placement else not has_beaten_game
|
||||||
for location in locations:
|
else:
|
||||||
|
perform_access_check = True
|
||||||
|
|
||||||
|
for i, location in enumerate(locations):
|
||||||
if (not single_player_placement or location.player == item_to_place.player) \
|
if (not single_player_placement or location.player == item_to_place.player) \
|
||||||
and location.can_fill(maximum_exploration_state, item_to_place, perform_access_check):
|
and location.can_fill(maximum_exploration_state, item_to_place, perform_access_check):
|
||||||
spot_to_fill = location
|
spot_to_fill = locations.pop(i) # poping by index is faster than removing by content,
|
||||||
|
# skipping a scan for the element
|
||||||
break
|
break
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
# fill in name of world for item
|
||||||
|
item_to_place.world = world
|
||||||
# we filled all reachable spots. Maybe the game can be beaten anyway?
|
# we filled all reachable spots. Maybe the game can be beaten anyway?
|
||||||
unplaced_items.insert(0, item_to_place)
|
unplaced_items.append(item_to_place)
|
||||||
if world.accessibility[item_to_place.player] != 'none' and world.can_beat_game():
|
if world.accessibility[item_to_place.player] != 'none' and world.can_beat_game():
|
||||||
logging.warning(
|
logging.warning(
|
||||||
f'Not all items placed. Game beatable anyway. (Could not place {item_to_place})')
|
f'Not all items placed. Game beatable anyway. (Could not place {item_to_place})')
|
||||||
continue
|
continue
|
||||||
# fill in name of world for item
|
|
||||||
item_to_place.world = world
|
|
||||||
raise FillError(f'No more spots to place {item_to_place}, locations {locations} are invalid. '
|
raise FillError(f'No more spots to place {item_to_place}, locations {locations} are invalid. '
|
||||||
f'Already placed {len(placements)}: {", ".join(str(place) for place in placements)}')
|
f'Already placed {len(placements)}: {", ".join(str(place) for place in placements)}')
|
||||||
|
|
||||||
world.push_item(spot_to_fill, item_to_place, False)
|
world.push_item(spot_to_fill, item_to_place, False)
|
||||||
if lock:
|
spot_to_fill.locked = lock
|
||||||
spot_to_fill.locked = True
|
|
||||||
locations.remove(spot_to_fill)
|
|
||||||
placements.append(spot_to_fill)
|
placements.append(spot_to_fill)
|
||||||
spot_to_fill.event = True
|
spot_to_fill.event = True
|
||||||
|
|
||||||
|
|
2
Gui.py
2
Gui.py
|
@ -404,7 +404,7 @@ def guiMain(args=None):
|
||||||
guiargs.red_clock_time = timerRedVar.get()
|
guiargs.red_clock_time = timerRedVar.get()
|
||||||
guiargs.blue_clock_time = timerBlueVar.get()
|
guiargs.blue_clock_time = timerBlueVar.get()
|
||||||
guiargs.green_clock_time = timerGreenVar.get()
|
guiargs.green_clock_time = timerGreenVar.get()
|
||||||
guiargs.skip_progression_balancing = not balancingVar.get()
|
guiargs.progression_balancing = balancingVar.get()
|
||||||
if guiargs.timer == "none":
|
if guiargs.timer == "none":
|
||||||
guiargs.timer = False
|
guiargs.timer = False
|
||||||
guiargs.dungeon_counters = dungeonCounterVar.get()
|
guiargs.dungeon_counters = dungeonCounterVar.get()
|
||||||
|
|
|
@ -526,9 +526,8 @@ def fill_prizes(world, attempts=15):
|
||||||
empty_crystal_locations = [loc for loc in crystal_locations if not loc.item]
|
empty_crystal_locations = [loc for loc in crystal_locations if not loc.item]
|
||||||
for attempt in range(attempts):
|
for attempt in range(attempts):
|
||||||
try:
|
try:
|
||||||
prizepool = list(unplaced_prizes)
|
prizepool = unplaced_prizes.copy()
|
||||||
prize_locs = list(empty_crystal_locations)
|
prize_locs = empty_crystal_locations.copy()
|
||||||
world.random.shuffle(prizepool)
|
|
||||||
world.random.shuffle(prize_locs)
|
world.random.shuffle(prize_locs)
|
||||||
fill_restrictive(world, all_state, prize_locs, prizepool, True, lock=True)
|
fill_restrictive(world, all_state, prize_locs, prizepool, True, lock=True)
|
||||||
except FillError as e:
|
except FillError as e:
|
||||||
|
|
Loading…
Reference in New Issue