Remove old fill algorithms that I have no intention to optimize or support in the future
This commit is contained in:
parent
6d38e87527
commit
d86eb69b4c
|
@ -972,7 +972,6 @@ class Location(object):
|
|||
self.spot_type = 'Location'
|
||||
self.hint_text: str = hint_text if hint_text else name
|
||||
self.recursion_count = 0
|
||||
self.staleness_count = 0
|
||||
self.event = False
|
||||
self.locked = False
|
||||
self.always_allow = lambda item, state: False
|
||||
|
|
|
@ -155,7 +155,8 @@ def parse_arguments(argv, no_defaults=False):
|
|||
category, be randomly progressive or not.
|
||||
Link will die in one hit.
|
||||
''')
|
||||
parser.add_argument('--algorithm', default=defval('balanced'), const='balanced', nargs='?', choices=['freshness', 'flood', 'vt21', 'vt22', 'vt25', 'vt26', 'balanced'],
|
||||
parser.add_argument('--algorithm', default=defval('balanced'), const='balanced', nargs='?',
|
||||
choices=['freshness', 'flood', 'vt25', 'vt26', 'balanced'],
|
||||
help='''\
|
||||
Select item filling algorithm. (default: %(default)s
|
||||
balanced: vt26 derivitive that aims to strike a balance between
|
||||
|
@ -166,14 +167,6 @@ def parse_arguments(argv, no_defaults=False):
|
|||
dungeon keys and items.
|
||||
vt25: Shuffle items and place them in a random location
|
||||
that it is not impossible to be in.
|
||||
vt21: Unbiased in its selection, but has tendency to put
|
||||
Ice Rod in Turtle Rock.
|
||||
vt22: Drops off stale locations after 1/3 of progress
|
||||
items were placed to try to circumvent vt21\'s
|
||||
shortcomings.
|
||||
Freshness: Keep track of stale locations (ones that cannot be
|
||||
reached yet) and decrease likeliness of selecting
|
||||
them the more often they were found unreachable.
|
||||
Flood: Push out items starting from Link\'s House and
|
||||
slightly biased to placing progression items with
|
||||
less restrictions.
|
||||
|
|
154
Fill.py
154
Fill.py
|
@ -7,160 +7,6 @@ from BaseClasses import CollectionState
|
|||
class FillError(RuntimeError):
|
||||
pass
|
||||
|
||||
def distribute_items_cutoff(world, cutoffrate=0.33):
|
||||
# get list of locations to fill in
|
||||
fill_locations = world.get_unfilled_locations()
|
||||
world.random.shuffle(fill_locations)
|
||||
|
||||
# get items to distribute
|
||||
world.random.shuffle(world.itempool)
|
||||
itempool = world.itempool
|
||||
|
||||
total_advancement_items = len([item for item in itempool if item.advancement])
|
||||
placed_advancement_items = 0
|
||||
|
||||
progress_done = False
|
||||
advancement_placed = False
|
||||
|
||||
# sweep once to pick up preplaced items
|
||||
world.state.sweep_for_events()
|
||||
|
||||
while itempool and fill_locations:
|
||||
candidate_item_to_place = None
|
||||
item_to_place = None
|
||||
for item in itempool:
|
||||
if advancement_placed or (progress_done and (item.advancement or item.priority)):
|
||||
item_to_place = item
|
||||
break
|
||||
if item.advancement:
|
||||
candidate_item_to_place = item
|
||||
if world.unlocks_new_location(item):
|
||||
item_to_place = item
|
||||
placed_advancement_items += 1
|
||||
break
|
||||
|
||||
if item_to_place is None:
|
||||
# check if we can reach all locations and that is why we find no new locations to place
|
||||
if not progress_done and len(world.get_reachable_locations()) == len(world.get_locations()):
|
||||
progress_done = True
|
||||
continue
|
||||
# check if we have now placed all advancement items
|
||||
if progress_done:
|
||||
advancement_placed = True
|
||||
continue
|
||||
# we might be in a situation where all new locations require multiple items to reach. If that is the case, just place any advancement item we've found and continue trying
|
||||
if candidate_item_to_place is not None:
|
||||
item_to_place = candidate_item_to_place
|
||||
placed_advancement_items += 1
|
||||
else:
|
||||
# we placed all available progress items. Maybe the game can be beaten anyway?
|
||||
if world.can_beat_game():
|
||||
logging.getLogger('').warning('Not all locations reachable. Game beatable anyway.')
|
||||
progress_done = True
|
||||
continue
|
||||
raise FillError('No more progress items left to place.')
|
||||
|
||||
spot_to_fill = None
|
||||
for location in fill_locations if placed_advancement_items / total_advancement_items < cutoffrate else reversed(fill_locations):
|
||||
if location.can_fill(world.state, item_to_place):
|
||||
spot_to_fill = location
|
||||
break
|
||||
|
||||
if spot_to_fill is None:
|
||||
# we filled all reachable spots. Maybe the game can be beaten anyway?
|
||||
if world.can_beat_game():
|
||||
logging.getLogger('').warning('Not all items placed. Game beatable anyway.')
|
||||
break
|
||||
raise FillError('No more spots to place %s' % item_to_place)
|
||||
|
||||
world.push_item(spot_to_fill, item_to_place, True)
|
||||
itempool.remove(item_to_place)
|
||||
fill_locations.remove(spot_to_fill)
|
||||
|
||||
logging.getLogger('').debug('Unplaced items: %s - Unfilled Locations: %s', [item.name for item in itempool], [location.name for location in fill_locations])
|
||||
|
||||
|
||||
def distribute_items_staleness(world):
|
||||
# get list of locations to fill in
|
||||
fill_locations = world.get_unfilled_locations()
|
||||
world.random.shuffle(fill_locations)
|
||||
|
||||
# get items to distribute
|
||||
world.random.shuffle(world.itempool)
|
||||
itempool = world.itempool
|
||||
|
||||
progress_done = False
|
||||
advancement_placed = False
|
||||
|
||||
# sweep once to pick up preplaced items
|
||||
world.state.sweep_for_events()
|
||||
|
||||
while itempool and fill_locations:
|
||||
candidate_item_to_place = None
|
||||
item_to_place = None
|
||||
for item in itempool:
|
||||
if advancement_placed or (progress_done and (item.advancement or item.priority)):
|
||||
item_to_place = item
|
||||
break
|
||||
if item.advancement:
|
||||
candidate_item_to_place = item
|
||||
if world.unlocks_new_location(item):
|
||||
item_to_place = item
|
||||
break
|
||||
|
||||
if item_to_place is None:
|
||||
# check if we can reach all locations and that is why we find no new locations to place
|
||||
if not progress_done and len(world.get_reachable_locations()) == len(world.get_locations()):
|
||||
progress_done = True
|
||||
continue
|
||||
# check if we have now placed all advancement items
|
||||
if progress_done:
|
||||
advancement_placed = True
|
||||
continue
|
||||
# we might be in a situation where all new locations require multiple items to reach. If that is the case, just place any advancement item we've found and continue trying
|
||||
if candidate_item_to_place is not None:
|
||||
item_to_place = candidate_item_to_place
|
||||
else:
|
||||
# we placed all available progress items. Maybe the game can be beaten anyway?
|
||||
if world.can_beat_game():
|
||||
logging.getLogger('').warning('Not all locations reachable. Game beatable anyway.')
|
||||
progress_done = True
|
||||
continue
|
||||
raise FillError('No more progress items left to place.')
|
||||
|
||||
spot_to_fill = None
|
||||
for location in fill_locations:
|
||||
# increase likelyhood of skipping a location if it has been found stale
|
||||
if not progress_done and world.random.randint(0, location.staleness_count) > 2:
|
||||
continue
|
||||
|
||||
if location.can_fill(world.state, item_to_place):
|
||||
spot_to_fill = location
|
||||
break
|
||||
else:
|
||||
location.staleness_count += 1
|
||||
|
||||
# might have skipped too many locations due to potential staleness. Do not check for staleness now to find a candidate
|
||||
if spot_to_fill is None:
|
||||
for location in fill_locations:
|
||||
if location.can_fill(world.state, item_to_place):
|
||||
spot_to_fill = location
|
||||
break
|
||||
|
||||
if spot_to_fill is None:
|
||||
# we filled all reachable spots. Maybe the game can be beaten anyway?
|
||||
if world.can_beat_game():
|
||||
logging.getLogger('').warning('Not all items placed. Game beatable anyway.')
|
||||
break
|
||||
raise FillError('No more spots to place %s' % item_to_place)
|
||||
|
||||
world.push_item(spot_to_fill, item_to_place, True)
|
||||
itempool.remove(item_to_place)
|
||||
fill_locations.remove(spot_to_fill)
|
||||
|
||||
logging.getLogger('').debug('Unplaced items: %s - Unfilled Locations: %s', [item.name for item in itempool], [location.name for location in fill_locations])
|
||||
|
||||
|
||||
def fill_restrictive(world, base_state: CollectionState, locations, itempool, single_player_placement=False):
|
||||
def sweep_from_pool():
|
||||
new_state = base_state.copy()
|
||||
|
|
2
Gui.py
2
Gui.py
|
@ -336,7 +336,7 @@ def guiMain(args=None):
|
|||
algorithmFrame = Frame(drowDownFrame)
|
||||
algorithmVar = StringVar()
|
||||
algorithmVar.set('balanced')
|
||||
algorithmOptionMenu = OptionMenu(algorithmFrame, algorithmVar, 'freshness', 'flood', 'vt21', 'vt22', 'vt25', 'vt26', 'balanced')
|
||||
algorithmOptionMenu = OptionMenu(algorithmFrame, algorithmVar, 'flood', 'vt25', 'vt26', 'balanced')
|
||||
algorithmOptionMenu.pack(side=RIGHT)
|
||||
algorithmLabel = Label(algorithmFrame, text='Item distribution algorithm')
|
||||
algorithmLabel.pack(side=LEFT)
|
||||
|
|
10
Main.py
10
Main.py
|
@ -17,8 +17,7 @@ from EntranceShuffle import link_entrances, link_inverted_entrances
|
|||
from Rom import patch_rom, patch_race_rom, patch_enemizer, apply_rom_settings, LocalRom, get_hash_string
|
||||
from Rules import set_rules
|
||||
from Dungeons import create_dungeons, fill_dungeons, fill_dungeons_restrictive
|
||||
from Fill import distribute_items_cutoff, distribute_items_staleness, distribute_items_restrictive, flood_items, \
|
||||
balance_multiworld_progression
|
||||
from Fill import distribute_items_restrictive, flood_items, balance_multiworld_progression
|
||||
from ItemPool import generate_itempool, difficulties, fill_prizes
|
||||
from Utils import output_path, parse_player_names, get_options, __version__, _version_tuple
|
||||
import Patch
|
||||
|
@ -160,16 +159,9 @@ def main(args, seed=None):
|
|||
|
||||
if args.algorithm == 'flood':
|
||||
flood_items(world) # different algo, biased towards early game progress items
|
||||
elif args.algorithm == 'vt21':
|
||||
distribute_items_cutoff(world, 1)
|
||||
elif args.algorithm == 'vt22':
|
||||
distribute_items_cutoff(world, 0.66)
|
||||
elif args.algorithm == 'freshness':
|
||||
distribute_items_staleness(world)
|
||||
elif args.algorithm == 'vt25':
|
||||
distribute_items_restrictive(world, False)
|
||||
elif args.algorithm == 'vt26':
|
||||
|
||||
distribute_items_restrictive(world, True, shuffled_locations)
|
||||
elif args.algorithm == 'balanced':
|
||||
distribute_items_restrictive(world, True)
|
||||
|
|
Loading…
Reference in New Issue