Don't allow items to swap infinitly
This commit is contained in:
		
							parent
							
								
									6a34fe5184
								
							
						
					
					
						commit
						d719eb356f
					
				
							
								
								
									
										11
									
								
								Fill.py
								
								
								
								
							
							
						
						
									
										11
									
								
								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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue