diff --git a/src/core/simulation.jl b/src/core/simulation.jl index e194d7de61ecb4e323e6a132d6de6feaafc236a7..079052392983b15956866554462e517e42e590c0 100644 --- a/src/core/simulation.jl +++ b/src/core/simulation.jl @@ -35,9 +35,10 @@ end Execute one update of the model. """ function stepsimulation!(model::AgentBasedModel) - @info "Simulating day $(model.date+Day(1))." + @info "Simulating day $(model.date)." for a in Schedulers.ByType((Farmer,Animal,CropPlot), true)(model) - stepagent!(getindex(model, a), model) + #The animal may have been killed, so we need a try/catch + try stepagent!(getindex(model, a), model) catch keyerror end end savepopulationdata(model) model.date += Day(1) diff --git a/src/nature/nature.jl b/src/nature/nature.jl index e628a35cc30fc3d944c80a51439de6e92b9cce50..c41af8fc2d111b8a3a77545a584b63eca8195a98 100644 --- a/src/nature/nature.jl +++ b/src/nature/nature.jl @@ -16,6 +16,7 @@ struct Species name::String initpop!::Function # takes one argument: model update!::Function # takes two arguments: animal, model + traits::Dict{String,Any} # a collection of species-specific traits end """ @@ -55,6 +56,27 @@ let specieslist = Dict{String, Species}() end end +""" + newspecies(properties...) + +A utility function to create and register a new species. +All function arguments are passed on to Species(). +""" +function newspecies(properties...) + registerspecies(Species(properties...)) +end + +""" + trait(animal, trait) + +A utility function to return a trait value for this animal's species. +Returns nothing if the trait is not defined. +""" +function trait(animal::Animal, trait::String) + !(trait in keys(animal.species.traits)) && (return nothing) + return animal.species.traits[trait] +end + """ stepagent!(animal, model) diff --git a/src/nature/wolpertinger.jl b/src/nature/wolpertinger.jl index 5741485a7751a2953711ed4d675d2361b351d544..0ebc1a81d53cf37f3f74145d7c5e1847bc99e1ae 100644 --- a/src/nature/wolpertinger.jl +++ b/src/nature/wolpertinger.jl @@ -13,11 +13,11 @@ Initialise a population of Wolpertingers in random locations around the landscap function initwolpertinger!(model::AgentBasedModel) species = getspecies("Wolpertinger") x, y = size(model.landscape) - popsize = Int(round((x*y)/10000)) + popsize = Int(round((x*y)*species.traits["popdensity"])) for i in 1:popsize - add_agent!(Animal, model, species, hermaphrodite, 0, 100) + add_agent!(Animal, model, species, hermaphrodite, 0, species.traits["birthenergy"]) end - @debug "Hid $(popsize) Wolpertingers for gullible tourists to find." + @debug "Hid $(popsize) wolpertingers for gullible tourists to find." end """ @@ -29,13 +29,22 @@ and occasionally reproduce by spontaneous parthogenesis... function updatewolpertinger!(w::Animal, model::AgentBasedModel) # walk in a random direction direction = Tuple(rand([-1,1], 2)) - walk!(w, direction, model; ifempty=false) - w.energy -= rand([1, 10])*5 + speed = rand([1, trait(w, "maxspeed")]) + for i in 1:speed + walk!(w, direction, model; ifempty=false) + end + w.energy -= speed # reproduce every once in a blue moon - if rand() < 0.01 + if rand() < 0.05 @debug "Wolpertinger $(w.id) has reproduced." - add_agent!(w.pos, Animal, model, getspecies("Wolpertinger"), hermaphrodite, 0, 100) + add_agent!(w.pos, Animal, model, getspecies("Wolpertinger"), + hermaphrodite, 0, trait(w, "birthenergy")) end end -registerspecies(Species("Wolpertinger", initwolpertinger!, updatewolpertinger!)) +newspecies("Wolpertinger", + initwolpertinger!, + updatewolpertinger!, + Dict("popdensity"=>1/10000, + "birthenergy"=>400, + "maxspeed"=>5)) diff --git a/src/parameters.toml b/src/parameters.toml index 4248b4529cee29ee3013c0781924b1b2404024e5..ea7411da90257fac7fdd3c31848f991d307afae8 100644 --- a/src/parameters.toml +++ b/src/parameters.toml @@ -9,19 +9,19 @@ [core] configfile = "src/parameters.toml" # location of the configuration file landcovermap = "data/landcover_jena.tif" # location of the landcover map -farmfieldsmap = "data/fields_jena.tif" # location of the field geometry map TODO not the real file yet +farmfieldsmap = "data/fields_jena.tif" # location of the field geometry map outdir = "results" # location and name of the output folder loglevel = "debug" # verbosity level: "debug", "info", "quiet" seed = 0 # seed value for the RNG (0 -> random value) # dates to start and end the simulation startdate = 2020-01-01 -enddate = 2020-01-05 +enddate = 2020-01-31 [farm] [nature] -targetspecies = ["Wolpertinger"] # list of target species to simulate +targetspecies = ["Wolpertinger", "Wyvern"] # list of target species to simulate [crop] cropmodel = "linear" # crop growth model to use, "linear" or "aquacrop" (not yet implemented)