Browse Source

feat: pop ants untill no more food

master
mco 4 months ago
parent
commit
27f4b2130c
5 changed files with 84 additions and 18 deletions
  1. +64
    -0
      README.md
  2. +7
    -7
      ants.yml
  3. +1
    -1
      ants/__init__.py
  4. +6
    -3
      applicators/collisionsystem.py
  5. +6
    -7
      objects/farm.py

+ 64
- 0
README.md View File

@ -136,3 +136,67 @@ python3 -m ants
| Green | Has food and is going back home |
| Pink | Has no food and is going back to food source |
| Gold | Has food but has lost the way back home |
| On the way back home | Has food | Lost | Status code | Color |
| -------------------- | -------- | ----- | ----------- | ----- |
| True | True | True | 7 | Gold |
| True | True | False | 6 | Green |
| False | False | True | 1 | White |
| False | False | False | 0 | Pink |
## Ants behavior
An ant moves randomly on the playground seeking for food.
Ant records `ants::max_memory` last positions along the path it walked. This records would help the ant going back home.
When an ant find a food source, it collects up to `ants::max_food` from the source and walk all the way back to the farm, following back the recorded path history. While on the way back home with food, its color turns to green.
If the recorded history goes empty before the ant reach the farm, then the ant is lost (color: gold).
When the ant get back to farm with some food, it store the food to the farm and immediately go back to the source for more food and turns its color to pink.
## Ants collisions
When two ants encounter, they turn their color to red and exchange some data according to the following matrix:
| Ant #1 Status | Ant #2 Status | Data exchange | Ant #1 final status |
| ------------- | ------------- | ------------- | ------------------- |
| 1 | 0 | True | 0 |
| 1 | 6 | True | 0 |
| 7 | 0 | True | 6 |
| 7 | 6 | True | 6 |
In all other cases, no data is exchanged.
## Ants life
Each ant has a maximum life time set by `ants::hp` configuration parameter.
This life is decreased by one for each move. So an ant with a `ants::hp` set to 300 will make 300 moves.
If an ant carries some food when its life comes to 0, it will eat one ration and have it's life restored back to the initial `ants::hp` value.
So the only way for an ant to extend its life is to find food and to carry some at the right time.
When an ant has no more life, it dies.
## Farms
Each farm produces ants at the cost of one food ration. When a farm as no more food in stock it stops producing ants. When an ant store food to the farm, then ants production restart immediately.
The initial food quantity of a farm can be set by the `farms::food` configuration parameter.
The number of farms on the playground is set buy the `farms::max_farms` configuration parameter.
## Sources
A food source has a maximum food quantity set by the `sources::food` configuration parameter.
When an ant find a food source, it collects up to `ants::max_food` from the source.
The number of sources on the playground is set buy the `sources::max_sources` configuration parameter.

+ 7
- 7
ants.yml View File

@ -32,7 +32,7 @@ coloredlogs:
sdl:
font:
filename: /usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf
size: 20
size: 14
color:
r: 89
g: 245
@ -45,24 +45,24 @@ sdl:
g: 0
b: 0
playground:
width: 512
width: 600
height: 300
farms:
width: 20
height: 20
food: 50
max_farms: 1
sources:
width: 50
height: 50
max_sources: 1
food: 10000
max_sources: 2
food: 100
ants:
width: 3
height: 3
max_ants: 100
max_memory: 200
max_memory: 100
max_food: 10
hp: 5000
hp: 300
velocity:
vx: 1
vy: 1

+ 1
- 1
ants/__init__.py View File

@ -55,7 +55,7 @@ def run(config):
# -- Dashboard
# -- ---------------------------------------------------------------------------------------------------------------
status_line = " {} [Q to quit] "
status_line = status_line.format(collision_sys.get_status(max_ants=config["ants"]["max_ants"] * config["farms"]["max_farms"]))
status_line = status_line.format(collision_sys.get_status())
if len(collision_sys.ants) == 0:
status_line = " GAME OVER. Press any key to quit. "
game_over = True


+ 6
- 3
applicators/collisionsystem.py View File

@ -48,9 +48,12 @@ class CollisionSystem(sdl2.ext.Applicator):
item_ant.set_position(sprite_pos)
return ants_colliders
def get_status(self, max_ants):
status_line = "Total ants: {}/{} | Collisions: {}"
return status_line.format(len(self.ants), max_ants, round(len(self.ants_colliders) / 2))
def get_status(self):
status_line = "Total ants: {} | Food: {} | Collisions: {}"
food = 0
for farm in self.farms:
food += farm.food.stock
return status_line.format(len(self.ants), food, round(len(self.ants_colliders) / 2))
def process(self, world, componentsets):
self.ants_colliders = [comp for comp in componentsets if self._overlap(comp)]

+ 6
- 7
objects/farm.py View File

@ -1,23 +1,22 @@
import random
import logging
from objects import BaseObject, Size, Food, Life
from objects import BaseObject, Size, Food
from objects import ant
class Farm(BaseObject):
def __init__(self, world, color, config, food=0):
def __init__(self, world, color, config):
super(Farm, self).__init__(world)
self.farm = self
self.size = Size(config["farms"]["width"], config["farms"]["height"])
self.life = Life(config["ants"]["max_ants"])
self.food = Food(food)
self.food = Food(config["farms"]["food"])
self.world = world
self.set_sprite(color=color, depth=0)
self.set_position(config=config)
def pop_ant(self, ants_config):
collision_sys = [s for s in self.world.systems if s.__class__.__name__ == "CollisionSystem"][0]
if self.life.hp > 0:
if self.food.stock > 0:
new_ant = ant.Ant(self.world, ants_config)
new_ant.set_sprite("WHITE")
new_ant_pos = (int(self.get_position()[0] + self.size.width / 2), int(self.get_position()[1] + self.size.height / 2))
@ -25,7 +24,7 @@ class Farm(BaseObject):
new_ant.set_velocity(ants_config["velocity"]["vx"], ants_config["velocity"]["vy"])
new_ant.record_position()
collision_sys.ants.append(new_ant)
self.life.decrement(1)
self.food.decrement(1)
logging.debug("Farm: {} popped {}".format(self.uuid, new_ant))
def set_position(self, config):
@ -47,4 +46,4 @@ class Farm(BaseObject):
def __str__(self):
str = "Farm({}: {}, {}, Position: {})"
return str.format(self.uuid, self.life, self.food, self.get_position())
return str.format(self.uuid, self.food, self.get_position())

Loading…
Cancel
Save