I am trying to get the first turtle to arrive at a specific patch (food source 1) to become a new breed (leader). This is what I tried so far...
ask one-of followers
if followers-at -41 -22
set breed [leaders]]
That gives me the error: Ask expected 2 inputs, an agent or agentset and a command block.
If I add a bracket before if --> [if...], the error becomes
IF expected two inputs, a true false and a command block.
Right now I have create-leaders 0 [set color red] in the to setup procedure, and a leader [leaders breed] at the beginning of the code, because I don't want any leaders to exist before the first turtle reaches food patch -41 -22. I'm still at a loss for how to determine which turtle is the first to arrive at that patch. Any suggestions for that?
I tried this to test whether I could get one follower at a specific patch to change:
to recruit
ask followers-at -41 -22
[ask one-of followers
[set color red]]
end
First, I counted 4 red followers during the course of the run, but the code specifies "one-of" which should only affect 1 follower. Then I modified it to:
to recruit
ask followers-at -41 -22
[ask one-of followers]
[set breed [ leaders ]
end
which doesn't seem like it has the right number of brackets, but is the only way that I don't get an "error no closing bracket" message. Instead, I get "Ask expected 2 inputs, an agent or agentset and a command block."
This is the way the bracketing would work (note that the spacing is not important for syntax, but I structured it so you could see where the code blocks start and end). I also added an any?:
ask one-of followers
[ if any? followers-at -41 -22
[ set breed leaders
]
]
So, the ask is asking one of the turtles of the breed named 'followers' to do everything in the outer code block. The randomly chosen turtle then checks if there are any 'followers' on the patch at coordinates -41 -22 from itself (relative, not absolute). If there are, then the randomly chosen turtle (not the ones on the specified patch) changes its breed to leaders.
What you probably want is to have one of the followers on the patch change breed. That would look like:
if any? followers-on patch -41 -22
[ ask one-of followers-on patch -41 -22
[ set breed leaders
]
]
So I changed turtles-at (relative) to turtles-on (absolute) position, as well as going to the turtles on the relevant patch.
For efficiency (so set of turtles created only once instead of twice), debugging (so you don't accidentally have different coordinates in the two places), a better way of doing this same code is:
let potential-leaders followers-on patch -41 -22
if any? potential-leaders
[ ask one-of potential-leaders
[ set breed leaders
]
]
As for finding out whether it's the first, all you need to do is check that there aren't any existing leaders as part of your conditions (eg not any? leaders)
Related
In brief below is the code I wrote to show whether there is a turtle on the neighbor patches
to play-the-game
ifelse any? turtles-on neighbors4
[show "turtles-found"]
[show "turtles-not-found"]
end
I need to change it to perform the procedures I have already written out;
if they are the same breed they 'gain-energy'
different breed 'fight-opponent'
I am not sure as to how to change the first part to carry out the other procedures.
If I understand correctly, you need to check the breed of both the asking turtle and the 'opponent' turtle. You're certainly on the right track by checking if there are any neighbors present, the next step is to make the breed check and then the turtles can choose what action to take. For example, look at this toy model where wolves and cows can identify whether they've landed on a patch next to the same breed or not:
breed [ cows cow ]
breed [ wolves wolf ]
to setup
ca
ask n-of 10 patches [
sprout-cows 1 [
set shape "cow"
set color white
]
]
ask n-of 10 patches with [ not any? turtles-here ] [
sprout-wolves 1 [
set shape "wolf"
set color red - 1
]
]
reset-ticks
end
to go
ask turtles [
face one-of neighbors
fd 1
play-the-game
]
tick
end
to play-the-game
if any? turtles-on neighbors4 [
let current-neighbor-turtle one-of turtles-on neighbors4
ifelse [breed] of current-neighbor-turtle = breed [
show "I see one of my own breed!"
] [
show "I see an opponent!!!"
]
]
end
If that's not quite what you had in mind, please edit your question above to provide more detail.
I think you should consider dropping ifelse. In your example, the two possible outcomes of the any? turtles-on neighbors4 condition are mutually exclusive: either there are turtles, or there are not.
However what you want to achieve in your model is a bit different: (I imagine that) on the neighboring cells there can be turtles of the same breed AND turtles of a different breed at the same time. In this case, the two scenarios are not mutually exclusive and using ifelse (where only one or the other of the two command blocks will be executed) would potentially overlook one of the two cases, depending on how you specify the condition.
I think two if statements would be more appropriate:
to play-the-game
if (any-friends-nearby?) [gain-energy]
if (any-opponents-nearby?) [fight]
end
to-report any-friends-nearby?
report (any? (turtles-on neighbors4) with [breed = [breed] of myself])
end
to-report any-opponents-nearby?
report (any? (turtles-on neighbors4) with [breed != [breed] of myself])
end
It is still relevant for you to choose which condition will be checked first (and therefore which action, between gain-energy and fight, will be executed first in case both conditions are satisfied)
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.
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.
I'd like to have patches count the number of turtles that have stood on them. What would be ideal is a event such as:
if turtle-lands-on-me [add one to count]
because a turtles could leave and come back and be counted twice (which is what I want) and it would avoid counting turtles who stand still twice or more (which I don't want). Is there any way to achieve this?
Thank you!
What you need is a variable for each patch (I am calling it 'landed' below). The following code assumes you want to know about the patch it lands on each time step, but ignores the ones it passes over. It also updates the counts only where the turtle changes the patch, as requested, and labels the patch with the count.
patches-own [landed]
to setup
create-turtles 20
[ setxy random-xcor random-ycor
]
end
to go
ask turtles
[ let old-patch patch-here
set heading random 360
forward one-of [0 0.5 1 3]
if old-patch != patch-here
[ ask patch-here
[ set landed landed + 1
]
]
]
ask patches [set plabel landed]
end
The problem is that a turtle can pass over multiple patches during one time step. You can see this in the example model for those turtles that move 3. If you also want them, you will need to do something like the 'Line of Sight' model in the NetLogo models library.
to setup-lava
ask n-of lava patches [set pcolor orange]
ask men [die]
end
When I ask the men to die when they stand on a lava patch Netlogo gives me and error saying 'expected a number here, rather than a list or block'.
You haven't told us what lava is, but the error message suggests it is not a number. If you look in the NetLogo Dictionary, you will see that n-of must be followed by a number and then the agentset to tell NetLogo how many of the agentset to select.
Choice 1: assumes that lava-patches is a variable with a number in it (eg a slider on your interface)
to setup-lava
ask n-of lava-patches patches
[ set pcolor orange
ask men-here [die]
]
end
Choice 2: lava? is an attribute of patches that flags whether it is lava and that you have (somewhere else in your code) set that flag for lava patches
to setup-lava
ask patches with [lava?]
[ set pcolor orange
ask men-here [die]
]
end
Neither of these are tested