Skip to content

Commit 7562102

Browse files
committed
Update README and align parameter naming in app/model
1 parent 67cf88f commit 7562102

2 files changed

Lines changed: 11 additions & 53 deletions

File tree

examples/energy_expenditure/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def agent_portrayal(agent):
2020

2121
# Allow easy parameter tweaking
2222
model = EnergyModel(
23-
N=20,
23+
n=20,
2424
width=10,
2525
height=10,
2626
)
Lines changed: 10 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,70 @@
11
from mesa import Agent, Model
22
from mesa.space import MultiGrid
3-
from mesa.time import RandomActivation
43

54

65
class EnergyAgent(Agent):
7-
"""
8-
Energy-based agent with a well-defined lifecycle.
9-
10-
Design guarantees:
11-
- Energy is updated ONLY in step()
12-
- Actions (move/rest) do not mutate energy
13-
- Energy strictly decreases over time
14-
- Agent is removed immediately when energy reaches zero
15-
16-
Invariant:
17-
energy > 0 <=> agent.alive == True
18-
"""
19-
206
# --- Tunable Parameters ---
217
LOW_ENERGY_THRESHOLD = 4
228
MOVE_DECAY = 1.0
239
REST_DECAY = 0.4
2410

25-
def __init__(self, unique_id, model, energy=10):
26-
super().__init__(unique_id, model)
11+
def __init__(self, model, energy=10):
12+
super().__init__(model)
2713
self.energy = energy
2814
self.alive = True
2915

3016
def step(self):
31-
"""Single authoritative lifecycle step."""
32-
3317
if not self.alive:
34-
return # safety guard
18+
return
3519

36-
# --- Decision Phase ---
3720
is_resting = self.energy < self.LOW_ENERGY_THRESHOLD
3821

39-
# --- Action Phase (pure, no energy mutation) ---
4022
if is_resting:
4123
self.rest()
4224
decay = self.REST_DECAY
4325
else:
4426
self.move()
4527
decay = self.MOVE_DECAY
4628

47-
# --- Energy Update ---
4829
self.energy = max(self.energy - decay, 0)
4930

50-
# --- Immediate Death (no zombie tick) ---
5131
if self.energy == 0:
5232
self._die()
5333

5434
def move(self):
55-
"""Move to a random neighboring cell."""
5635
neighbors = self.model.grid.get_neighborhood(
5736
self.pos, moore=True, include_center=False
5837
)
59-
6038
if neighbors:
6139
new_pos = self.random.choice(neighbors)
6240
self.model.grid.move_agent(self, new_pos)
6341

6442
def rest(self):
65-
"""Agent remains stationary to conserve energy."""
43+
pass
6644

6745
def _die(self):
68-
"""
69-
Safe removal:
70-
- Marks agent as dead
71-
- Removes from grid and scheduler
72-
"""
7346
self.alive = False
7447
self.model.grid.remove_agent(self)
75-
self.model.schedule.remove(self)
48+
self.remove() # deregisters from model AgentSet
7649

7750

7851
class EnergyModel(Model):
79-
"""
80-
Model with agents that expend energy over time and eventually die.
81-
82-
Behavior:
83-
- Agents move when energy is sufficient
84-
- Agents rest when energy is low
85-
- All agents eventually die due to energy depletion
86-
"""
87-
8852
def __init__(self, n=10, width=10, height=10):
8953
super().__init__()
90-
9154
self.num_agents = n
9255
self.grid = MultiGrid(width, height, torus=True)
93-
self.schedule = RandomActivation(self)
94-
95-
# Create agents
96-
for i in range(self.num_agents):
97-
agent = EnergyAgent(i, self)
98-
self.schedule.add(agent)
9956

57+
for _ in range(self.num_agents):
58+
agent = EnergyAgent(self)
10059
x = self.random.randrange(self.grid.width)
10160
y = self.random.randrange(self.grid.height)
10261
self.grid.place_agent(agent, (x, y))
10362

10463
self.running = True
10564

10665
def step(self):
107-
"""Advance the model by one step."""
108-
self.schedule.step()
66+
# RandomActivation replacement in Mesa 3.x
67+
self.agents.shuffle_do("step")
10968

110-
# Stop simulation if no agents remain
111-
if self.schedule.get_agent_count() == 0:
69+
if len(self.agents) == 0:
11270
self.running = False

0 commit comments

Comments
 (0)