Synthesized Zombie Chase Law

An example of a world law learned by OneLife

Back to main page
class ZombieAggroMovement:
    def __init__(self):
        """Initialize with configurable parameters."""
        pass # No specific parameters are needed for this observed law.
    
    def precondition(self, current_state: WorldState, action: str) -> bool:
        """Return True if this law should apply to the given state and action."""
        # This law applies if there are any ZombieState entities within the player's
        # update range, as their movement is an autonomous process.
        zombies_in_range = current_state.get_object_of_type_in_update_range(ZombieState)
        return len(zombies_in_range) > 0
    
    def effect(self, current_state: WorldState, action: str) -> None:
        """Apply the law by modifying the world state."""
        player_pos = current_state.player.position

        # Retrieve all ZombieState objects that are within the update range.
        # This implicitly filters for zombies close enough to be active/observable.
        zombies_to_update = current_state.get_object_of_type_in_update_range(ZombieState)

        for zombie in zombies_to_update:
            # Calculate the differences in coordinates between the player and the zombie.
            dx = player_pos.x - zombie.position.x
            dy = player_pos.y - zombie.position.y

            # Initialize new positions to current positions (no movement by default)
            new_x = zombie.position.x
            new_y = zombie.position.y

            # Prioritize movement along the X-axis
            if dx != 0:
                # Move one step towards the player along the X-axis.
                new_x = zombie.position.x + (1 if dx > 0 else -1)
            elif dy != 0:
                # If X-axis is already aligned, move one step towards the player along the Y-axis.
                new_y = zombie.position.y + (1 if dy > 0 else -1)
            
            # Update the zombie's position in the state using DiscreteDistribution.
            zombie.position.x = DiscreteDistribution(support=[new_x])
            zombie.position.y = DiscreteDistribution(support=[new_y])
Back to main page