Only observer can ask all turtles - NetLogo error - netlogo

I am new user for Netlogo,
Although when I checked the code, there are no issues. However, when i run the program a while, it throws error message
Only the observer can ASK the set of all turtles. Error while turtle 0 running ASK. called by procedure EXIT called by procedure Customer, GO and by button 'go'
to go
customer
end
to setup-turtles
create-turtles 1
ask turtles
[
set shape "person"
set size 3
set heading -90
fd 10
setxy 15 -15
set color red
]
end
to customer
ask turtles
[
set products ( products )
rt (random 360)
fd 1
if patch-here = one-of patches with
[
pcolor = green
]
[
set pcolor orange
set products (products + 1)
]
if patch-here = one-of patches with
[
pcolor = gray
]
[exit]
show count patches with
[pcolor = green ]
move-to one-of patches with
[
pcolor = black
]
]
end
to exit
ask turtles
[
ifelse patch-here = one-of patches with
[
pcolor = gray
]
[ifelse count products >= 2
[
die
]
[move-to one-of patches with
[
pcolor = green or pcolor = black
]
]
]
[
die
]
move-to one-of patches with
[pcolor = green
]
move-to one-of patches with
[pcolor = black
]
]
end

In your customer procedure, you have
ask turtles
[ ...
if patch-here = one-of patches with [pcolor = gray]
[ exit ]
...
]
So the exit procedure is being called by any turtle that is on a gray patch. Each turtle that meets that condition enters the exit procedure. As soon as it enters that procedure, the first command (in the exit procedure) is to ask turtles. So a turtle is asking all turtles to do something.
This is explicitly banned by the NetLogo language partly because it is a common source of beginner errors and is generally both unnecessary and inefficient. You have already selected the turtle to exit, what is it that this particular turtle needs to do to actually exit. It is very unlikely that they need to identify all the turtles on gray patches.

Related

How do you fix a problem with convert probability on a zombie apocalypse simulation on Netlogo [duplicate]

This question already has an answer here:
How do you go about making a convert probability chance for an agent in netlogo?
(1 answer)
Closed 1 year ago.
currently I'm working on a zombie apocalypse simulation on Netlogo, and I'm almost done except that the convertion function is not working. when the zombies collide with humans the humans they either die or convert the human to a zombie according to the global variable convert_probability. For example, if convert probability is set to 80 the human would have an 80% chance of winning the fight and killing the zombie and the zombie would have a 20% chance of converting the human to a zombie.
Also, zombies and humans are not allowed to pass over the brown patches and the function I wrote for that is change_direction, but had to comment those parts because I run to an error.
I have spent hours but couldnt come up with a solution so I would really appreciate any help;
breed [humans human]
humans-own [ humans_speed]
turtles-own [
infected?
]
patches-own [
block
]
breed [zombies zombie]
zombies-own [ zombies_speed]
globals [
student_id
username
nzomb
%infected
]
to setup_world
clear-all
reset-ticks
set student_id 19009670
ask patches [set pcolor green]
set-default-shape zombies "person"
set-default-shape humans "person"
create-zombies 5 [
set color red
set size 4
set zombies_speed 0.5
setxy random-pxcor random-pycor
]
ask zombies[
move-to one-of patches with [pcolor = green]
]
create-humans 15 [
set color blue
set size 4
set humans_speed 1 + random-float 0.1
setxy random-pxcor random-pycor
]
ask humans[
move-to one-of patches with [pcolor = green]
]
set %infected (count turtles with [color = red ] / 20 ) * 100
set nzomb 0
draw_blocks
end
to draw_blocks
ask patches [
set block false
]
ask n-of 100 patches with [pcolor = green][
set pcolor brown
set block true
]
end
to change_direction
if[block] of patch-ahead 2 = true [
right 180
face one-of patches in-radius 2 with [not block]
]
end
to run_model
if ticks >= 10000 [ stop ]
tick
move-turtles
convert
if not any? humans [stop]
end
to move-turtles
ask humans [move-humans]
ask zombies [move-zombies]
end
to move-humans
ask humans [
if any? zombies in-radius (10 + random 20) [rt 180]
set infected? false
set heading (heading + 45 - (random 90))
forward 1 + random-float 1.1
zombiedeath
convert
;;change_direction
]
end
to move-zombies
ask zombies [
chasehuman
convert
zombiedeath
set %infected (count turtles with [color = red ] / 20 ) * 100
set infected? true
set heading (heading + 45 - (random 90))
forward 0.5
; change-direction
]
end
to chasehuman
if any? humans in-radius 10 [
set heading towards one-of humans in-radius 10]
; change_direction
end
to runaway
face min-one-of zombies [distance myself]
rt 180
;change_direction
end
to convert
ask turtles with [ breed = zombies ]
[
ask humans-on patch-here
[
if random 100 < convert_probability [set breed zombies]]
ask humans-on patch-here [if random 100 < convert_probability
[set color red]]
]
end
to zombiedeath
ask zombies-on patch-here [if random 100 > convert_probability
[die]]
end
Okay, the only procedure relevant to this question is this one (same code as above, formatted so you can see the structure logic}:
to convert
ask turtles with [ breed = zombies ]
[ ask humans-on patch-here
[ if random 100 < convert_probability
[ set breed zombies
]
]
ask humans-on patch-here
[ if random 100 < convert_probability
[ set color red
]
]
]
end
You haven't actually told us what the problem is - "convertion function is not working" does not say whether it is generating an error, or what behaviour it is doing compared to what is expected for example. But, look at what this code actually does. First it finds all the zombies then, for each zombie, it:
gets the humans on the same patch to convert to zombies with some probability
gets the humans on the same patch to change colour to red with some probability
Your first problem is that you haven't linked the turning red with becoming a zombie. Is that the problem you were trying to solve? If so, here is some cleaned up code that links zombie and red:
to convert
ask zombies ; note, you can just directly use the breed name
[ ask humans-here ; again, can use the breed name
[ if random 100 < convert_probability
[ set breed zombies
set color red
]
]
]
end

Spatial Autocorrelation in NetLogo

Is there any straight-forward way to adjust spatial autocorrelation for three different patch colors? I am trying to control both the number of red patches and how spatially autocorrelated (how close same colored patches are to each other). I can control the proportion of red patches, but don't know how to setup the autocorrelation.
Here is my code so far:
to setup-patches
resize-world 0 15 0 15
set-patch-size 30
ask patches [
set pcolor one-of [ green brown ]
]
ask patches [
let close-patches patches with [pcolor != red]
ask n-of ((proportion-red-plants * count patches) - count patches with [pcolor = red]) close-patches
[set pcolor red]
]
end
proportion-red-plants is a slider in the interface
If you know that AC of 0 means pick a patch that has no red neighbours, and that AC of 1 means pick a neighbour of any red patch, then all that is required is to choose AC=1 method with the given probability and the AC=0 method otherwise. This is what I meant by a design issue, you need to work out the steps required before trying to code those steps.
Here is an almost solution. I haven't bothered to do things like make sure the patches being turned red aren't already red so the counts will be incorrect.
to setup
clear-all
let prop-red 0.1
let AC 0
ask one-of patches [set pcolor red]
ask n-of (prop-red * count patches) patches
[ ifelse random-float 1 < AC
[ ask one-of patches with [ pcolor = red ]
[ ask one-of neighbors [ set pcolor red ]
]
]
[ let candidates patches with [not any? neighbors with [pcolor = red] ]
if any? candidates
[ ask one-of candidates [ set pcolor red ]
]
]
]
end
Thank you JenB again for helping. This is the code I ended up using which proved to get the job done (while keeping counts of red patches correct)
to setup-patches
resize-world 0 15 0 15
set-patch-size 30
ask patches [set pcolor one-of [green brown]]
let first-patch one-of patches
ask first-patch [set pcolor red]
repeat (proportion-red-plants * count patches - 1) [ask one-of patches [assign]]
end
to assign
ifelse random-float 1 < AC
[let candds patches with [any? (neighbors with [pcolor = red])]
ask one-of candds [set pcolor red]]
[ask one-of patches [set pcolor red]]
end

Netlogo: find next target discounting previous targets

I'm trying to get my agents to calculate the next patch target once they have reached their first target. A target is defined as the (highest patch influence value / distance to agent). The next target needs to be calculated using this same procedure, but also discounting any previous targets from the equation.
I have attempted to create a patch-set to include all targets, although I'm not sure if it works.
My issue is how to create a to-report function that calculates the next highest-influence-value. I've gotten completely stuck with this final part of my procedure.
My initial reporter function is:
to-report highest-influence
let available-target patches with [influence > 0] ;and not any? patches with [pcolor = green]
report max-one-of available-target [influence / distance myself]
end
But I'm not sure how to have the next reporter function use the same parameters while also discounting any previous targets
to-report next-highest-influence
; patches with [influence > 0] and not part of patch set
end
Any help would be greatly appreciated. I've provided the full code.
breed [walkers walker]
walkers-own [traveled? ;; parameter to keep track of if a walker has traveled to a target yet or not
target ]
patches-own [influence influence-set] ;highest-influence
to setup
clear-all
reset-ticks
define-patches
create-walkers num-walkers
ask walkers [
setxy 0 0
set heading 90
let streets neighbors with [pcolor = black]
ifelse any? streets in-cone 1 25
[fd 1]
[move-to one-of streets in-radius 1]
set traveled? false ;; so that walkers know they have not yet moved to a target
]
ask walkers [
define-target ]
end
to define-patches
ask n-of 100 patches [
set pcolor white
]
ask n-of 40 patches with [pcolor = white] [set influence random 5 set pcolor blue set plabel influence]
ask patches [set influence-set patches with [pcolor = green] ]
end
to define-target ;; this defines the initial destination of walkers
if traveled? = false [
set target highest-influence
ask target [set pcolor green]
face target ]
end
to new-target ;; this defines subsequent desinations after walkers have reached inital target
if traveled? = true [
set target next-highest-influence
ask target [set pcolor green + 2]
face target ]
end
;;;;;;;;;;;;run-time procedure;;;;;;;;;;
to go
ask walkers [
if distance target > 1
[ travel-walkers
leave-a-trail
set traveled? true ]
if distance target = 1
[ stop
new-target
travel-walkers
leave-a-trail
]
]
tick
end
to travel-walkers
ask walkers [
move-towards-target
]
end
to move-towards-target
ask walkers [
ifelse [pcolor] of patch-ahead 1 != white or any? other turtles-here
[ Move-Function ]
[ Avoid-Function ]
]
end
to Move-Function
let t target
face min-one-of all-possible-moves [distance t]
fd 1
end
to Avoid-Function
let t target
face min-one-of all-possible-moves [distance t]
end
to leave-a-trail
ask patch-here [set pcolor grey]
end
;;;;;; reporter calculations ;;;;;;
to-report highest-influence
let available-target patches with [influence > 0] ;and not any? patches with [pcolor = green]
report max-one-of available-target [influence / distance myself]
end
to-report next-highest-influence
; patches with [influence > 0] and not part of patch set
end
to-report all-possible-moves
report patches in-radius 1 with [pcolor != white and distance myself <= 1 and distance myself > 0 and plabel = "" ]
end
You can make use of the member? primitive to do that. Check out the simplified toy model below (I didn't use your code as I'm not sure how you'd want to implement and there are some interface pieces i would need to set up to run it. Check out the MCVE guidelines).
turtles-own [ visited-list ]
patches-own [ influence ]
to setup-member?
ca
crt 1 [ set visited-list [] ]
ask patches [ set influence 0 ]
ask n-of 5 patches [ set influence 5 + random 50 ]
reset-ticks
end
to go-member?
ask turtles [
let target highest-influence
ifelse target != nobody [
face target
ifelse distance target > 1 [
fd 1
] [
move-to target
ask target [ set pcolor red]
set visited-list lput target visited-list
]
] [ print "No targets remaining." ]
]
tick
end
to-report highest-influence
let to-visit patches with [
influence > 0 and
not member? self [visited-list] of myself ]
report max-one-of to-visit [ influence / ( distance myself )]
end
The reported returns the patch with the highest influence/distance value that is not a member of the turtle's visited-list. Initially, no patches are a member of the list, but as the turtle visits each target, it adds the target to the visited-list so that patch is no longer considered.

How to stop turtles when all patches have been colored

When the turtles have covered the world in patches, I would like the turtles to stop on the last one so that I can record the amount of ticks it took.
Here is my code so far:
globals [marked-patches angle nextangle]
to setup ca ask patches [ set pcolor black ] crt turtle_amount
[set color red
set size 1
setxy (random 20) (random 20)] reset-ticks
end
to go ask turtles [
fd 1
rt random trt_ang
lt random trt_ang
if pcolor = black [set pcolor yellow] ]
tick end
In go, specifically in the turtle command, you can add:
to go
ask turtles [
fd 1
rt random trt_ang
lt random trt_ang
if pcolor = black [
set pcolor yellow
if count patches with [pcolor = black] = 0 [
stop
]
]
]
tick
end

Define home area-turtles?

I am very new to netlogo. I have searched every question here before I posted this.
I have the following code which sprouts a given number of horses:
ask n-of Number-horses patches with [grass? = "Yes"]
[sprout-horses 1 [set color 25 ]]
The person can change the number of horses using the slider but I would like each horse to have its own area/range/radius.
They can only move within this radius/area and they cannot meet each other.
From what I've read it's got something to do with the distance function?
You can find a similar problem here which has examples too :
Spacing agents in NetLogo based on territory size
There are several ways that you can assign a territory zone to each horse, but all methods that I know have two steps, first step is in order to make sure initial home area of horses are separated from each other , So we need to create horses only in patches which has a certain distance from another patch which has a horse on it,I did not follow your method that asked patches to sprout horses and instead I created them without asking patches.
I was not sure how you defined grass? Variable for each patch but I have assigned a number of patches with grass? = true and others false.
Second step is to set home-area property of each horse. If initially you moved them far away from each other they will have separate territories.
I have included a few examples here :
First to use in-radius for both steps:
Breed [Horses horse]
Horses-own [home-area]
patches-own [grass?]
globals [Zone-Radius]
to setup
clear-all
reset-ticks
set Zone-Radius 2
ask patches
[
ifelse pxcor mod 5 = 3
[ set Grass? true ]
[ set Grass? false ]
]
create-horses Number-horses
[ Move-to one-of patches with [Grass? and not any? other horses in-radius (Zone-Radius + 1)]
set home-area patches in-radius Zone-Radius
set color 25
]
end
to go
ask horses [
ifelse member? patch-ahead 1 home-area
[rt random 10 fd 1 ] ; move if next patch is in their zone
[rt random 180]
]
tick
end
In this example horses only move in the patches in their radius 2. But you can change that base on your model requirements.
In the second method you can use distance for the first step (finding empty patches with enough distance to current patch) and radius for second one (assigning home-area to each horse).
Move-to one-of patches with [Grass? and not any? other horses with [distance myself < (Zone-Radius + 1)]]
set home-area patches in-radius Zone-Radius
If you use higher distance for finding empty patches you will have completely seprated zones. Finally , you can use distance for both steps:
Move-to one-of patches with [Grass? and not any? other horses with [distance myself < (Zone-Radius + 1)]]
set home-area patches with [distance myself < Zone-Radius]
I just did it another way:
Breed [Horses horse]
Horses-own [home-area]
patches-own [ concession? forest? parks?]
globals [Zone-Radius]
to setup
clear-all
reset-ticks
set Zone-Radius 2
ask n-of 500 patches [ set concession? "No" ]
ask n-of 500 patches[ set forest? "Yes" ]
ask n-of 500 patches[ set parks? "Yes"]
let i 0
while [i < Number-horses]
[
ask one-of patches with [(concession? = "No" or forest? = "YES" or parks? = "YES" ) and (not any? horses in-radius (Zone-Radius + 2) )]
[
sprout-horses 1 [
set home-area patches with [distance myself < Zone-Radius]
let w who
ask home-area [set pcolor red]
set color 25 ]
]
set i (i + 1)
]
end
to go
ask horses [
ifelse member? patch-ahead 1 home-area [rt random 10 fd 1 ] [rt random 180]
]
tick
end
As you can see I used while and a condition to ask patches one by one, I might be mistaken but when I ask all the n-of Number-of-horses patches with [YourCondition][...] I get the wrong results and distance between horses is not effective, maybe they are created all at the same time and therefore upon creating a horse there was no horse nearby!? I am new to these concepts and might be wrong.
This is the code and view for the one which asks patches to create horses at once here :
Breed [Horses horse]
Horses-own [home-area]
patches-own [ concession? forest? parks?]
globals [Zone-Radius]
to setup
clear-all
reset-ticks
set Zone-Radius 2
ask n-of 500 patches [ set concession? "No" ]
ask n-of 500 patches[ set forest? "Yes" ]
ask n-of 500 patches[ set parks? "Yes"]
ask n-of number-horses patches with [(concession? = "No" or forest? = "YES" or parks? = "YES" ) and (not any? horses in-radius (Zone-Radius + 2) )]
[
sprout-horses 1 [
set home-area patches with [distance myself < Zone-Radius]
let w who
ask home-area [set pcolor red]
set color 25 ]
]
end
to go
ask horses [
ifelse member? patch-ahead 1 home-area [rt random 10 fd 1 ] [rt random 180]
]
tick
end