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. Your file can contain one dependency using StatsBase, but no other packages can be used. For example, having a using Plots in your code will cause the automatic evaluation to fail.

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> 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 50% 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}
  ๐ŸŒฟ  #2 70% 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> # `@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{Any, Any}(Main.Animal{๐Ÿ‘} => 1, Main.Plant{๐ŸŒฟ} => 0.7, Main.Animal{๐Ÿบ} => 1)