NetLogo: Having a turtle remember its starting location - netlogo

I want to have my turtles move back and forth between a central area and their starting location. I have set the central area (patch 0 0, and its neighbouring patches). I have set these turtles to begin from random locations on setup.
Now I need them to move to the central area and be able to remember and return to their respective starting positions. Here is my attempt, but one that is not working.
ask patches
[ set target-patch patch 0 0
ask target-patch
[ set pcolor green
ask neighbors [set pcolor green]
set hold-time 5
]
]
create-turtles 10
[ set shape "car"
set size 1
set color white
setxy random-xcor random-ycor
if (patches != patches with [pcolor = green])
[ set start-position (random-xcor random-ycor)] ;; line with error
]
to go
ask turtles
[ set heading target-patch move-to target-patch
set hold-time hold-time + 5
]
ask turtles
[ if hold-time >= 10
[ set heading start-position move-to start-position]
]
end

There are several problems with your code. I strongly suggest that you code in smaller pieces. That is, add some code and make sure it works before writing the next piece. Making sure it works is not just making it through without error messages, it needs to do what you expect it to do.
On your specific question. The line if (patches != patches with [pcolor = green]) is causing an error. First, patches is the set of all patches, not just a particular patch. So you are (sort of) asking whether the set of all patches is not equal to the set of patches that are green. Is that really what you intended? If so, it is easier to simply ask whether there is any patch that is not green:
if any? patches with [pcolor != green]
or to check whether they are all green and continue if not:
if not all? patches [pcolor = green]
However, since you are asking about moving back and forth to and from the central green patches, I think you really want to have the turtle check whether the patch they happen to be located on is green. This code looks at the patch where the turtle is located (patch-here) and checks whether the color (pcolor) is green:
if [pcolor] of patch-here = green [ ]
However, one of the tricks of NetLogo is that turtles can access the variables of the patch they are on directly. Note that a patch cannot access a turtle's variables because there may be multiple turtles on the patch so the patch doesn't know which turtle you want. But a turtle can only ever be on one patch at once. So you could write:
if pcolor = green [ ]
You also need to rethink this code:
ask patches
[ set target-patch patch 0 0
ask target-patch
[ set pcolor green
ask neighbors [set pcolor green]
set hold-time 5
]
]
This suggests to me that you have misunderstood something very fundamental to NetLogo programming. You need to think from the perspective of an individual agent. Looking at this code, you first do ask turtles, so that is going to run through all the turtles in random order. Let's call them A, then B, then C and so on.
What is each turtle going to do? Everything in the [ ]. So, A sets the value of the global variable named "target-patch" to patch 0 0. Then A asks that patch to turn green, have the 8 surrounding patches to turn green, and to set the variable "hold-time" to the value 5.
So far, so good. But then turtle B does exactly the same thing - it assigns "target-patch", turns it and its neighbors green etc. Then turtle C. If you have 100 turtles, this block of code will run 100 times and do exactly the same thing each time.

Related

How to ask turtles to stop if other turtles go over a certain patch-colour?

How can I tell a turtle to stop moving if there are other turtles going over a certain patch-color?
For example, I told 4 random patches to turn blue. I want a turtle only to be able to go over these blue patches if no other turtles are going over/are at these blue patches.
I already have this, but it does not seem to work:
if any? other turtles-on patches with [pcolor = blue]
[
set speed 0
]

NetLogo - turtles to imprint 'who' on patches and only move-to patches which match their 'who'

I'm working on a land-use model featuring a forested World where turtles (smallholders and companies) have the ability to convert forest into crop-land. I would like to introduce a feature that turtles 'own' the patches they convert and are able to revisit them later to get these patches certified. The main issue is that when turtles move-to crop-land patches to get them certified, they do not only move to those they 'own' but also jump across the world to other turtles' crop-land patches and certify those. I've tried a few different workarounds, but I seem to run into the same two issues eventually:
#1 - error: can't use who in a patch context
I wanted to use the 'who' variable to mark crop-land patches as belonging to the turtle that converted the patch, e.g., turtle 0 goes to the forest, converts it to crop-land and that patch of cropland should be 'owned' by turtle 0, i.e., the patches owned-by variable should be equivalent to the turtle's 'who'. The issue here is that 'who' is a turtles-own variable. So, when I use it in a patch-context it produces an error. For example, ask smallholders [move-to one-of patches with [[owner = who]] --> error.
#2 - can't manage to set a global variable = 'who'
Two, I tried to work around this by using a proxy variable: a globals-variable called 'owner-ID'. I would use set owner-ID who to imprint the turtles individual number to the owner-ID. This seems to work to some extent, namely that the patches' 'owner' variable corresponds to the turtle that converted the patch. It also works when counting how many patches of certified and conventional crop-land turtles own (see set-land-ownership command below). However, when the smallholders-certify-crop-land commands are triggered, turtles don't stick to the patches they own, but 'jump' across the world. When prompting turtles through the command-center ask turtles [print owner-ID] they all return the same owner-ID value. I feel there might be a mistake in my move-to command-line but I just can't find it.
Summary & Question
I want crop-land patches to be 'owned by' the turtles that converted them, and want turtles to move only to the patches they 'own' when certifying crop-land patches, not to patches they don't own. I guess my questions revolve around whether it's possible to somehow use the 'who' variable in a patch-context. And, if not, what a good workaround for the problem could look like.
Relevant code is below (I hope)!
globals [owner-ID]
turtles-own [conventional-land-ownership certified-land-ownership]
patches-own [owned-by owner certified?]
to setup [
ask patches [
set pcolor green ;; green = forest
set certified? "no"
set owner "nobody"
]
]
to go
ask turtles [set-land-ownership]
ask smallholders [check-smallholder-status]
tick
end
to set-land-ownership
ask smallholders [
set owner-ID who
set conventional-land-ownership count patches with [owner = owner-ID and certified? = "no"]
set certified-land-ownership count patches with [owner = owner-ID and certified? = "yes"]
]
end
to check-smallholder-status
if wealth >= 0 and (conventional-land-ownership + certified-land-ownership) < SH_max-land-ownership [
smallholders-choose-activity
]
if wealth < 0 [
set color red
set shape "cow skull"
]
if (conventional-land-ownership + certified-land-ownership) >= SH_max-land-ownership [
set color orange + 2
]
end
;; smallholders-choose-activities is a reporter-based command where turtles choose the most economical option available. One of the outcomes is: smallholders-certify-crop-land
to smallholders-certify-crop-land
let available-patch max-one-of patches with [owner = owner-ID and certified? = "no"] [count neighbors with [certified? = "yes"]]
ifelse not any? turtles-on available-patch [
move-to available-patch
]
[]
set wealth wealth - smallholder-certification-cost
set pcolor brown + 1
set certified? "yes"
end
Your first approach is definitely the way to go and could be fixed with one small adjustment.
ask smallholders [move-to one-of patches with [owner = who]]
should be
ask smallholders [move-to one-of patches with [owner = [who] of myself]]
Within the block after with, variables are in the context of patches, but myself refers to the agent that asked the patches to check their owner, in this case, each smallholder. The global variable owner-ID is then unnecessary. If you carry this through the rest of the code, your second problem may solve itself.
BUT, in general it is best not to use who numbers at all, but rather refer to the agent directly. (You have actually taken that approach implicitly when you initialize owner to nobody, which is "no agent".) I don't see where you ask a patch to set its owner, but if a smallholder is on a patch, the smallholder would
ask patch-here [set owner myself]
and the line above would now read
ask smallholders [move-to one-of patches with [owner = myself]]
The NetLogo gurus suggest that we use who numbers only when there is no other approach.

How would I "target" patches within a certain area?

I have set up agents and nodes to represent people and stores and it is my intention that the agents will "target" the store in their "awareness" space with the highest value ("vulnerability"). I've largely coded what I have so far through trial and error however setting the turtle's target to the patch with the highest value within a 10 unit radius is a hurdle I can't get over. Currently they target the patch with the highest value regardless of its position in the world. Could somebody suggest what I might consider to achieve this please? I have pasted what I have written so far for reference.
Thanks.
breed [shoplifters a-shoplifter]
patches-own [vulnerability]
shoplifters-own [target
awareness]
to setup
clear-all
setup-patches
setup-turtles
reset-ticks
end
to setup-patches
setup-stores
end
to setup-stores
ask n-of num-stores patches [ set pcolor lime ] ;; create 'num-stores' randomly
ask patches [
if pcolor = lime
[ set vulnerability random 100
]
]
end
to setup-turtles
setup-shoplifters
setup-target
end
to setup-shoplifters
create-shoplifters num-shoplifters [ ;; create 'num-turtles' shoplifters randomly
set xcor random-xcor
set ycor random-ycor
set shape "person"
set color red
]
end
to setup-awareness
ask turtles [
set awareness
patches in-radius 10
]
end
to setup-target
ask turtles [
set target
max-one-of patches [vulnerability]
]
end
You are on the right track using max-one-of. At the moment, however, you are sending patches as the space to search through to look for the one with maximum vulnerability value, when you really want patches in-radius 10. So you could simply do this:
to setup-target
ask turtles [
set target max-one-of patches in-radius 10 [vulnerability]
]
end
However, this is going to be inefficient because NetLogo will have to first work out which are the patches within the radius. You have already asked the turtles to work this out and assign it to their variable 'awareness'. What you really want to do is therefore:
to setup-target
ask shoplifters [
set target max-one-of patches awareness [vulnerability]
]
end
Note that I also changed ask turtles to ask shoplifters. It is only shoplifters who have the attribute 'target' so you should only be asking them to calculate it. Same thing goes for 'awareness'. At the moment you don't have any other breeds so it's not causing an error, but it is good practice to use the breed, otherwise there is no point in creating it.

Changing Node ID with every Setup in Netlogo

We try to show a simple infection via Netlogo. For our purpose we need to start the infection with the same turtle for several times.
But right now with every setup another turtle begins with the infection. We already tried to work with the Node ID, but unfortunately the ID of the different turtles changes with every setup, too. We are out of ideas but
maybe there is a way to sove this problem I am happy for any answers :)
This is our Code so far:
extensions [nw]
globals
[
num-informed
informed-size
]
turtles-own
[
informed?
]
to setup
clear-all
nw:load-graphml "JK_nachnamen.graphml"
ask turtles [ set size 1.5 ]
layout-radial turtles links turtle 61
ask turtles [set color red]
ask turtles [set shape "dot"]
ask links [set color grey + 1.5]
ask patches [set pcolor white]
ask turtles [set label-color black]
ask turtles [set informed? false]
ask turtle 72
[
set informed? true
set color green
]
set num-informed 1
set informed-size 2
reset-ticks
nw:save-graphml "JKnachnamennetlogo.graphml"
end
to spread
if (count turtles with [informed? = true] > .7 * count turtles) [stop]
ask turtles with [ informed? = true ]
[
ask link-neighbors with [not informed?]
[
if (random-float 1 <= 0.01)
[
set informed? true
show-turtle
set color green
]
]
]
set num-informed count turtles with [informed? = true]
tick
end
Thank you a lot.
I am a little unclear so am giving bits of different answers for different situations.
If the turtles are different each time, what do you mean by 'the same turtle'. For example, do you mean the turtle in a particular position? If so, you could select the turtle on the appropriate patch.
If it doesn't matter which particular turtle it is (just that it's the same turtle), then the simplest approach is to set the random-seed. Then every time you run any random process (including choosing one-of the turtles to select the starting infection, or ask turtles to do something), NetLogo will use the same chain of random numbers. Of course, if you are still building your model, then adding new pieces of code that change how many calls are made to the random number generator will lead to a different chain, but rerunning with the same code will give the identical run.
You may need to use with-local-randomness and random-seed new-seed if you want to have some parts actually change.
The problem is that nw does not store the WHO variable this is to avoid conflict with already existing turtles in a model.
A work-around would be assigning each turtle a separate id variable and setting that to who.
turtles-own [informed? id]
in turtles creation asign them each the id thus
set id who
you may want to write a conversion procedure like this
to convert
nw:load-graphml "JK_nachnamen.graphml"
ask turtles [set id who]
nw:save-graphml file-name "JK_nachnamen(id).graphml"
end
and use the copy. Of course you would not use
turtle 74
but
one-of turtles with [id = 74]

Why do i get this runtime error when i instruct a turtles to set its heading towards a patch with a certain pcolor?

I want to be make turtles set their heading towards one of the patches that have pcolor = grey in a cone of 1 270 when they are on a patch with pcolor = 6. My code is as follows:
ask turtles[if [pcolor] of patch-here = 6 [ set heading towards one-of neighbors4 in-cone 1 270 with [pcolor] = grey
However I get the error:
TOWARDS expected input to be an agent but got NOBODY instead.
What should be done to the code to prevent this error? Any help would be great.
If you're getting nobody, that means that there isn't always a patch meeting the conditions you have set up.
You need to decide what you want to do in that case. Suppose you decide the turtle should do nothing. Then the new code is:
ask turtles [
if pcolor = 6 [
let target one-of ...
if is-patch? target [
face target
]
]
]
Note that of patch-here is always redundant. A turtle always has direct access to the patch variables of the patch it is standing on.
Note also the use of face, which is more concise than set heading towards.