Add agent to random position in 3D GridSpace

I am trying to create a 3D ABM using agents.jl. I am stuck with a very simple issue, I cannot add agents to the GridSpace. I just want to give each agent a random starting point in 3D space.

I have cannibalised the wolf-sheep and the 3D Mixed-Agent Ecosystem with Pathfinding example models, to cerate a reproducible example, the below code works if dim = (20,20), but not if dim = (20,20,20).

I initially tried adding an agent simply using add_agent!() but I couldn’t get that to work, so following the 3D Mixed-Agent Ecosystem with Pathfinding example I used the AStar() pathfinding function used to add hawks (seems unnecessary since I just want a random starting position and nowhere is restricted space), but that didn’t work either. I keep getting the error message:

ERROR: MethodError: Cannot `convert` an object of type 
  Tuple{Int64{},Int64{},Int64} to an object of type
  Tuple{Int64{},Int64{}}

The error occurs in the # Add agents block of code. Any advice would be great!

Reproduceable example:

using Agents, Agents.Pathfinding
using Random
using InteractiveDynamics
using GLMakie

# sheep agents with no traits (other than id and pos)
@agent Sheep GridAgent{2} begin
end


function initialize_model(;
    n_sheep = 10,
    dims = (20, 20, 20),
    seed = 23182,
)

rng = MersenneTwister(seed)
space = GridSpace(dims, periodic = false)

# define where "sheep" can walk - everywhere
# land_walkmap = BitArray(trues(dims...))

# model properties
properties = (
    landfinder = AStar(space; diagonal_movement = true),
    #landfinder = AStar(space; walkmap = land_walkmap),
    #landfinder = AStar(space; walkmap = land_walkmap, cost_metric = MaxDistance{3}(), diagonal_movement = true),
    fully_grown = falses(dims),
)

model = ABM(Sheep, space; properties, rng, scheduler = Schedulers.randomly, warn = false
)
# Add agents
for _ in 1:n_sheep
    add_agent_pos!(
        Sheep(
            nextid(model), 
            random_walkable(model, model.landfinder),
        ),
        model,
    )
end

# Add grass with random initial growth
for p in positions(model)
    fully_grown = rand(model.rng, Bool)
    model.fully_grown[p...] = fully_grown
end

return model

end

# sheep movement - random
function sheepwolf_step!(sheep::Sheep, model)
    walk!(sheep, rand, model)
end


# grass - something mundane 
function grass_step!(model)
    for p in positions(model)
                model.fully_grown[p...] = true
            end
end

# set up model - fails
sheepwolfgrass = initialize_model() 

There’s a 3D GridSpace model example for the Schelling model in the InteractiveDynamics repository. Maybe this helps you to find out what you want to do?

1 Like

That {2} looks like it would need to be {3}?

2 Likes

I’m an idiot. … thank you!

Great catch, it’s these little things. :slight_smile: