Homework 3
In this homework we will implement a function find_food
and practice the use of closures. The solution of lab 3 can be found here. You can use this file and add the code that you write for the homework to it.
How to submit?
Put all your code (including your or the provided solution of lab 2) in a script named hw.jl
. Zip only this file (not its parent folder) and upload it to BRUTE.
Agents looking for food
Implement a method find_food(a::Animal, w::World)
returns one randomly chosen agent from all w.agents
that can be eaten by a
or nothing
if no food could be found. This means that if e.g. the animal is a Wolf
you have to return one random Sheep
, etc.
Hint: You can write a general find_food
method for all animals and move the parts that are specific to the concrete animal types to a separate function. E.g. you could define a function eats(::Animal{Wolf}, ::Animal{Sheep}) = true
, etc.
You can check your solution with the public test:
julia> sheep = Sheep(1,pf=1.0)
🐑♂ #1 E=4.0 ΔE=0.2 pr=0.8 pf=1.0
julia> world = World([Grass(2), sheep])
Main.World{Main.Agent} 🌿 #2 70% grown 🐑♂ #1 E=4.0 ΔE=0.2 pr=0.8 pf=1.0
julia> find_food(sheep, world) isa Plant{Grass}
true
Callbacks & Closures
Implement a function every_nth(f::Function,n::Int)
that takes an inner function f
and uses a closure to construct an outer function g
that only calls f
every n
th call to g
. For example, if n=3
the inner function f
be called at the 3rd, 6th, 9th ... call to g
(not at the 1st, 2nd, 4th, 5th, 7th... call).
Hint: You can use splatting via ...
to pass on an unknown number of arguments from the outer to the inner function.
You can use every_nth
to log (or save) the agent count only every couple of steps of your simulation. Using every_nth
will look like this:
julia> w = World([Sheep(1), Grass(2), Wolf(3)]) # `@info agent_count(w)` is executed only every 3rd call to logcb(w)
Main.World{Main.Agent} 🌿 #2 40% grown 🐺♀ #3 E=10.0 ΔE=8.0 pr=0.1 pf=0.2 🐑♀ #1 E=4.0 ΔE=0.2 pr=0.8 pf=0.6
julia> logcb = every_nth(w->(@info agent_count(w)), 3);
julia> logcb(w); # x->(@info agent_count(w)) is not called
julia> logcb(w); # x->(@info agent_count(w)) is not called
julia> logcb(w); # x->(@info agent_count(w)) *is* called
[ Info: Dict(:Wolf => 1.0, :Grass => 0.4, :Sheep => 1.0)