Don't allow items to swap infinitly

This commit is contained in:
Brad Humphrey 2021-12-20 18:14:50 -07:00 committed by Fabian Dill
parent 6a34fe5184
commit d719eb356f
2 changed files with 29 additions and 3 deletions

11
Fill.py
View File

@ -2,6 +2,8 @@ import logging
import typing
import collections
import itertools
from collections import Counter
from BaseClasses import CollectionState, Location, MultiWorld, Item
from worlds.generic import PlandoItem
@ -25,6 +27,7 @@ def fill_restrictive(world: MultiWorld, base_state: CollectionState, locations,
unplaced_items = []
placements = []
swapped_items: Counter[Item] = Counter()
reachable_items = {}
for item in itempool:
reachable_items.setdefault(item.player, []).append(item)
@ -59,15 +62,19 @@ def fill_restrictive(world: MultiWorld, base_state: CollectionState, locations,
# try swaping this item with previously placed items
for(i, location) in enumerate(placements):
placed_item = location.item
if swapped_items[placed_item.name] > 0:
continue
location.item = None
placed_item.location = None
swap_state = sweep_from_pool(base_state, itempool)
if (not single_player_placement or location.player == item_to_place.player) \
and location.can_fill(swap_state, item_to_place, perform_access_check):
# Add this item to the exisiting placement, and
# Add this item to the exisiting placement, and
# add the old item to the back of the queue
spot_to_fill = placements.pop(i)
reachable_items.setdefault(placed_item.player, []).append(placed_item)
swapped_items[placed_item.name] += 1
reachable_items.setdefault(
placed_item.player, []).append(placed_item)
itempool.append(placed_item)
break
else:

View File

@ -149,4 +149,23 @@ class TestBase(unittest.TestCase):
set_rule(loc2, lambda state: state.has(item1.name, player1_id))
set_rule(loc0, lambda state: state.has(item2.name, player1_id))
with pytest.raises(FillError):
fill_restrictive(multi_world, multi_world.state, locations, items)
fill_restrictive(multi_world, multi_world.state, locations, items)
def test_competing_fill_restrictive(self):
multi_world = generate_multi_world()
player1_id = 1
player1_menu = multi_world.get_region("Menu", player1_id)
locations = generate_locations(2, player1_id, None, player1_menu)
items = generate_items(2, player1_id, True)
item0 = items[0]
item1 = items[1]
loc1 = locations[1]
multi_world.completion_condition[player1_id] = lambda state: state.has(
item0.name, player1_id) and state.has(item0.name, player1_id) and state.has(item1.name, player1_id)
set_rule(loc1, lambda state: state.has(item0.name, player1_id)
and state.has(item1.name, player1_id))
with pytest.raises(FillError):
fill_restrictive(multi_world, multi_world.state, locations, items)