ABMEv_world.jl 2.81 KB
Newer Older
Victor's avatar
Victor committed
1
# this used to be the worldalive
2
3

# TODO: do a constructor that ensures the parameters numerics are of the same type as the agents
Victor's avatar
Victor committed
4
5
6
mutable struct World{A<:AbstractAgent, S<:AbstractSpacesTuple,T<:Number}
    agents::Vector{AbstractAgentM}
    space::S
7
    parameters::Dict
Victor's avatar
Victor committed
8
9
10
    t::T
end

11
12
13
#constructor
function World(w::Vector{A},s::S,p::Dict,t::T=0.) where {A<:AbstractAgent,S<:AbstractSpacesTuple,T}
    if typeof(p["D"]) != eltype(skipmissing(w)[1])
Victor's avatar
Victor committed
14
        throw(ArgumentError("Diffusion coefficient does not match with underlying space\n `D::Tuple`"))
15
16
17
18
19
    end
    ww = vcat(w,repeat([missing],Int(p["NMax"] - length(w))))
    World{A,S,T}(ww,s,p,t)
end

Victor's avatar
Victor committed
20
parameters(world::World) = world.parameters
21
time(w::World) = w.t
Victor's avatar
Victor committed
22
23
24
25
space(w::World) = w.space
# this throws indices that are occupied by agents
_get_idx(world::World) = collect(eachindex(skipmissing(world.agents)))
# this throws agents of an abstract array of size size(world)
26
27
import Base:size,getindex
Base.size(world::World) = length(world.agents) - count(ismissing,world.agents)
Victor's avatar
Victor committed
28
29
30
Base.getindex(w::World,i::Int) = w.agents[_get_idx(w)[i]]

# this throws an iterators of agents in the world
31
32
33
agents(world::World) = skipmissing(world.agents)
maxsize(w::World) = w.parameters["NMax"]
_findfreeidx(w::World) = findfirst(ismissing,w.agents)
34
addAgent!(w::World,a::AbstractAgent) = begin
Victor's avatar
Victor committed
35
36
37
38
    idx = _findfreeidx(w)
    w.agents[idx] = a
    return nothing
end
39
removeAgent!(w::World,i::Int) = begin
40
    w.agents[_get_idx(w)[i]] = missing
Victor's avatar
Victor committed
41
42
43
44
45
46
47
    return nothing
end

update_clock!(w::World{A,S,T},dt) where {A,S,T} = begin
    w.t = convert(T,sum(w.t + dt))
    return nothing
end
Victor's avatar
Victor committed
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62


## Accessors
"""
$(SIGNATURES)
Get x of world without geotrait.
"""
Base.getindex(w::World,i::Integer) = getindex.(agents(w),i)
#TODO : code it
# """
# $(SIGNATURES)
# Returns trait of every agents of world in the form of an array which dimensions corresponds to the input.
# If `trait = 0` , we return the geotrait.
# """
# get_x(w::World,t::Number,trait::Integer) = trait > 0 ? w[i] : reshape(hcat(get_geo.(w,t)),size(w,1),size(w,2))
Victor's avatar
Victor committed
63
#
Victor's avatar
Victor committed
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# """
# $(SIGNATURES)
# Returns every traits of every agents of world in the form of an array
# """
# function get_xarray(world::Array{T,1}) where {T <: Agent}
#     return hcat(get_x.(world)...)
# end
# """
# $(SIGNATURES)
# Returns every traits of every agents of `world` in the form **of a one dimensional array** (in contrast to `get_x`).
# If `geotrait=true` the geotrait is also added to the set of trait, in the last line.
# If you do not want to specify `t` (only useful for geotrait), it is also possible to use `get_xarray(world::Array{T,1}) where {T <: Agent}`.
# """
# function get_xarray(world::Array{T,1},t::Number,geotrait::Bool=false) where {T <: Agent}
#     xarray = hcat(get_x.(world)...)
#     if geotrait
#         xarray = vcat( xarray, get_geo.(world,t)')
#     end
#     return xarray
# end