1+ '''
2+ Wolf-Sheep Predation Model
3+ ================================
4+
5+ Replication of the model found in NetLogo:
6+ Wilensky, U. (1997). NetLogo Wolf Sheep Predation model.
7+ http://ccl.northwestern.edu/netlogo/models/WolfSheepPredation.
8+ Center for Connected Learning and Computer-Based Modeling,
9+ Northwestern University, Evanston, IL.
10+
11+ TODO: Implement grass
12+ '''
13+
14+ import random
15+
16+ from mesa import Model , Agent
17+ from mesa .space import MultiGrid
18+ from mesa .time import Random_Activation
19+
20+ from RandomWalk import RandomWalker
21+
22+ class WolfSheepPredation (Model ):
23+ '''
24+ Wolf-Sheep Predation Model
25+ '''
26+
27+ initial_sheep = 100
28+ initial_wolves = 50
29+ sheep_gain_from_food = 4
30+
31+ grass = False
32+
33+ wolf_gain_from_food = 20
34+ sheep_reproduce = 0.04
35+ wolf_reproduce = 0.05
36+
37+ height = 20
38+ width = 20
39+
40+ def __init__ (self , height = 20 , width = 20 ,
41+ initial_sheep = 100 , initial_wolves = 50 , sheep_reproduce = 0.04 ,
42+ wolf_reproduce = 0.05 , wolf_gain_from_food = 20 ,
43+ grass = False , sheep_gain_from_food = 4 ):
44+ '''
45+ Create a new Wolf-Sheep model with the given parameters.
46+
47+ Args:
48+ initial_sheep: Number of sheep to start with
49+ initial_wolves: Number of wolves to start with
50+ sheep_reproduce: Probability of each sheep reproducing each step
51+ wolf_reproduce: Probability of each wolf reproducing each step
52+ wolf_gain_from_food: Energy a wolf gains from eating a sheep
53+ grass: Whether to have the sheep eat grass for energy
54+ sheep_gain_from_food: Energy sheep gain from grass, if enabled.
55+ '''
56+
57+ # Set parameters
58+ self .height = height
59+ self .width = width
60+ self .initial_sheep = initial_sheep
61+ self .initial_wolves = initial_wolves
62+ self .sheep_reproduce = sheep_reproduce
63+ self .wolf_reproduce = wolf_reproduce
64+ self .wolf_gain_from_food = wolf_gain_from_food
65+ self .grass = grass
66+ self .sheep_gain_from_food = sheep_gain_from_food
67+
68+ self .schedule = Random_Activation (self )
69+ self .grid = MultiGrid (self .height , self .width , torus = True )
70+
71+ # Create sheep:
72+ for i in range (self .initial_sheep ):
73+ x = random .randrange (self .width )
74+ y = random .randrange (self .height )
75+ sheep = Sheep (self .grid , x , y , True )
76+ self .grid [y ][x ].add (sheep )
77+ self .schedule .add (sheep )
78+
79+ # Create wolves
80+ for i in range (self .initial_wolves ):
81+ x = random .randrange (self .width )
82+ y = random .randrange (self .height )
83+ energy = random .randrange (2 * self .wolf_gain_from_food )
84+ wolf = Wolf (self .grid , x , y , True , energy )
85+ self .grid [y ][x ].add (wolf )
86+ self .schedule .add (wolf )
87+
88+ def step (self ):
89+ self .schedule .step ()
90+
91+
92+ class Sheep (RandomWalker , Agent ):
93+ '''
94+ A sheep that walks around, reproduces (asexually) and gets eaten.
95+
96+ The init is the same as the RandomWalker.
97+ '''
98+
99+ def step (self , model ):
100+ '''
101+ A model step. Move, then eat grass and reproduce.
102+ '''
103+ self .random_move ()
104+ if random .random () < model .sheep_reproduce :
105+ # Create a new sheep:
106+ lamb = Sheep (self .grid , self .x , self .y , self .moore )
107+ model .grid [self .y ][self .x ].add (lamb )
108+ model .schedule .add (lamb )
109+
110+
111+ class Wolf (RandomWalker , Agent ):
112+ '''
113+ A wolf that walks around, reproduces (asexually) and eats sheep.
114+ '''
115+
116+ energy = None
117+
118+ def __init__ (self , grid , x , y , moore , energy ):
119+ super ().__init__ (grid , x , y , moore )
120+ self .energy = energy
121+
122+
123+ def step (self , model ):
124+ self .random_move ()
125+ self .energy -= 1
126+
127+ # If there are sheep present, eat one
128+ this_cell = model .grid [self .y ][self .x ]
129+ sheep = [obj for obj in this_cell if isinstance (obj , Sheep )]
130+ if len (sheep ) > 0 :
131+ sheep_to_eat = random .choice (sheep )
132+ self .energy += model .wolf_gain_from_food
133+
134+ # Kill the sheep
135+ model .grid [self .y ][self .x ].remove (sheep_to_eat )
136+ model .schedule .remove (sheep_to_eat )
137+
138+ # Reproduction:
139+ if random .random () < model .wolf_reproduce :
140+ # Create a new wolf cub
141+ cub = Wolf (self .grid , self .x , self .y , self .moore , self .energy / 2 )
142+ self .energy = self .energy / 2
143+ model .grid [self .y ][self .x ].add (cub )
144+ model .schedule .add (cub )
0 commit comments