diff --git a/Fill.py b/Fill.py index 9660e1af..a6864d87 100644 --- a/Fill.py +++ b/Fill.py @@ -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: diff --git a/test/base/TestFill.py b/test/base/TestFill.py index 9b132b65..8e032109 100644 --- a/test/base/TestFill.py +++ b/test/base/TestFill.py @@ -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) \ No newline at end of file + 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)