Skip to content

Commit c77e2a5

Browse files
authored
Lab02 fixes (#12)
1 parent 8f6296e commit c77e2a5

File tree

2 files changed

+23
-18
lines changed

2 files changed

+23
-18
lines changed

docs/src/lecture_02/Lab02Ecosystem.jl

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ end
4444

4545
function agent_step!(a::Animal, w::World)
4646
incr_energy!(a,-1)
47-
if rand() <= food_prob(a)
47+
if rand() <= foodprob(a)
4848
dinner = find_food(a,w)
4949
eat!(a, dinner, w)
5050
end
5151
if energy(a) <= 0
5252
kill_agent!(a,w)
5353
return
5454
end
55-
if rand() <= reproduction_prob(a)
55+
if rand() <= reprprob(a)
5656
reproduce!(a,w)
5757
end
5858
return a
@@ -63,21 +63,22 @@ mutable struct Grass <: Plant
6363
size::Int
6464
max_size::Int
6565
end
66+
Grass(id,m) = Grass(id, rand(1:m), m)
6667

6768
mutable struct Sheep <: Animal
6869
id::Int
6970
energy::Float64
7071
Δenergy::Float64
71-
reproduction_prob::Float64
72-
food_prob::Float64
72+
reprprob::Float64
73+
foodprob::Float64
7374
end
7475

7576
mutable struct Wolf <: Animal
7677
id::Int
7778
energy::Float64
7879
Δenergy::Float64
79-
reproduction_prob::Float64
80-
food_prob::Float64
80+
reprprob::Float64
81+
foodprob::Float64
8182
end
8283

8384
id(a::Agent) = a.id # every agent has an ID so we can just define id for Agent here
@@ -89,8 +90,8 @@ grow!(a::Plant) = a.size += 1
8990
# get field values
9091
energy(a::Animal) = a.energy
9192
Δenergy(a::Animal) = a.Δenergy
92-
reproduction_prob(a::Animal) = a.reproduction_prob
93-
food_prob(a::Animal) = a.food_prob
93+
reprprob(a::Animal) = a.reprprob
94+
foodprob(a::Animal) = a.foodprob
9495

9596
# set field values
9697
energy!(a::Animal, e) = a.energy = e
@@ -118,23 +119,22 @@ end
118119

119120
function eat!(a::Sheep, b::Grass, w::World)
120121
incr_energy!(a, size(b)*Δenergy(a))
121-
kill_agent!(b,w)
122+
b.size = 0
122123
end
123124
function eat!(wolf::Wolf, sheep::Sheep, w::World)
124125
incr_energy!(wolf, energy(sheep)*Δenergy(wolf))
125126
kill_agent!(sheep,w)
126127
end
127128
eat!(a::Animal,b::Nothing,w::World) = nothing
128129

129-
kill_agent!(a::Plant, w::World) = a.size = 0
130130
kill_agent!(a::Animal, w::World) = delete!(w.agents, id(a))
131131

132132
function find_food(a::Animal, w::World)
133133
as = filter(x->eats(a,x), w.agents |> values |> collect)
134134
isempty(as) ? nothing : sample(as)
135135
end
136136

137-
eats(::Sheep,::Grass) = true
137+
eats(::Sheep,g::Grass) = size(g) > 0
138138
eats(::Wolf,::Sheep) = true
139139
eats(::Agent,::Agent) = false
140140

docs/src/lecture_02/lab.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,10 @@ input types and is our first practical example of [*multiple dispatch*](https://
236236
```
237237
Implement a function `eat!(::Sheep, ::Grass, ::World)` which increases the sheep's
238238
energy by $\Delta E$ multiplied by the size of the grass.
239+
239240
After the sheep's energy is updated the grass is eaten and its size counter has
240241
to be set to zero.
242+
241243
Note that you do not yet need the world in this function. It is needed later
242244
for the case of wolves eating sheep.
243245
```@raw html
@@ -248,9 +250,8 @@ for the case of wolves eating sheep.
248250
```@example non_parametric_agents
249251
function eat!(a::Sheep, b::Grass, w::World)
250252
incr_energy!(a, size(b)*Δenergy(a))
251-
kill_agent!(b,w)
253+
b.size = 0
252254
end
253-
kill_agent!(a::Plant, w::World) = a.size = 0
254255
nothing # hide
255256
```
256257
```@raw html
@@ -281,9 +282,12 @@ eat!(grass,sheep,world);
281282
<div class="admonition-body">
282283
```
283284
Next, implement a `Wolf` with the same properties as the sheep ($E$, $\Delta
284-
E$, $p_r$, and $p_f$) as well as the correspoding `eat!` method which increases
285+
E$, $p_r$, and $p_f$) as well as its `eat!` method. The `eat!` method for wolves increases
285286
the wolf's energy by `energy(sheep)*Δenergy(wolf)` and kills the sheep (i.e.
286287
removes the sheep from the world).
288+
Both `eat!` and `agent_step!` need to be able to remove agents from the world
289+
so it makes sense to create another function `kill_agent!(::Animal,::World)`.
290+
Please implement it as well to make your `agent_step!` work.
287291

288292
Hint: You can use `delete!` to remove agents from the dictionary in your world.
289293

@@ -343,7 +347,7 @@ function find_food(a::Animal, w::World)
343347
isempty(as) ? nothing : sample(as)
344348
end
345349
346-
eats(::Sheep,::Grass) = true
350+
eats(::Sheep,g::Grass) = size(g) > 0
347351
eats(::Wolf,::Sheep) = true
348352
eats(::Agent,::Agent) = false
349353
```
@@ -362,7 +366,8 @@ random `Grass` from all available `Grass` agents.
362366
```
363367

364368
Implement the method `find_food(::Sheep, ::World)` which first returns either a
365-
`Grass` (sampled randomly from all `Grass`es) or returns `nothing`.
369+
`Grass` (sampled randomly from all `Grass`es with a size larger than zero) or
370+
returns `nothing`.
366371

367372
1. Hint: For the functional programming way of coding this can use `filter` and
368373
`isa` to filter for a certain type and `StatsBase.sample` to choose a random
@@ -382,7 +387,7 @@ using StatsBase # needed for `sample`
382387
# you can install it by typing `]add StatsBase` in the REPL
383388

384389
function find_food(a::Sheep, w::World)
385-
as = filter(x->isa(x,Grass), w.agents |> values |> collect)
390+
as = filter(x->isa(x,Grass) && size(x)>0, w.agents |> values |> collect)
386391
isempty(as) ? nothing : sample(as)
387392
end
388393
```
@@ -460,7 +465,7 @@ function find_food(a::Animal, w::World)
460465
isempty(as) ? nothing : sample(as)
461466
end
462467

463-
eats(::Sheep,::Grass) = true
468+
eats(::Sheep,g::Grass) = size(g) > 0
464469
eats(::Wolf,::Sheep) = true
465470
eats(::Agent,::Agent) = false
466471
```

0 commit comments

Comments
 (0)