Turtle Behavior after asking for Patch Evaluation - netlogo

I'm creating a fish-tank style simulation in NetLogo. There are "prey", "predators", and "hidingspots".
The idea is that when a predator appears on the map, the prey will individually run the "hide" behavior and head to the nearest "hidingspot" - provided there are no predators between it and the "hidingspot".
to move-turtles
ask prey [
if (any? predators)
[
hide
stop
]
The relevant code to run the hide command.
to hide
face min-one-of hidingspot [distance myself]
set d distance min-one-of hidingspot [distance myself]
ask patches in-cone d 80
[ set pcolor yellow
if (any? predators-here)
[ ask prey
[ forward 1
set color red
output-print "DANGER"]]]
forward 1
end
The problem is that I do not know how to use the if statement in the "ask patches" properly. And therefore when one prey spots a threat all prey are running the else part of the statement rather than evaluating it individually.
How would I fix this?
Any help is appreciated.

You need to separate what you are asking the prey to do from what you are asking the patches to do. As King-Ink said, you are asking the patches to ask all the prey to do things.
The easiest way is to create a patchset for the 'danger' patches and then check if there's a predator on those patches. To do this, you want something like the following (note that this is a complete model, so you can copy this whole code into a new model and run it).
A couple of other things in your code that I cleaned up. I used let for the local variable d so that it doesn't have to appear in your globals. I asked for min-one-of only once and reused because otherwise a different hidingspot could be selected each time (if multiple at same distance). While this would not have caused an error this time (because the second selection is just to find the distance which is, by definition, the same), it is good practice.
breed [prey a-prey]
breed [predators predator]
breed [hidingspots hidingspot]
to setup
clear-all
create-predators 1 [setxy random-xcor random-ycor set color red]
create-prey 5 [setxy random-xcor random-ycor set color brown]
create-hidingspots 20
[ setxy random-xcor random-ycor
hide-turtle
ask patch-here [set pcolor green]
]
reset-ticks
end
to go
ifelse any? predators
[ ask prey [hide] ]
[ ask prey [swim] ]
end
to hide ; turtle procedure
let target min-one-of hidingspots [distance self]
let path patches in-cone distance target 80
ask path [ set pcolor yellow ]
if any? predators-on path
[ set color red
output-print "DANGER"
face target
]
forward 1
end
to swim
end

you are asking each prey to ask all prey to hide. If you drop the ask prey from the command all prey are running it should work fine and be a bit faster
to hide
face min-one-of hidingspot [distance myself]
set d distance min-one-of hidingspot [distance myself]
ask patches in-cone d 80
[set pcolor yellow]
if (any? predators-here)
[
forward 1
set color red
output-print "DANGER"
]
end

Related

Is there a way to kill a certain number of turtles within a radius of a patch with a certain color in Netlogo?

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

How to move to a patch that is at least x distance from a turtle

I'd like to ask a turtle to move to any patch that is at least a distance of x away from another turtle. So in a mix of NetLogo and English it would be:
move-to one-of patches with [distance to nearest turtle > 4]
How can this be done please?
You find the nearest turtle using the min-one-of + [distance myself] reporter. You also need to make sure that you only look at other turtles since a turtle will always be the turtle that is closest to itself.
The code can be broken up like this:
let nearest-turtle min-one-of other turtles [distance myself]
move-to one-of patches with [distance nearest-turtle > 4]
For (arguably) better readability.
edit: thanks Nicolas for the correction. You are totally right.
Using all of the above, here is a solution:
to go
ask patches [set nearest-turtle min-one-of turtles [distance myself]
set distance-turtle distance nearest-turtle
]
crt 1 [
set color blue
move-to one-of patches with [distance-turtle > 4]]
end

How can I move a turtle as close as possible to a certain patch?

I have a single blue patch and would like to move a turtle to the closest, empty patch to it. The only way I can think of doing this is using in-radius in a loop, increasing the radius size by one each time, but is there a better way?
globals [bluey]
to setup
ca
ask one-of patches [set pcolor blue set bluey self]
ask n-of 250 patches [sprout 1]
end
to-report nearest-empty [#patch]
report min-one-of
[other (patches with [not any? turtles-here])] of #patch
[distance #patch]
end
to test
setup
;the following fails if all patches occupied
;(can add a test for nobody)
ask nearest-empty bluey [set pcolor red]
end

NetLogo - find minimum angle between two patches in patchset

I'd like to find the set of patches that constitute the convex hull around a set of patches belonging to the turtle's territory. I was planning to use a "gift wrap" procedure to calculate the convex hull (related to below picture).
I'm first finding the territory patch with the lowest pxcor to start at. Then, I'd like to find the territory patch that has the smallest heading (i.e., angle closest to zero) from the starting patch, and so on, until I arrive back at the starting patch. But I can't seem to figure out how to calculate headings between two patches. Any suggestions would be really helpful. Here is what I have so far. Eventually I will have to make this loop through each point along the outer hull.
patches-own [ owner-animal ]
turtles-own [ territory ]
to setup
ca
create-turtles 1
[
move-to patch-at (max-pxcor / 2) (max-pycor / 2)
set territory patches in-radius (2 + random 8)
ask territory [
set owner-animal myself
set pcolor [ color ] of myself - 2
]
]
end
to find-convex-hull
ask turtles
[
let start-patch min-one-of territory [pxcor]
ask start-patch
[
let next-patch min-one-of [territory] of myself [towards self]
]
]
end
I think this does what you're looking for. The only odd thing about the code is the [towards myself - heading] of myself] in which the first myself refers to the next turtle and the second myself refers to original, because it is the myself of the myself.
Does that make sense? Let me know if you have any questions.
to setup
ca
crt 10 [setxy random-xcor random-ycor]
end
to start-connecting
ask min-one-of turtles [xcor][set heading 0 connect]
end
to connect
let the-turtle min-one-of other turtles with [[towards myself - heading] of myself > 0] [ [towards myself - heading] of myself]
if the-turtle = nobody [stop]
face the-turtle
ask the-turtle [set heading [heading] of myself]
create-link-with the-turtle
ask the-turtle [connect]
end
By the way, if you only want to do this for particular agentsets, just change which turtles you connect with in the connect procedure.

asking red turtles to avoid other turtles and move to one of its neighbor which is empty and has highest conc

I'm new to Netlogo. Here I'm trying ask red turtles to move towards the hight conc. patches. yellow turtles do not move. I did that! but I also want to ask the red turtles to avoid the patches which have yellow or red turtles on them and move to the neighbor of high conc.. In my code I asked them to stop once they become next to an occupied patch just because I couldn't do it. I also want to avoid getting 2 turtles on the same patch at any time. Any one could help me with that please?
patches-own [conc]
to set-up
clear-all
ask patch random-pxcor random-pycor [
set conc 200
set pcolor scale-color red conc 0 1]
crt 5 [setxy random-xcor random-ycor set shape "circle" set color red]
crt 20 [setxy random-xcor random-ycor set shape "circle" set color yellow]
reset-ticks
end
to go
diffuse conc 0.1
ask patches [set pcolor scale-color red conc 0 1]
ask turtles with [color = red]
[ifelse not any? turtles-on neighbors
[if [conc] of max-one-of neighbors [conc] > conc [
face max-one-of neighbors4 [conc]
move-to max-one-of neighbors4 [conc]]]
[stop]
]
tick
end
I think your code would read a little nicer if you used let to avoid repetition, like this:
let target max-one-of neighbors [conc]
if [conc] of target > conc [
face target
move-to target
]
For some different possible approaches to enforcing a "one turtle per patch" rule, see the One Turtle Per Patch Example model, in the Code Examples section of NetLogo's Models Library.
I assume that ifelse not any? turtles-on neighbors is your attempt to make turtles avoid occupied patches. But as you've written it, it has a stronger effect than that — it makes it so that any turtle with an adjacent occupied patch won't move at all.
I think you may have meant something more like:
ask turtles with [color = red] [
let targets neighbors with [not any? turtles-here]
let target max-one-of targets [conc]
if target != nobody and [conc] of target > conc [
face target
move-to target
]
]
Hope this helps.