An example of a world law learned by OneLife
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