I have turtles with a memory that stores the coordinates of patches they travel:
turtles-own [
memory
]
to setup
clear-all
create-turtles 1 [
set memory (list)
]
end
to go
ask turtles [
right random 360
move-to patch-ahead 1
set memory (lput patch-here memory)
]
end
From this list, I want to ask something to any patches that have these coordinates and are white. I was trying:
ask patches at-points memory with [pcolor = white] [do-something]
But getting the error
Invalid list of points [(patch 0 1)]
How can this be fixed?
Fix it with:
set memory (lput ([list pxcor pycor] of patch-here) memory)
Your answer works so feel free to ignore this. I just thought I'd offer you a few more options.
The problem with your original code is that you are not storing coordinates in a list but rather are storing patches in a list.
To work with agents that you have stored in a list, you will need to use foreach. This allows you to cycle through all agents in the list and ask them indidivually to change their color.
to change-pcolor-list
ask turtles [
foreach memory [
the-patch -> ask the-patch [set pcolor white]
]
]
end
Another option is to store all the patches a turtle passes through in a turtles-own agent-set. This allows the turtles to call upon all the patches simultaneously instead of patch by patch and allows you to bypass the need for using anonymous procedures (which is what foreach uses).
turtles-own [
memory-2
]
to setup
clear-all
create-turtles 1 [
set memory-2 (patch-set)
]
end
to go
ask turtles [
right random 360
move-to patch-ahead 1
set memory-2 (patch-set memory-2 patch-here)
]
end
to change-pcolor-agentset
ask turtles [
ask memory-2 [
set pcolor white
]
]
end
Related
I am trying to spawn turtles 5 patches away from each other but I'm not sure how, right now they all spawn on green patches (I don't want them to spawn on brown ones) and I'm not sure how exactly you control the distance between the spawning of turtles, thanks.
breed [ humans person ]
breed [ zombies zombie ]
to setup_world
clear-all
reset-ticks
ask patches [
set pcolor green
]
ask n-of 100 patches [
set pcolor brown
]
ask n-of 15 patches with [pcolor != brown][sprout-humans 1 [set size 5
set color blue
set shape "person"]]
ask n-of 5 patches with [pcolor != brown][sprout-zombies 1 [set size 4
set color red
set shape "person"]]
end
Have you read this question: NetLogo Create turtle at regular distance from each other?
Anyway, I thought that showing you some working functions would be helpful, here I made two alternatives, sprout-distanced1 and sprout-distanced2, you can test them both by alternating which line is commented; I also added a slider called Min-Distance to control the turtles spacing.
sprout-distanced1 uses the keyword carefully with is basically a try-else block, it's there in case that the turtle doesn't find a patch distanced enough to move to, in which case rather than sending a warning the turtle will stay where it is and print its distance to the closest turtle.
sprout-distanced2 uses a while loop, in case that the turtle doesn't find a place to move to that is at least Min-Distance from another turtle it will reduce the minimum radius by a small amount until it can distance itself from other turtles, if it had to move to a patch where it is less than Min-Distance away from other turtles it will log the distance at the Command Center.
breed [ humans person ]
breed [ zombies zombie ]
to setup_world
clear-all
reset-ticks
ask patches
[
set pcolor green
]
ask n-of 100 patches
[
set pcolor brown
]
ask n-of 15 patches with [pcolor != brown]
[
sprout-humans 1
[
set size 5
set color blue
set shape "person"
;sprout-distanced1
sprout-distanced2
]
]
ask n-of 5 patches with [pcolor != brown]
[
sprout-zombies 1
[
set size 4
set color red
set shape "person"
;sprout-distanced1
sprout-distanced2
]
]
end
to sprout-distanced1
carefully
[
; try to move at least Min-Distance away from other turtles
move-to one-of patches with [not any? other turtles in-radius Min-Distance]
]
[
; if can't move Min-Distance away from other turtles
; stay put and log the min distance to other turtle, just for reference
show distance min-one-of other turtles [distance myself]
setxy random-xcor random-ycor
sprout-distanced1
]
end
to sprout-distanced2
let min-dist Min-Distance
let moved? FALSE
while [not moved? and min-dist > 0]
[
; can distance it self somewhere?
ifelse any? patches with [not any? other turtles in-radius min-dist]
[
; if yes, go there
move-to one-of patches with [not any? other turtles in-radius min-dist]
set moved? TRUE
; if had to reduce the distancing radious log it
if moved? and min-dist < Min-Distance
[
show distance min-one-of other turtles [distance myself]
]
]
[
; no where to go, reduce the distancing radious
set min-dist min-dist - 0.1
]
]
end
Choose whichever suits better your model.
How do I get a patch set that contains all patches that the turtle is facing?
I know patch-ahead report the patch with a specific distance. But what if I want to get all patches in this direction instead of the single one with specific distance?
What you can do is hatch a turtle and move it forward until it reaches the edge of the world, adding all the patches it crosses.
Here's a visible version to see the approach:
to testme
clear-all
create-turtles 1 [setxy random-xcor random-ycor]
ask one-of turtles
[ set pcolor red
hatch 1
[ while [can-move? 1]
[ forward 1
set pcolor red
]
die
]
]
end
To actually do the patchset version, you need to start with the current patch and add the patches as the hatched turtle moves over them. Try this for a procedure version and a demonstration of how it can be used:
turtles-own [ my-path ]
to testme
clear-all
create-turtles 1 [setxy random-xcor random-ycor]
ask one-of turtles
[ set my-path get-patches-forward self
print my-path
]
end
to-report get-patches-forward [ #me ] ; turtle procedure
let front-patches patch-here
hatch 1
[ while [can-move? 1]
[ forward 1
set front-patches (patch-set front-patches patch-here)
]
die
]
report front-patches
end
This will return the wrong answer if the world is wrapped because the hatched turtle can keep on going indefinitely. Instead, you would need to check its coordinates rather than relying on the can-move? primitive.
I want to select the network neighbours filtered by a link attribute rather than a turtle attribute. For example, this might be selecting only the closest friends based on a strength score on the friendship link. I could do this by having different link breeds for close friends, but this would require constantly changing breeds as the condition was or was not required.
Below is an example with a boolean condition.
links-own [flag?]
to testme
clear-all
ask patches [set pcolor white]
create-turtles 20
[ setxy 0.95 * random-xcor 0.95 * random-ycor
set color black
]
ask n-of 3 turtles [set color red]
repeat 40
[ ask one-of turtles
[ create-link-with one-of other turtles
[ set flag? random-float 1 < 0.4
set color ifelse-value flag? [red] [gray]
]
]
]
; colour-neighbours
colour-neighbours2
end
to colour-neighbours
ask turtles with [color = red ]
[ ask my-links with [flag?]
[ ask other-end [ set color blue ]
]
]
end
to colour-neighbours2
ask turtles with [color = red ]
[ ask turtle-set [ other-end ] of my-links with [flag?]
[ set color blue ]
]
end
I am currently doing the equivalent of colour-neighbours, but it involves stepping through several contexts. The colour-neighbours2 version is conceptually closer because it is referring directly to the network neighbours. However, because of the of, I get a list of neighbours that I then have to convert to an agentset.
This is for teaching and, while both work, they seem very convoluted when compared to the unconditional network neighbourhood with the link-neighbors primitive. That is, if I didn't care about the flag, I could simply say ask link-neighbors [ set color blue ].
Is there a more direct way to identify network neighbours conditional on a link attribute?
You already cover most possibilities. Another way to do it would be:
to colour-neighbours3
foreach [ other-end ] of my-links with [ flag? ] [ t ->
ask t [ set color blue ]
]
end
I would avoid colour-neighbours2 because, as you stated, it requires the conversion from a list to an agentset. Whether you should use colour-neighbours or colour-neighbours3 is, I think, a matter of personal preference.
Just to add a more-convoluted (worse?) option that uses an agentset:
to colour-neighbours4
ask turtles with [ color = red ] [
let flag-links my-links with [flag?]
ask link-neighbors with [ any? my-links with [ member? self flag-links ] ] [
set color blue
]
]
end
I would like to create some turtles in a radius of another breed agent.
I have this example code:
breed [ readers reader ]
undirected-link-breed [ rris rri ]
breed [ tags tag ]
to setup
clear-all
set xy-file "locations.txt"
setup-readers
setup-tags
end
to setup-readers
create-readers num-readers [
set shape "circle"
set color white ; means idle state 'red' is active
setxy random-xcor random-ycor
]
end
to setup-tags
create-tags tag-population [
setxy random-xcor random-ycor in-radius 6 of one-of readers
]
end
The line setxy... to place the tags in a circle of distance 6 from one of the readers it does not work, but I do not know how to fix it. I have also tested move-to primitive without good result.
What I would like is to have a population of tags in a radius of each reader and if possible select the number of tags for each reader to be different.
The sprout primitive might get you what you need- instead of creating your tags and then moving them, just have the appropriate patches spawn them directly. For example, with this setup:
breed [ readers reader ]
breed [ tags tag ]
to setup
clear-all
setup-readers
setup-tags
reset-ticks
end
to setup-readers
create-readers 5 [
set shape "circle"
set color white
setxy random-xcor random-ycor
]
end
You can make a population of patches that are within the radius of readers and have however many you like sprout a tag:
to setup-tags
let radii-patches patch-set []
ask readers [
set radii-patches ( patch-set radii-patches patches in-radius 6 )
]
; Code above defines the patch-set of patches within 6 of readers
; Then, just ask 10 of those radii patches to sprout a tag
ask n-of 10 radii-patches [
sprout-tags 1
]
end
If you are doing this on a per-reader basis and you want each to have a different number of tags, you could try something like:
to setup-tags-reader
let n-tag random 5
ask readers [
ask n-of n-tag patches in-radius 6 [
sprout-tags 1
]
]
end
but then set the n-tag value some other way (for example, from another .csv file as you seem to be setting reader location).
Side note- when you post on here try to strip out any code than cannot be directly copied and pasted into Netlogo by other users (eg the 'xy-file' line, the tag-population and num-readers variables)- it just makes things super simple!
Edit
As per your comment- try this option (using the same setup as above)
to setup-tags
create-tags 10 [
move-to one-of readers
rt random-float 360
fd random-float 6
]
end
This just creates tags, moves them to a reader, has them randomly select a direction, then has them step forward a random amount from 0 to 6.
As to how to assign patches to each reader- just make a readers-own variable then have them assign patches to that variable in their setup (eg, set my-patches patches in-radius 6). You could do a similar thing with tags to define a reader-specific set of tags (eg `set my-tags tags in-radius 6). Note that in both cases you can get overlap where two readers share patches/tags- you will have to account for that.
Readers,
I'm a beginner in NetLogo. Please help me in solving few issues with my code that is below:
I'm getting an error "You can't use tick in a turtle context, because tick is observer-only.
I need to get tick value updated after each turtle go all three of "arrive-reception, arrive-triage, go-drroom".
the rest of people is not moving around the arrive reception, arrive triage is running.
to setup-people
set-default-shape turtles "person"
set destination ( patch-set patch -2 34 patch 8 34 )
create-turtles uninfected
[ set color blue
allocate-turtles
]
create-turtles infected
[ set color red
allocate-turtles
]
end
to allocate-turtles
if (pcolor = 9.9 and any? turtles-here)
[
set size 1.5
set heading 0
setxy int random-xcor int random-ycor
]
end
to go
move-people
arrive-reception
arrive-triage
go-drroom
tick
end
to move-people
ask turtles [
rt 360
forward 1
]
end
to arrive-reception
ask n-of (random count turtles) turtles
[
if windows = 1
[
move-to patch -2 34
ifelse not any? turtles-here
[ wait wait-time ]
[ wait-in-queue ]
]
]
end
to wait-in-queue
set arrival-time ticks
bk 1
if any? other turtles-here
[ wait-in-queue ]
wait wait-time
if ticks - arrival-time > wait-time
[ set arrival-time 0
fd 1 ]
end
to arrive-triage
if triage = "Open"
[
move-to patch 26 11
if any? other turtles-here
[ wait-in-queue]
wait wait-time
move-to one-of patches with [pcolor = 109 and not any? other turtles-here ]
wait wait-time
]
end
to go-drroom
move-to one-of patches with [pcolor = 128]
if ( min-one-of other turtles in-radius 5 [distance myself] != nobody)
[
move-to one-of patches with [pcolor = 129]
if ( min-one-of other turtles in-radius 5 [distance myself] != nobody)
[
move-to one-of patches with [pcolor = 5]
if any? seats with [turtles = nobody]
[
move-to one-of max-n-of 6 neighbors [seats]
]
]
]
wait wait-time
die
end
Thanks.
First, some basic programming tricks - don't write so much before trying to debug. If you make a small change and check it, then it's easy to work out where the error is. The first draft of a procedure can be as simple as:
to go-drroom
end
and then fill in the details of what happens in the procedure later.
Typically this error is because you forgot to close a bracket somewhere. That is, one of the procedures starts with ask turtles [ ... and there is no ] so NetLogo is still thinking that the code applies to turtles. However, I can't see an obvious missing ].
But you do have a conceptual problem. The term context is used in NetLogo to refer to who is asking the code to be done and to whom. So ask turtles [ forward 1] is the observer asking the turtles to move and is an observer context procedure. You are not thinking about what context you are in when writing the procedures, and this is probably what is setting off your error.
In the go procedure, you first call move-people. This does ask turtles [ ] so is (appropriately) from the observer context. Then you call arrive-reception and it is also okay.
But then you call arrive-triage and go-drroom still from the observer context and have commands like move-to. Who is being asked to move? You don't have ask turtles .... On the other hand, the procedure wait-in-queue has commands like move-to, but it is fine because it is only called from within an ask turtles ... in the arrive-reception procedure.