I want to move turtles to one of patches not fully occupied (n-jobs-to-fill != 0). The code is
ask turtles [move-to one-of patches with [n-jobs-to-fill != 0]
After each allocation turtle-patch, n-jobs-to-fill (that works like a counter) counts one place less
ask patches [set n-jobs-to-fill n-jobs-to-fill - 1]
Can you help me to do that iteratively (for each tick) and to test it by printing each movement turlte-patch in the observer line?
Thank you
The part where you ask patches to update their variable should not be done with a general ask patches, as this will target all patches and either be called too seldom (if you do it just once per iteration of go) or too often (if you do it every time a specific patch receives a turtle).
To easily target the specific patch that just received a turtle, and exactly the amount of times that it receives a turtle, make the moving turtle ask its new patch to perform the update. Or even better: given that turtles can directly access the patches-own variables of the patch they are standing on, you can do:
patches-own [
n-jobs-to-fill
]
to setup
clear-all
reset-ticks
ask patches [
set n-jobs-to-fill random 10
]
create-turtles 10
end
to go
if (not any? patches with [n-jobs-to-fill != 0]) [stop]
ask turtles [
if (any? patches with [n-jobs-to-fill != 0]) [
move-to one-of patches with [n-jobs-to-fill != 0]
set n-jobs-to-fill n-jobs-to-fill - 1
show (word "I moved to " patch-here ", which now has " n-jobs-to-fill " jobs to fill")
]
]
tick
end
Related
I am very new to Netlogo and I am trying to simulate culling of turtles within a certain region based on the characteristics of the patch. Within my model landscape, I have one single patch that is orange. I want 50% of turtles within 5 pixels of that patch to die. I would also like this process to continue every year after the first year of the simulation (this part I think I have). Can anyone help me?
if d = 10 [
if year >= 2 [
let ring nobody
set ring patches in-radius 5 patches with [pcolor = orange]
ask turtles-on ring [die]
]
]
in-radius reports agents that are within a certain distance from the caller, so the orange patch must be the one calling in-radius.
The code in your example is not reproducible, so I'll make an arbitrary example:
to setup
clear-all
ask one-of patches [
set pcolor orange
]
create-turtles 100 [
setxy random-xcor random-ycor
]
end
to go
ask patches with [pcolor = orange] [
ask turtles-on patches in-radius 5 [
if (random 2 < 1) [die]
]
]
end
Note that in-radius reports agents within a certain distance, where the unit of measure of distance is a patch`s side.
Identifying patches within a certain distance and then asking all turtles on those patches to die (as in the example above, which follows the approach in your question) has a different effect than asking all turtles within a certain distance to die.
Which of the two approaches fits your case is something that you have to decide. Below, the code that would address turtles directly:
to go
ask patches with [pcolor = orange] [
ask turtles in-radius 5 [
if (random 2 < 1) [die]
]
]
end
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 compare the patches in a certain radius regarding the amount of a certain class of agents on them. The agents should move to the patch where the most agents (in this case humans) are. If they are already on the patch with the most humans then they must not move. I coded it and the humans group but most of them don't stay and run around in lines (one behind the other). Would be great if anyone of you could have a quick look at my code. Thanks
if Strategy = "Gathering-Simple" [
if ((count(humans-on max-one-of patches in-radius rad [count(humans-here)] )) ) >= count(humans-here) [
if count(humans-on patches in-radius rad) - count(humans-here) > 0 [
face max-one-of patches in-radius rad [count(humans-here)]
fd 1
]]
]
This is a complete working example that uses your code. Is this displaying the behaviour you mean? It does have turtles chasing each other.
to setup
clear-all
create-turtles 100 [ setxy random-xcor random-ycor ]
reset-ticks
end
to go
let rad 5
ask turtles
[ let target-patch max-one-of patches in-radius rad [count turtles-here]
if count turtles-on target-patch >= count turtles-here ; comment 1
[ if count turtles-on patches in-radius rad > count turtles-here ; comment 2
[ face target-patch
forward 1
]
]
]
tick
end
If so, have a look at the two lines I have comments on.
Comment 1: The >= means that, even if the turtles are already on the highest count patch, this condition will be satisfied because count turtles-here will be equal to the count of the turtles on the highest count patch (this patch).
Comment 2: This line means that as long as there are any turtles on any patch within the radius but not on the particular patch where the asking turtle is located, then the turtle will move forward.
If you want to only have turtles move if not on a maximum count patch, try this instead:
to setup
clear-all
create-turtles 100 [ setxy random-xcor random-ycor ]
reset-ticks
end
to go
let rad 5
ask turtles
[ let target-patch max-one-of patches in-radius rad [count turtles-here]
if count turtles-on target-patch > count turtles-here
[ face target-patch
forward 1
]
]
tick
end
I took out the = in the comment 1 line and removed the second condition entirely so now the turtles move if their current patch has fewer (strictly, not <=) turtles than the patch they've spotted.
I agree with the previous post, but have some additional information.
If you want to move entirely to the target patch on each iteration, instead of moving just one step towards the target patch, in the above answer you could replace the code which produces one step of motion
[ face target-patch
forward 1
]
with
[
move-to target-patch
]
I confirmed by experimentation that the results of the two methods of moving will produce similar but somewhat different results.
I'm simulating female animals dispersing from their mother's territory to search for their own territory. Essentially they need to find areas that are unoccupied by other female territories. Patches have a variable owner-fem that identifies which female it belongs to. Ideally, I'd like to have females:
move to a patch,
search within some radius around that patch for any other territory, and if there is another female's territory within that radius to
move to another patch to start the search process again. Below is what I have so far but I don't think I'm using the in-radius correctly.
I'm not sure what the best way is to tell the female to continue searching until the condition is met. Any help would be much appreciated.
to female-disperse
move-to one-of patches with [owner-fem = nobody]
if [owner-fem] of patches in-radius 3 != nobody
[
move-to one-of patches with [owner-fem = nobody]
]
end
If you want to it in "one shot", you could have them move directly to a suitable patch:
to female-disperse
move-to one-of patches with [
not any? patches in-radius 3 with [owner-fem != nobody]
]
end
Note that patches in-radius includes the patch that the turtle is on so there is no need for a separate move-to one-of patches with [owner-fem = nobody].
I don't know what your model requires, but if I were you, I might try to have them disperse a little more gradually. Here is another version that you could call from your go procedure (or any other procedure that runs "forever"):
to female-disperse
ask females with [owner-fem != self ] [
move-to one-of neighbors ; or however you want them to move
if not any? patches in-radius 3 with [owner-fem != nobody] [
set owner-fem self
]
]
end
In this version, all females that are not on a patch where they are the owner move to one of the neighboring patches. They then check if that new patch is suitable. If it is, they become the owner of it. If it is not, they just stop there for now: they will continue searching at the next iteration of go. You don't have to do it exactly this way; it could just be something loosely along those lines.
I ask patches sprout a number of turtles equal to slider initial-population on interface, now i wont that each turtle has neighbors around empty and that each patch contain one turtle. Below my wrong-code
to setup-turtles
set-default-shape turtles "circle"
ask n-of initial-population patches with [(pcolor = white - 1) and (not any? other turtles-here) and (not any? turtles-on neighbors)] [
sprout-normals 1 [
set color blue
set size 1
]
]
end
but no result neighbors empty foreach turtle..why?
I'm not sure that this is really what you are asking because the sentence "that each turtle has neighbors around empty and that each patch contain one turtle" is really hard to understand, but here is my guess:
You want turtles to appear only on patches where they will not have any neighbors. But it doesn't work because at the time you select your patches, every single patch fulfills the criteria (not any? other turtles-here) and (not any? turtles-on neighbors). As soon as you start sprouting turtles, that condition is not true for every patch anymore, but that fact is not taken into account by your code because you have already asked the patches to sprout turtles.
What you need to do is to check for the condition again each time you add a turtle. You can do that using repeat and then one-of instead of n-of:
repeat initial-population [
ask one-of patches with [(pcolor = white - 1) and (not any? other turtles-here) and (not any? turtles-on neighbors)] [
sprout-normals 1 [
set color blue
set size 1
]
]
]