Strict and Partial key logic implementations with new test suite utility

This commit is contained in:
aerinon
2023-02-17 10:07:43 -07:00
parent 2b8b9156d9
commit d7c15ae22c
17 changed files with 512 additions and 24 deletions

64
Fill.py
View File

@@ -105,6 +105,8 @@ def fill_restrictive(world, base_state, locations, itempool, key_pool=None, sing
spot_to_fill = None
item_locations = filter_locations(item_to_place, locations, world, vanilla)
verify(item_to_place, item_locations, maximum_exploration_state, single_player_placement,
perform_access_check, key_pool, world)
for location in item_locations:
spot_to_fill = verify_spot_to_fill(location, item_to_place, maximum_exploration_state,
single_player_placement, perform_access_check, key_pool, world)
@@ -128,9 +130,6 @@ def fill_restrictive(world, base_state, locations, itempool, key_pool=None, sing
raise FillError('No more spots to place %s' % item_to_place)
world.push_item(spot_to_fill, item_to_place, False)
if item_to_place.smallkey:
with suppress(ValueError):
key_pool.remove(item_to_place)
track_outside_keys(item_to_place, spot_to_fill, world)
track_dungeon_items(item_to_place, spot_to_fill, world)
locations.remove(spot_to_fill)
@@ -144,6 +143,9 @@ def verify_spot_to_fill(location, item_to_place, max_exp_state, single_player_pl
if item_to_place.smallkey or item_to_place.bigkey: # a better test to see if a key can go there
location.item = item_to_place
location.event = True
if item_to_place.smallkey:
with suppress(ValueError):
key_pool.remove(item_to_place)
test_state = max_exp_state.copy()
test_state.stale[item_to_place.player] = True
else:
@@ -157,6 +159,8 @@ def verify_spot_to_fill(location, item_to_place, max_exp_state, single_player_pl
if item_to_place.smallkey or item_to_place.bigkey:
location.item = None
location.event = False
if item_to_place.smallkey:
key_pool.append(item_to_place)
return None
@@ -394,11 +398,7 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
random.shuffle(fill_locations)
random.shuffle(world.itempool)
if world.item_pool_config.preferred:
pref = list(world.item_pool_config.preferred.keys())
pref_len = len(pref)
world.itempool.sort(key=lambda i: pref_len - pref.index((i.name, i.player))
if (i.name, i.player) in world.item_pool_config.preferred else 0)
config_sort(world)
progitempool = [item for item in world.itempool if item.advancement]
prioitempool = [item for item in world.itempool if not item.advancement and item.priority]
restitempool = [item for item in world.itempool if not item.advancement and not item.priority]
@@ -496,6 +496,20 @@ def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None
ensure_good_pots(world)
def config_sort(world):
if world.item_pool_config.verify:
config_sort_helper(world, world.item_pool_config.verify)
elif world.item_pool_config.preferred:
config_sort_helper(world, world.item_pool_config.preferred)
def config_sort_helper(world, sort_dict):
pref = list(sort_dict.keys())
pref_len = len(pref)
world.itempool.sort(key=lambda i: pref_len - pref.index((i.name, i.player))
if (i.name, i.player) in sort_dict else 0)
def calc_trash_locations(world, player):
total_count, gt_count = 0, 0
for loc in world.get_locations():
@@ -667,6 +681,40 @@ def sell_keys(world, player):
world.itempool.remove(universal_key)
def verify(item_to_place, item_locations, state, spp, pac, key_pool, world):
if world.item_pool_config.verify:
logger = logging.getLogger('')
item_name = 'Bottle' if item_to_place.name.startswith('Bottle') else item_to_place.name
item_player = item_to_place.player
config = world.item_pool_config
if (item_name, item_player) in config.verify:
tests = config.verify[(item_name, item_player)]
issues = []
for location in item_locations:
if location.name in tests:
expected = tests[location.name]
spot = verify_spot_to_fill(location, item_to_place, state, spp, pac, key_pool, world)
if spot and (item_to_place.smallkey or item_to_place.bigkey):
location.item = None
location.event = False
if item_to_place.smallkey:
key_pool.append(item_to_place)
if (expected and spot) or (not expected and spot is None):
logger.debug(f'Placing {item_name} ({item_player}) at {location.name} was {expected}')
config.verify_count += 1
if config.verify_count >= config.verify_target:
exit()
else:
issues.append((item_name, item_player, location.name, expected))
if len(issues) > 0:
for name, player, loc, expected in issues:
if expected:
logger.error(f'Could not place {name} ({player}) at {loc}')
else:
logger.error(f'{name} ({player}) should not be allowed at {loc}')
raise Exception(f'Test failed placing {name}')
def balance_multiworld_progression(world):
state = CollectionState(world)
checked_locations = set()