Performs the actions for a predator entity :param occupied_by_prey_coords: Move to this location if there is prey there For predators the rules are: 1. At each chronon, a predator moves randomly to an adjacent square occupied by a prey. If there
(
self,
entity: Entity,
occupied_by_prey_coords: tuple[int, int] | None,
direction_orders: list[Literal["N", "E", "S", "W"]],
)
| 371 | self.move_and_reproduce(entity, direction_orders) |
| 372 | |
| 373 | def perform_predator_actions( |
| 374 | self, |
| 375 | entity: Entity, |
| 376 | occupied_by_prey_coords: tuple[int, int] | None, |
| 377 | direction_orders: list[Literal["N", "E", "S", "W"]], |
| 378 | ) -> None: |
| 379 | """ |
| 380 | Performs the actions for a predator entity |
| 381 | |
| 382 | :param occupied_by_prey_coords: Move to this location if there is prey there |
| 383 | |
| 384 | For predators the rules are: |
| 385 | 1. At each chronon, a predator moves randomly to an adjacent square occupied |
| 386 | by a prey. If there is none, the predator moves to a random adjacent |
| 387 | unoccupied square. If there are no free squares, no movement takes place. |
| 388 | 2. At each chronon, each predator is deprived of a unit of energy. |
| 389 | 3. Upon reaching zero energy, a predator dies. |
| 390 | 4. If a predator moves to a square occupied by a prey, |
| 391 | it eats the prey and earns a certain amount of energy. |
| 392 | 5. Once a predator has survived a certain number of chronons |
| 393 | it may reproduce in exactly the same way as the prey. |
| 394 | |
| 395 | >>> wt = WaTor(WIDTH, HEIGHT) |
| 396 | >>> wt.set_planet([[Entity(True, coords=(0, 0)), Entity(False, coords=(0, 1))]]) |
| 397 | >>> wt.perform_predator_actions(Entity(False, coords=(0, 1)), (0, 0), []) |
| 398 | >>> wt.planet # doctest: +NORMALIZE_WHITESPACE |
| 399 | [[Entity(prey=False, coords=(0, 0), |
| 400 | remaining_reproduction_time=20, energy_value=19), None]] |
| 401 | """ |
| 402 | assert entity.energy_value is not None # [type checking] |
| 403 | |
| 404 | # (3.) If the entity has 0 energy, it will die |
| 405 | if entity.energy_value == 0: |
| 406 | self.planet[entity.coords[0]][entity.coords[1]] = None |
| 407 | return |
| 408 | |
| 409 | # (1.) Move to entity if possible |
| 410 | if occupied_by_prey_coords is not None: |
| 411 | # Kill the prey |
| 412 | prey = self.planet[occupied_by_prey_coords[0]][occupied_by_prey_coords[1]] |
| 413 | assert prey is not None |
| 414 | prey.alive = False |
| 415 | |
| 416 | # Move onto prey |
| 417 | self.planet[occupied_by_prey_coords[0]][occupied_by_prey_coords[1]] = entity |
| 418 | self.planet[entity.coords[0]][entity.coords[1]] = None |
| 419 | |
| 420 | entity.coords = occupied_by_prey_coords |
| 421 | # (4.) Eats the prey and earns energy |
| 422 | entity.energy_value += PREDATOR_FOOD_VALUE |
| 423 | else: |
| 424 | # (5.) If it has survived the certain number of chronons it will also |
| 425 | # reproduce in this function |
| 426 | self.move_and_reproduce(entity, direction_orders) |
| 427 | |
| 428 | # (2.) Each chronon, the predator is deprived of a unit of energy |
| 429 | entity.energy_value -= 1 |
| 430 |