Skip to content

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 ​

Homework

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
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 30% 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 ​

Homework

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 nth 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)])
Main.World{Main.Agent}
  🐺♂ #3 E=10.0 ΔE=8.0 pr=0.1 pf=0.2
  🌿  #2 80% grown
  🐑♀ #1 E=4.0 ΔE=0.2 pr=0.8 pf=0.6

julia> # `@info agent_count(w)` is executed only every 3rd call to logcb(w)
       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.8, :Sheep => 1.0)