From 4c0c8ea21aef86f5e04d7cc31f50ed2a09437764 Mon Sep 17 00:00:00 2001 From: aerinon Date: Wed, 22 Jan 2020 12:35:13 -0700 Subject: [PATCH] Key and crystal sweep fixes --- BaseClasses.py | 5 ++++- KeyDoorShuffle.py | 11 ++++++----- Main.py | 6 +++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 032df900..db6659fe 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -429,6 +429,7 @@ class CollectionState(object): door = self.world.check_for_door(ext.name, player) if door is not None and door.crystal == CrystalBarrier.Either: c_switch_present = True + break if c_switch_present: ccr[candidate] = CrystalBarrier.Either self.spread_crystal_access(candidate, CrystalBarrier.Either, rrp, ccr, player) @@ -543,6 +544,8 @@ class CollectionState(object): self.collect(event.item, True, event) new_locations = len(reachable_events) > checked_locations checked_locations = len(reachable_events) + if new_locations: + self.sweep_for_crystal_access() def can_reach_blue(self, region, player): if region not in self.colored_regions[player].keys(): @@ -773,9 +776,9 @@ class CollectionState(object): self.stale[item.player] = True if changed: - # self.sweep_for_crystal_access(item.player) if not event: self.sweep_for_events() + self.sweep_for_crystal_access() def remove(self, item): if item.advancement: diff --git a/KeyDoorShuffle.py b/KeyDoorShuffle.py index bafed982..311c7077 100644 --- a/KeyDoorShuffle.py +++ b/KeyDoorShuffle.py @@ -360,7 +360,7 @@ def create_rule(key_counter, prev_counter, key_layout, world, player): adj_chest_keys = min(chest_keys, required_keys) needed_chests = required_keys - len(key_counter.key_only_locations) is_valid = needed_chests <= chest_keys - unneeded_chests = min(key_gain, adj_chest_keys - needed_chests) + unneeded_chests = min(key_gain, max(0, adj_chest_keys - needed_chests)) rule_num = required_keys - unneeded_chests return DoorRules(rule_num, is_valid) @@ -469,7 +469,7 @@ def bk_restricted_rules(rule, door, odd_counter, empty_flag, key_counter, key_la return best_counter = find_best_counter(door, odd_counter, key_counter, key_layout, world, player, True, empty_flag) bk_rule = create_rule(best_counter, key_counter, key_layout, world, player) - if bk_rule.is_valid and bk_rule.small_key_num == rule.small_key_num: + if bk_rule.small_key_num >= rule.small_key_num: return door_open = find_next_counter(door, best_counter, key_layout) ignored_doors = dict_intersection(best_counter.child_doors, door_open.child_doors) @@ -827,7 +827,7 @@ def validate_key_layout_sub_loop(key_layout, state, checked_states, flat_proposa # todo: fix state to separate out these types ttl_locations = count_free_locations(state) if state.big_key_opened else count_locations_exclude_big_chest(state) ttl_key_only = count_key_only_locations(state) - available_small_locations = cnt_avail_small_locations(ttl_locations + ttl_key_only, state, world, player) + available_small_locations = cnt_avail_small_locations(ttl_locations, ttl_key_only, state, world, player) available_big_locations = cnt_avail_big_locations(ttl_locations, state, world, player) if (not smalls_avail or available_small_locations == 0) and (state.big_key_opened or num_bigs == 0 or available_big_locations == 0): return False @@ -862,9 +862,10 @@ def validate_key_layout_sub_loop(key_layout, state, checked_states, flat_proposa return True -def cnt_avail_small_locations(ttl_locations, state, world, player): +def cnt_avail_small_locations(free_locations, key_only, state, world, player): if not world.keyshuffle[player] and not world.retro[player]: - return min(ttl_locations - state.used_locations, state.key_locations - state.used_smalls) + avail_chest_keys = min(free_locations - state.used_locations, state.key_locations - key_only) + return max(0, avail_chest_keys + key_only - state.used_smalls) return state.key_locations - state.used_smalls diff --git a/Main.py b/Main.py index 51787ea6..f9d61c2a 100644 --- a/Main.py +++ b/Main.py @@ -23,7 +23,7 @@ from Fill import distribute_items_cutoff, distribute_items_staleness, distribute from ItemList import generate_itempool, difficulties, fill_prizes from Utils import output_path, parse_player_names -__version__ = '0.0.3-pre' +__version__ = '0.0.4-pre' def main(args, seed=None): if args.outputpath: @@ -385,7 +385,7 @@ def create_playthrough(world): logging.getLogger('').debug('Building up collection spheres.') while sphere_candidates: state.sweep_for_events(key_only=True) - # state.sweep_for_crystal_access() + 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 @@ -447,7 +447,7 @@ def create_playthrough(world): collection_spheres = [] while required_locations: state.sweep_for_events(key_only=True) - # state.sweep_for_crystal_access() + state.sweep_for_crystal_access() sphere = list(filter(lambda loc: state.can_reach(loc) and state.not_flooding_a_key(world, loc), required_locations))