Is there a way to create an enum in netlogo? - netlogo

I have some netlogo code that I would like to make more descriptive.
So instead of:
MOVE-TO ONE-OF PATCHES WITH [ PCOLOR = BLUE ]
It would say:
MOVE-TO ONE-OF PATCHES WITH [ WATER ]
In java I would create an enum to accomplish this. How can I do it in Netlogo?

Alan's answer is fine, but I would also consider the possibility of creating a patch variable instead of relying on the patch color. For example:
patches-own [ water? ]
If you set this to true for each water patch, you can then say things like:
move-to one-of patches with [ water? ]
The main reason for doing this is that you might want to change the color of the water patches at some point: make them a slightly darker or lighter blue, for example, or use color to temporarily highlight patches with some other characteristic.
Separating presentation and program semantics is generally good practice.
Another, different way to achieve this would be to create an agentset with your water patches during setup. For example, supposing you declare water-patches as a global variable, you would do:
set water-patches patches with [ pcolor = blue ]
And then you can do:
move-to one-of water-patches
The water-patches agentset is not affected if you change the color of a patch. It might also be a bit faster since you only construct it once instead of filtering over all patches over and over again.

to-report water ;patch proc
report pcolor = blue
end

Alan's answer is perfectly fine, but this question suggests to me a different conceptualisation. What you really mean is that the patch is coloured blue because it is water, but you are coding it the other way around so that colour is indicating its status as water. If other aspects of your model (eg travel speed, type of crops) depend on whether it is water or not, then you could consider a different construction.
patches-own
[ water?
]
to setup
ask patches
[ set water? FALSE
if random-float 1 < 0.2
[ set water? TRUE
set pcolor blue
]
]
end
In this construction, you have a true/false variable for each patch that indicates it is water (if true). Then you can directly have statements such as ask patches with [water?] []. You can also set up a global variable that holds the patch-set of water patches and then make statements like ask water-patches []
If you have multiple types of land style (eg water, sand, soil, rock...) then you colour is more likely to be the way to go since you don't want separate variables for all of these. Even then, though, you could have one attribute for land style and have constructions that are ask patches with [ type = "water"]

Related

Can't run Netlogo code - asking turtles to look around themselves and select the lowest patch variable

I am trying to get my turtles to look around themselves in netlogo and select a patch with the lowest slope variable in radius 2 - and if there isn't one to just select any patch.
I check my code, and it says everything is fine, but when I run it I keep getting this error: this code can't be run by a patch - error while patch X X running ifelse - called by procedure move - called by procedure go - called by button "go"
This is my move code:
to move
ask turtles [ask patches in-radius 2
[ifelse slope < 5
[fd 1]
[move-to one-of patches in-radius 2]
]
]
end
I have already tried downhill and downhill4 but my agents seemed to get stuck at the bottom of the slope and couldn't move anywhere.
Thank you for any help and advice!
Thank you - my code now works!
Because you are asking turtles to ask patches, the code inside the ask patches is run by the patch! A patch can’t use turtle variables, and doesn’t know that you mean to refer to the variables of the turtle that asked the patch.
This is what “of myself” is for. It lets an agent (self) talk to the agent that is telling it what to do. You’ll see stuff like “set heading [heading] of myself” But that’s not what you need here.
we could use an ask patches like you are doing here, but we really don’t want them to do anything, and it’s going to make the code much more complex looking. Anyway, We just want to find a patch that meets the turtle’s needs and move to it.
So instead. We can query the nearby patches using a WITH and store the set of patches found in a “patch set” variable.
If there are any, we can move to one of them.
Else, we can just move forward.
So
To move
Ask turtles
[
;; here the turtle tells patches to test the patch’s own slope
Let good-spots patches in-radius 2 with [ slope < 5 ]
;; are there some patches that pass the test?
If-else any? Good-spots
[ ;; Yes, pick one and go there
move-to one-of good-spots
]
[ ;; No, just move forward
Fd 1
]
]
End
Edit to add : Matteo’s answer correctly identifies the actual requirement, based on the question: move directly to the flattest patch, versus what the code above does, move to one of the flatter patches, if there is one.
Move-to min-one-of patches in-radius 2 [ slope ]
As you noted, This is similar but not identical to
Downhill slope
And neither of these may prevent turtles from getting stuck in a pit. You may need more code to detect pits and jump out of them.
The problem is not about variables but about commands: you are asking patches to run forward or to run move-to, while these are turtles' commands.
Now, for the purpose of the question, there is another issue: you said that you want
turtles to look around themselves in netlogo and select a patch with the lowest slope variable in radius 2 - and if there isn't one to just select any patch
However, even if we ignore the problem about asking patches to run forward or move-to, the structure of your code implies something very different. Your code seems to intend:
Turtles, check if there are any nearby patches with slope lower than a specific threshold;
If there are, move forward in whatever direction you are already facing;
If there are not, move to a random nearby patch.
The solution below is based on the assumption that what you want is what you said, and not what your code seems to imply.
The solution is very simple and only needs min-one-of (check it here):
to move
ask turtles [
move-to min-one-of patches in-radius 2 [slope]
]
end
As a demonstration, consider this full example:
patches-own [
slope
]
to setup
clear-all
ask patches [
set slope random 10 + 5
set pcolor scale-color green slope 5 14
]
create-turtles 10 [
setxy random-xcor random-ycor
set color yellow
]
end
to go
ask turtles [
move-to min-one-of patches in-radius 2 [slope]
]
end
You will see that turtles tend to go to darker patches, that are those with lower slope.

Moving turtles towards two different colors of the patch in NetLogo

I have a basic NetLogo question.
I would like to encode the following:
The turtle asks what color the patch is in if it is green, it can walk on the green patches.
I know it is a basic question of NetLogo. But, I'm trying and some errors appear, such as: MOVE-TO expected input to be an agent but got NOBODY instead
Could someone help me understand what I am wrong with, or give any suggestions or even models that do this for me to explore? Every help is welcome. Thanks
globals [ edge-size ]
to setup
clear-all
set edge-size 10
set-patch-size 20
let pcolors []
set pcolors [135 55 105 85]
ask patches [
set pcolor item (random 4) colors
]
crt 1 [
set size 1
set color black
;pen-down
]
reset-ticks
end
to go
ask turtles [
if pcolor = green ;; if own pcolor patch = green
[ move-to one-of patches with [ pcolor = "green" ] ]
end
This code move-to [ veg ] of patch-under-me suggests you have several fundamental misunderstandings about how NetLogo thinks. I recommend that you do some more of the tutorials and look at the Model Library built in to NetLogo to find models that are similar to what you want to do. You also need to build in much smaller pieces and get a piece working properly before moving to the next piece.
What is wrong with move-to [ veg ] of patch-under-me?
[ veg ] of patch-under-me is a variable with values like pink or green. So you are saying 'move to green'
What's more, the colour that it gives back is the colour where the turtle is standing now, not where you want it to go to
You probably want something more like:
move-to one-of patches with [veg = "green"]
So go back to basics. Have just two colours (say red and blue) and move turtles around trying to get onto a red patch. Make that work before doing anything else. Now have only a few red patches, does your code still work? Then you can start adding a bunch of different conditions and colours

NetLogo: Having a turtle remember its starting location

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.

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.

simultaneously coordination in Netlogo

I'm currently trying to implement a model in Netlogo where the turtles’ behaviors depend on all of their neighbors.
My point of departure is the coordination game code provided by:
http://modelingcommons.org/browse/one_model/2549#model_tabs_browse_info
According to this model the payoff of for the turtle is determined by introducing a variable which takes the color of neighbor as its value.
ask turtles [
let his-color [color] of one-of turtles-on neighbors
if color = yellow and his-color = yellow [set payoff A-yellow-yellow set alt-payoff B-red-yellow]
However, I need to my turtles to gain their payoff by comparing their color with all of their neighbors simultaneously. The last part is problematic due to Netlogo's default synchronic update
Can anyone guide me in how to make the update simultaneously and depending on all of the neighbors, or does someone have a reference to a place where this is discussed?
Just collect all colors before changing any of them. E.g.,
turtles-own [nbr-colors]
to go
ask turtles [
set nbr-colors [color] of neighbors ;get list of current colors
]
ask turtles [
set payoff compute-payoff nbr-colors
set color anything-you-want
]
end