为何实体act方法会被重复调用至World列表越界?
Root Cause
The issue stems from your apply_entity_logic_all function iterating directly over the live world matrix while modifying it. When a Plankton moves, it adds a new Plankton to the adjacent cell (i+1, j). Since the outer loop hasn’t finished processing all rows yet, when it reaches row i+1, the new Plankton is included in the iteration. Its act method runs immediately, creating another Plankton in row i+2, and this chain continues until posx exceeds the world’s row count, causing an index out-of-bounds error.
Why Only add Seems to Repeat
Each new Plankton’s act method gets called in the same iteration pass. The del statement only runs once per original entity, but every new Plankton triggers another add when its act is processed. This creates a domino effect of new entities being added and processed immediately.
Fix: Process Entities from a Snapshot
To prevent new entities from being processed in the same pass, first collect all entities along with their current positions and IDs before modifying the world. Then iterate over this static snapshot instead of the live matrix.
Modified apply_entity_logic_all Code
def apply_entity_logic_all(): # Collect all entities with their initial positions and IDs entities_to_process = [] world = singleton.World.world for i in range(len(world)): row = world[i] for j in range(len(row)): # Create a copy of the entity list at (i,j) to capture current state entities = list(row[j]) for entity_id, entity in enumerate(entities): entities_to_process.append((entity, i, j, entity_id)) # Process each entity from the snapshot for entity, i, j, entity_id in entities_to_process: # Safeguard: Check if the entity is still in its original position # (in case it was deleted by another entity's action) if j < len(world[i]) and entity_id < len(world[i][j]) and world[i][j][entity_id] is entity: entity.act(i, j, entity_id)
Fix the Indentation in act Method
Your original act method has an indentation error that would cause unexpected behavior. Correct it to ensure del and add run after creating new_object:
def act(self, i, j, id): new_object = Plankton(posx=i+1, posy=j) del singleton.World.world[i][j][id] singleton.World.add(new_object, i+1, j)
Explanation
- By creating a snapshot of all entities before processing, we ensure only the entities present at the start of
apply_entity_logic_allare acted upon. New entities added during the pass won’t be included until the next call to this function. - The safeguard check ensures we don’t attempt to delete an entity that’s already been removed (e.g., if multiple entities are in the same cell and one deletes another).
内容的提问来源于stack exchange,提问作者Sushanta Banerjee

