How to make people go towards a specific patch and avoid certain patches on the way to the destination? - netlogo

I am building an evacuation model for my university lecture hall. The problem I am facing is that the people always walk over the gray patch that is not supposed to be walked over even though I have included the procedure to avoid walls in the code. This is the current code for my evacuation model. Also is it possible for the turtles to stop moving when arrived at the exit which in this case is the green patch?
breed [people person]
to setup
clear-all
reset-ticks
setup-patches
setup-people
end
to setup-people
set-default-shape people "person"
ask n-of n-people (patches with [pcolor = white]) [sprout-people 1]
ask people [set color cyan]
end
to setup-patches
draw-wall
draw-exit
;change the color of the floor for better visibility
ask patches[
if pcolor = black [set pcolor white ]
]
end
to draw-wall
; Make 4 boundary walls
ask patches with [ pycor >= -25 and pycor >= 25][ set pcolor gray ]
ask patches with [ pycor <= -25 and pycor <= 25][ set pcolor gray ]
ask patches with [ pxcor >= -25 and pxcor >= 25][ set pcolor gray ]
ask patches with [ pxcor <= -25 and pxcor <= 25][ set pcolor gray ]
; make rows of walls inside that look like seats in a lecture hall
; left rows of chairs
ask patches with [pxcor <= 21 and pxcor >= 13 and pycor = 20][set pcolor gray]
ask patches with [pxcor <= 21 and pxcor >= 13 and pycor = 18][set pcolor gray]
ask patches with [pxcor <= 21 and pxcor >= 13 and pycor = 16][set pcolor gray]
ask patches with [pxcor <= 21 and pxcor >= 13 and pycor = 14][set pcolor gray]
ask patches with [pxcor <= 21 and pxcor >= 13 and pycor = 12][set pcolor gray]
ask patches with [pxcor <= 21 and pxcor >= 13 and pycor = 10][set pcolor gray]
ask patches with [pxcor <= 21 and pxcor >= 13 and pycor = 8][set pcolor gray]
ask patches with [pxcor <= 21 and pxcor >= 13 and pycor = 6][set pcolor gray]
ask patches with [pxcor <= 21 and pxcor >= 13 and pycor = 4][set pcolor gray]
ask patches with [pxcor <= 21 and pxcor >= 13 and pycor = 2][set pcolor gray]
ask patches with [pxcor <= 21 and pxcor >= 13 and pycor = 0][set pcolor gray]
ask patches with [pxcor <= 21 and pxcor >= 13 and pycor = -2][set pcolor gray]
ask patches with [pxcor <= 21 and pxcor >= 13 and pycor = -4][set pcolor gray]
ask patches with [pxcor <= 21 and pxcor >= 13 and pycor = -6][set pcolor gray]
ask patches with [pxcor <= 21 and pxcor >= 13 and pycor = -8][set pcolor gray]
ask patches with [pxcor <= 21 and pxcor >= 13 and pycor = -10][set pcolor gray]
; middle rows of chairs
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = 20][set pcolor gray]
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = 18][set pcolor gray]
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = 16][set pcolor gray]
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = 14][set pcolor gray]
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = 12][set pcolor gray]
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = 10][set pcolor gray]
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = 8][set pcolor gray]
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = 6][set pcolor gray]
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = 4][set pcolor gray]
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = 2][set pcolor gray]
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = 0][set pcolor gray]
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = -2][set pcolor gray]
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = -4][set pcolor gray]
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = -6][set pcolor gray]
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = -8][set pcolor gray]
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = -10][set pcolor gray]
; right rows of chairs
ask patches with [pxcor >= -21 and pxcor <= -13 and pycor = 20][set pcolor gray]
ask patches with [pxcor >= -21 and pxcor <= -13 and pycor = 18][set pcolor gray]
ask patches with [pxcor >= -21 and pxcor <= -13 and pycor = 16][set pcolor gray]
ask patches with [pxcor >= -21 and pxcor <= -13 and pycor = 14][set pcolor gray]
ask patches with [pxcor >= -21 and pxcor <= -13 and pycor = 12][set pcolor gray]
ask patches with [pxcor >= -21 and pxcor <= -13 and pycor = 10][set pcolor gray]
ask patches with [pxcor >= -21 and pxcor <= -13 and pycor = 8][set pcolor gray]
ask patches with [pxcor >= -21 and pxcor <= -13 and pycor = 6][set pcolor gray]
ask patches with [pxcor >= -21 and pxcor <= -13 and pycor = 4][set pcolor gray]
ask patches with [pxcor >= -21 and pxcor <= -13 and pycor = 2][set pcolor gray]
ask patches with [pxcor >= -21 and pxcor <= -13 and pycor = 0][set pcolor gray]
ask patches with [pxcor >= -21 and pxcor <= -13 and pycor = -2][set pcolor gray]
ask patches with [pxcor >= -21 and pxcor <= -13 and pycor = -4][set pcolor gray]
ask patches with [pxcor >= -21 and pxcor <= -13 and pycor = -6][set pcolor gray]
ask patches with [pxcor >= -21 and pxcor <= -13 and pycor = -8][set pcolor gray]
ask patches with [pxcor >= -21 and pxcor <= -13 and pycor = -10][set pcolor gray]
end
to draw-exit
; Setting 4 exits assuming all UTAR lecture halls have 4 exits
; two at the top left and right and two at the bottom left and right
ask patches with [pxcor <= 23 and pxcor >= 21 and pycor = 25][set pcolor green]
ask patches with [pxcor >= -23 and pxcor <= -21 and pycor = 25][set pcolor green]
ask patches with [pxcor <= 23 and pxcor >= 21 and pycor = -25][set pcolor green]
ask patches with [pxcor >= -23 and pxcor <= -21 and pycor = -25][set pcolor green]
end
to go
let hall patches with [pycor <= 0 and pycor >= -25 and pxcor <= 0 and pxcor >= -25 ]
ask people[
move-people
avoid-walls
]
tick
end
to move-people
face min-one-of patches with [pcolor = green ] [distance myself ]
fd 0.1
end
to avoid-walls
ifelse [pcolor] of patch-ahead 1 = gray
[lt random-float 360 ] ;; we see a gray patch ahead of us. We turn a random amount
[fd 0.1] ;; otherwise, it is safe to move forward
end

This will be a long answer but I want to guide you step by step.
Let's start from why you are facing an unwanted behaviour.
In go, first you ask people to move (move-people) and only later you ask them to avoid walls (avoid-walls).
Even looking at it more closely, you can see that your avoid-walls procedure is not having any effect on your people's walk. Let's read your code from the point of view of your agents:
I am a person and I enter the move-people procedure, which makes me face the nearest exit. There is a wall in front of me, but nothing in the code is telling me that I should care about it: in fact the next line of code is forward 0.1, so I just move forward.
Now I enter the avoid-walls procedure. As I said, there is a wall in front of me, so I randomly change my heading. Ah, there is no wall in front of me anymore! However I will not move forward in this new direction, because there is no line of code telling me to do it now that I changed my heading.
I exit avoid-walls and this means that I also need to exit the ask people [...] command block in go. I have finished my actions for this iteration.
Here we are in the next iteration. I am now heading towards a patch without walls (because I randomly selected this heading from avoid-walls in the previous iteration)... however, before I can move in this correct direction, I am again in move-people, and I am asked again to change my heading to face the nearest green patch. This means that I am back to the initial situation, when I had a wall in front of me! The next line of code is asking me to move forward 0.1, so I continue moving on the wall...
and on, and on, and on...
So let's see, step by step, how you can solve this.
First of all, let's tidy up a couple of things:
Your people are the agents executing the move-people procedure, so a better name for this procedure would be just move so that you can have ask people [move].
In order to have agents stop moving when they reached the exit, you can simply make sure that only those agents who are not on a green patch will be asked to move: ask people with [pcolor != green] [move] (note that turtles can directly read and modify patches-own variables of the patch they are standing on, this is why we are able to use pcolor in the context of a turtle).
You will also probably want to have your model stop when everyone reached an exit, so you can add a stop condition at the beginning of the go procedure: if (not any? people with [pcolor != green]) [stop].
The result of the three points above will be the following go procedure:
to go
if (not any? people with [pcolor != green]) [stop]
ask people with [pcolor != green] [
move
]
tick
end
Now, back to the content of move.
As you can see, I only have move inside go (i.e. I removed any procedure that is specific to the goal of avoiding walls). This is because, following the journey of a person as we described it above, it is essential that the actions for avoiding walls are not carried out after moving, but upon choosing where to move.
An equally important thing is to make sure that when a person finds a direction where there are no walls, it has to move in that direction before being asked to face the exit again.
Therefore, a first idea could be to do:
to move
face min-one-of patches with [pcolor = green] [distance myself]
while [[pcolor] of patch-ahead 1 = gray] [
right random 360
]
forward 1
end
This way, we make sure that at each iteration of go people will:
Face the nearest exit.
If the patch ahead of them is clear, they will ignore the while loop and jump directly to forward 1.
If the patch ahead of them has a wall, they will enter the loop and only exit it when they found a clear direction (i.e. when the condition of the while loop evaluates as false).
In any case, on each iteration of go every turtle will move exactly by 1 in a direction without walls. On the next iteration of go each turtle will simply start again by facing the nearest exit and testing the wall condition again.
This works, and it is similar to the Look Ahead Example model in the NetLogo library (with the difference that, here, the while loop makes it possible that every turtle moves at every iteration of go, instead of having to spend a full iteration only to change heading if they need to). However, if you try it, you will see that the result is that people who find themselves between the lines of walls will move randomly until they find a way out. This is not very realistic, but we can make it more realistic.
For example, we can make sure that people who find a wall will not move completely randomly to find a way away from the wall, but instead will lean somewhat towards the direction of the nearest exit.
An idea could be to divide the 360° spectrum into four quadrants (0°-89°; 90°-179°; 180°-269°; 270°-359°), so that each person facing a wall can:
Keep note of the quadrant in which the nearest exit is;
If there is a wall in front of them, look for a new direction in the same quadrant.
This way, the wandering of people will be less randomic (i.e. we will see less back and forth, and more going around obstacles).
For this purpose, let's create a new reporter called new-direction. To use this we can create a people-own variable called target (to avoid repeating min-one-of patches with [pcolor = green] [distance myself]):
people-own [
target
]
to move
set target min-one-of patches with [pcolor = green] [distance myself]
face target
while [[pcolor] of patch-ahead 1 = gray] [
set heading new-direction
]
forward 1
end
to-report new-direction
let direction-quadrant ceiling (towards target / 90)
if (direction-quadrant = 0) [
set direction-quadrant 1
]
report random 91 + (90 * (direction-quadrant - 1))
end
You can work out the maths yourself and see that new-direction always reports a new heading that is in the same quadrant (including its borders) as the direction towards the nearest exit. Given that this happens inside the while loop, each agent will then exit the loop only once they found a direction that is more or less towards the nearest exit and that can avoid the wall. Once they found it, they move forward.
However you will also see that sometimes people get stuck in a loop: this happens when they find themselves in a location where another step forward causes the nearest exit to change quadrant (as we defined quadrants from the point of view of turtles), and the subsequent step forward causes the nearest exit to go back to the previous quadrant.
We can solve this by making sure that people remember what was the exact patch they were standing on in the previous step (I call it last-patch in the code below). If such patch is the same as the one they are planning to go to now (checked with (patch-ahead 1 = last-patch)), it means that they are stuck in a loop. In that case, instead of executing forward 1 they execute forward -1 which basically means "go backwards by 1". Considering that at this point forward refers to the heading the turtle has acquired after exiting the while block, this means that in this way the turtle is forced outside the loop:
to move
let last-patch patch-at-heading-and-distance (heading) (-1)
set target min-one-of patches with [pcolor = green] [distance myself]
face target
while [[pcolor] of patch-ahead 1 = gray] [
set heading new-direction
]
ifelse (patch-ahead 1 = last-patch)
[forward -1]
[forward 1]
end
Note that this solution is improvable: it works in your scenario but it may not be sufficient with more complicated designs of the hall and walls.

You run "move" in which the turtles face a direction, then move.
Then you run "avoid" in which the turtles look for gray and turn.
So your turtles have already moved before they look for gray.
My advice: aim, then correct, then move. Note that this very simple navigation rule will not move like a person would move.
to aim
;; face nearest green patch
face min-one-of patches with [pcolor = green ] [distance myself ]
end
to correct
;;if about to step on a gray patch, turn away from it
if ([ pcolor ] of patch-ahead .1 = gray)
[ ;; where is the center of the next patch?
let towards-patch-center towards patch-ahead .1
;; calculate a direction away from the center of the patch
let diff subtract-headings towards-patch-center heading
;; turn left (CCW) or right (CW)
if (diff >= 0 ) ;; it's ahead or clockwise
[ set heading heading - 1 ] ;; turn counter-clockwise
if (diff < 0 ) ;; its counter-clockwise
[ set heading heading + 1 ] ;; turn clockwise
]
end
to walk
jump .1
end
to navigate
aim
correct
walk
end

Related

Turtles randomly walking in specific area

Hi I would like to hatch turtles at random patches but confined within a specific area.
ask employees [
set shape "person"
set size 1.5
set color blue
setxy random-xcor random-ycor ]
How do I adjust the setxy line to force the turtles to all be confined to: [ pxcor <= 8 and pxcor >= -8 and pycor <= 8 and pycor >= -8 ]
After looking through various bits of different code, what I've done is:
globals [office-space]
set office-space patches with [ pxcor <= 8 and pxcor >= -8 and pycor <= 8 and pycor >= -8 ]
ask office-space [ set pcolor grey]
place-on-color-employees
to place-on-color-employees
let _patches (patches with [pcolor = grey])
ask employees [
move-to one-of (_patches with [not any? turtles-here])
]
end

turtles walk to the wall instead of door in netlogo

I write a code that evacuates turtles to the only exit door. But as I noticed that the turtles are divided into several groups. There are turtles that walk toward the exit door and the others walk to the nearest wall. I want to create a simulation that all the turtles will go to the exit doors. Here's my code. Can anyone advise, please?
globals [
;wall
door
goal-x goal-y
n
]
patches-own [ path? ]
turtles-own [
direction
fast?
other-nearby
]
to setup
clear-all
setup-patches
set-default-shape turtles "person"
ask n-of number-room1 patches with [pxcor < 47 and pxcor > 0 and pycor < 45 and pycor > 0 and pcolor = black]
[
sprout 1 [
facexy 41 45
set direction 1
set color yellow
]
]
reset-ticks
end
to setup-patches
draw-wall
draw-exit
ask patch 21 41 [
set plabel-color white
set plabel "Room1"
]
end
to draw-wall
ask patches with [pxcor <= 38 and pxcor >= 0 and pycor = 45]
[set pcolor blue]
ask patches with [pxcor <= 47 and pxcor >= 44 and pycor = 45]
[set pcolor blue]
ask patches with [pxcor <= 47 and pxcor >= 0 and pycor = 0]
[set pcolor blue]
ask patches with [pxcor = 0 and pycor <= 45 and pycor >= 0]
[set pcolor blue]
ask patches with [pxcor = 47 and pycor <= 45 and pycor >= 0]
[set pcolor blue]
end
to draw-exit
ask patches with [pxcor <= 43 and pxcor >= 39 and pycor = 45]
[set pcolor green]
end
to go
if ticks >= 100 [stop]
ask turtles [walk]
tick
end
to walk
let room1 patches with [pxcor < 47 and pxcor > 0 and pycor < 45 and pycor > 0]
;let exitpoint patches with [pxcor < 46 and pxcor > 33 and pycor < 45 and pycor > 32]
ask turtles-on room1
[face one-of patches with [pxcor <= 43 and pxcor >= 39 and pycor = 47]
fd 0.01
]
;ask turtles-on exitpoint
;[face one-of patches with [pxcor <= 42 and pxcor >= 38 and pycor = 47]
; fd 0.01
;]
end
You can try these 2 steps to make it work:
Check the setting of your simulation (besides the simulation speed slider on the top right side), make sure to uncheck world wrap horizontally & world wrap vertically. If it is still checked, it means that the turtles can go beyond your vertical/horizontal boundary and appear on the other side. That's why some group of turtles is moving towards the wall, they assume they can pass the boundary and arrive at the exit, while they will be stuck there because of your code constraint.
After making sure that the setting is okay, if you still have some of them stuck in the upper side of the wall near the exit, you can try to replace your to walk code with this:
to walk
set heading towards one-of patches with [pcolor = green]
fd 1
end
Hopefully, this will help you solve the problem

Creating a bottleneck obstacle for agents

I am trying to create a patch that will be a bottleneck structure in the middle of a path where the turtles have to go through.
I have created the parabolas but I would like to add a slider so that the size of the bottleneck can be changed but I don't know how to create a code that will move it.
Here is the code (I am very bad with the maths of the parabola so I had help with the top one and I just manually created the down one)
to setup-road
;; patch procedure
;; colour patches to paint a horizontal road
let bound (max-pycor / 3)
ifelse (pycor < (max-pycor - bound)) and (pycor > (min-pycor + bound))
[ set pcolor red - 3 ]
[ set pcolor green ]
set upper-road-bound (max-pycor - bound - 2 )
set lower-road-bound (min-pycor + bound + 2 )
setup-top-parabola-on-road
setup-down-parabola-on-road
end
;; I want to be able to expand the parabolas so that the opening between them will be wider as well as narrow according a slider.
to setup-top-parabola-on-road
ask patches with
[pxcor > -25 and pxcor < 25] [
if pycor > ((pxcor ^ 2) / 20 + 10)
[ set pcolor green ]
]
end
to setup-down-parabola-on-road
ask patches with [pxcor >= -4 and pxcor <= 4 and pycor = -11][set pcolor green]
ask patches with [pxcor >= -5 and pxcor <= 5 and pycor = -12][set pcolor green]
ask patches with [pxcor >= -6 and pxcor <= 6 and pycor = -13][set pcolor green]
ask patches with [pxcor >= -7 and pxcor <= 7 and pycor = -14][set pcolor green]
ask patches with [pxcor >= -8 and pxcor <= 8 and pycor = -15][set pcolor green]
ask patches with [pxcor >= -9 and pxcor <= 9 and pycor = -16][set pcolor green]
ask patches with [pxcor >= -10 and pxcor <= 10 and pycor = -17][set pcolor green]
ask patches with [pxcor >= -11 and pxcor <= 11 and pycor = -18][set pcolor green]
ask patches with [pxcor >= -12 and pxcor <= 12 and pycor = -19][set pcolor green]
ask patches with [pxcor >= -13 and pxcor <= 13 and pycor = -20][set pcolor green]
ask patches with [pxcor >= -14 and pxcor <= 14 and pycor = -21][set pcolor green]
ask patches with [pxcor >= -15 and pxcor <= 15 and pycor = -22][set pcolor green]
ask patches with [pxcor >= -16 and pxcor <= 16 and pycor = -23][set pcolor green]
ask patches with [pxcor >= -17 and pxcor <= 17 and pycor = -24][set pcolor green]
ask patches with [pxcor >= -18 and pxcor <= 18 and pycor = -25][set pcolor green]
end
Can anyone help?
Here you go.
This assumes you have a button called setup
and a slider for variable "width" that ranges from 0 to 11.
I added an "ask patches [ ]" in near the top where you are setting red and green.
to setup
clear-all
setup-road
reset-ticks
end
to setup-road
;; patch procedure
;; colour patches to paint a horizontal road
let bound (max-pycor / 3)
ask patches [
ifelse (pycor < (max-pycor - bound)) and (pycor > (min-pycor + bound))
[ set pcolor red - 3 ]
[ set pcolor green ]
]
let upper-road-bound (max-pycor - bound - 2 )
let lower-road-bound (min-pycor + bound + 2 )
setup-top-parabola-on-road
setup-down-parabola-on-road
end
;; I want to be able to expand the parabolas so that the opening between them will be wider as well as narrow according a slider.
to setup-top-parabola-on-road
ask patches with
[pxcor > -25 and pxcor < 25] [
if pycor > ((pxcor ^ 2) / 20 + width)
[ set pcolor blue ]
]
end
to setup-down-parabola-on-road
ask patches with
[pxcor > -25 and pxcor < 25] [
if pycor < (-1 * (pxcor ^ 2) / 20) - width + 1
[ set pcolor yellow ]
]
end

How to move turtles on a game board simulation?

I'm creating a board game simulation similar to monopoly, where pieces are moving around the board. My turtle acts as the user's game piece and moves around the border of the world. The border is set up in alternating colors. I have a button that generates the number of steps the turtle moves. Those steps are stored as dice-num, a global variable. However, when the turtle lands on the patches before the patch (16 -16) (the bottom right-hand corner of the board) and the number of steps it needs to move exceeds 1, I can't turn the turtle's heading halfway to move up the board. As a result it only moves back to the beginning of the board.
I've tried to treat each case separately:
;if the turtle lands on the patch before the corner
ask turtle 0 [if pycor = min-pycor and pxcor = max-pxcor - 1
[setxy max-pxcor min-pycor
set dice-num dice-num - 1
show dice-num
]
]
;dice-num refers to number of steps the turtle moves
Heres my code so far:
to setup
board
end
to go
dice-roll
end
to board
ask patches [if pxcor = max-pxcor or pycor = max-pycor or pxcor = min-
pxcor or pycor = min-pycor
[set pcolor blue]]
ask patches [if pycor = max-pycor or pycor = min-pycor
[if pxcor mod 2 = 0
[set pcolor orange]]]
ask patches [if pxcor = max-pxcor or pxcor = min-pxcor
[if pycor mod 2 = 0
[set pcolor orange]]]
ask patch min-pxcor min-pycor [set pcolor green]
end
to dice-roll
set dice [1 2 3 4 5 6]
set dice-num one-of dice
user-message (word "You rolled: " dice-num)
ask turtle 0 [
fd dice-num
]
;allows the turtle to turn if it lands on a corner
ask turtle 0 [if ycor = min-pycor and xcor = max-pxcor [set heading 0]
if xcor = max-pxcor and ycor = max-pycor [set heading 270]
if xcor = min-pxcor and ycor = max-pycor [set heading 180]
;add a statement to end game once player rereaches the green patch
]
;if the turtle lands on the patch before the corner
ask turtle 0 [if pycor = min-pycor and pxcor = max-pxcor - 1
[setxy max-pxcor min-pycor
set dice-num dice-num - 1
show dice-num
]
]
end
I expect the output to be the turtle to start moving up the right hand side of the board once it lands on the patch (15 -16) and recieves a dice-num greater than 1. However, when the turtle does land on the patch (15 -16) and the dice-num is greater than 1 it simply moves back to the beginning of the board.
Okay, this was simply too long for comments so I had to make some guesses. I expect the problem was that you were forwarding the full amount of the die roll after checking location. This would mean you have to test all the potential patches that could reach the corner. Instead, it is easier to move one patch and test location before moving the next patch. This is a cleaned up version of your code that implements this move and check process.
to setup
clear-all
board
ask one-of patches with [pcolor = green]
[ sprout 1
[ set color white
set heading 90
forward 1
]
]
end
to go
let die-num dice-roll
ask one-of turtles [ move die-num ]
end
to board
ask patches with [ pxcor = max-pxcor or pxcor = min-pxcor ]
[ set pcolor ifelse-value (pycor mod 2 = 0) [orange][blue] ]
ask patches with [ pycor = max-pycor or pycor = min-pycor ]
[ set pcolor ifelse-value (pxcor mod 2 = 0) [orange][blue] ]
ask patch min-pxcor min-pycor [set pcolor green]
end
to-report dice-roll
let dice-num one-of [1 2 3 4 5 6]
user-message (word "You rolled: " dice-num)
report dice-num
end
to move [#roll]
while [ #roll > 0 ]
[ if pxcor = max-pxcor and pycor = max-pycor [set heading one-of [180 270] ]
if pxcor = max-pxcor and pycor = min-pycor [set heading one-of [0 270] ]
if pxcor = min-pxcor and pycor = max-pycor [set heading one-of [180 90] ]
if pxcor = min-pxcor and pycor = min-pycor [ stop ]
fd 1
set #roll #roll - 1
]
end
The alternative is simply to add the die roll to the current location and see if it goes past. If it does, calculate where you want to get to.

How to make turtles move around patches with specific rules?

I am new to Netlogo, and have some questions. That would be great if you could help me.
I would like to create some fruit flies moving around a tree that is made up by green patches. Fruit flies are attracted to the tree. They will turn back to the tree if fruit flies move away certain distance (such as 5 grids) from the tree.
In the beginning, they will not stop on the green patches because they have enough energy. As time passed, they will loss their energy. They will find the closest green patch, and stay on it for certain time once their energy reaches 0. They gain energy after that, and they only can do short hops from the bottom branch to the top one (3 hops). Flies will move back to the bottom branch when they are on the top part of tree. I think I need to do a WHILE loop, but I have no idea how to do that. Please look at my codes.
breed [flies fly]
breed [suns sun]
turtles-own [energy]
flies-own [count-down]
to setup
clear-all
setup-suns
setup-flies
setup-patches
reset-ticks
end
to setup-suns
;; Create the sun
set-default-shape suns "sun"
create-suns 1 [
setxy max-pxcor - 3
max-pycor - 3
set color yellow
set size 7
]
end
to setup-flies
set-default-shape flies "bee 2"
create-flies number-fly [ set color white setxy random-xcor random-ycor set count-down 15]
end
to setup-patches
;; Create sky and grass
ask patches
[ set pcolor blue ]
ask patches with [pycor < min-pycor + 2]
[ set pcolor 66 ]
;; Create trunk and branches
ask patches with [ pxcor = -15 and pycor <= 0 ] [ set pcolor brown ]
ask patches with [ pxcor = -15 and pycor < 8 and pycor > 0] [ set pcolor lime ]
ask patches with [ pxcor = pycor - 15 and pycor <= 5 and pycor > 0 ] [ set pcolor lime ]
ask patches with [ pxcor = (- pycor) - 15 and pycor <= 5 and pycor > 0 ] [ set pcolor lime ]
ask patches with [ pxcor = pycor - 8 and pycor <= 2 and pxcor > -15 ] [ set pcolor lime ]
ask patches with [ pxcor = (- pycor) - 22 and pycor <= 2 and pxcor < -15 ] [ set pcolor lime ]
ask patches with [ pxcor = pycor - 1 and pycor <= -1 and pxcor > -15 ] [ set pcolor lime ]
ask patches with [ pxcor = (- pycor) - 29 and pycor <= -1 and pxcor < -15 ] [ set pcolor lime ]
ask patches with [ pxcor = 15 and pycor <= 0 ] [ set pcolor brown ]
ask patches with [ pxcor = 15 and pycor < 8 and pycor > 0] [ set pcolor lime ]
ask patches with [ pxcor = pycor + 15 and pycor <= 5 and pycor > 0 ] [ set pcolor lime ]
ask patches with [ pxcor = (- pycor) + 15 and pycor <= 5 and pycor > 0 ] [ set pcolor lime ]
ask patches with [ pxcor = pycor + 22 and pycor <= 2 and pxcor > 15 ] [ set pcolor lime ]
ask patches with [ pxcor = (- pycor) + 8 and pycor <= 2 and pxcor < 15 ] [ set pcolor lime ]
ask patches with [ pxcor = pycor + 29 and pycor <= -1 and pxcor > 15 ] [ set pcolor lime ]
ask patches with [ pxcor = (- pycor) + 1 and pycor <= -1 and pxcor < 15 ] [ set pcolor lime ]
ask patches with [ pxcor = -26 and pycor = -3 ] [ set pcolor red ]
ask patches with [ pxcor = -10 and pycor = 5 ] [ set pcolor red ]
ask patches with [ pxcor = 21 and pycor = -1 ] [ set pcolor red ]
end
to go
move-flies
tick
end
to move-flies
ask flies [
set energy 6
ifelse energy > 10 [
;rt random 50 lt random 50 jump random-float 1 ;
let nearest-leaf min-one-of (patches with [pcolor = lime] ) [distance myself] ; Find the closest leaf within 5 grids - long range search.
if is-patch? nearest-leaf [ ; If it is a leaf, and flies will be attracted to the leaf.
face nearest-leaf
;set heading 45
;fd distance nearest-leaf
rt random 50 lt random 50 jump random-float 5 ; Protential resources make flies move actively (fast movement).
;move-to nearest-leaf ;
]
]
[
ifelse pcolor != lime
[ rt random 50 lt random 50 jump random-float 1 ; Initialization - flies fly around to search their resources.
continue]
[ stay ]
]
]
end
to continue
let nearest-leaf min-one-of (patches in-radius 1 with [pcolor = lime] ) [distance myself] ; Find the closest leaf within 2 grids - short hops.
ifelse is-patch? nearest-leaf [ ; If it is a leaf, and flies will be attracted to the leaf.
face nearest-leaf
fd random distance nearest-leaf
;ask patches in-radius 1 [set pcolor red]
;rt random 50 lt random 50 jump random-float 5 ; Protential resources make flies move actively (fast movement).
;move-to nearest-leaf ;
]
[
let turn-back min-one-of (patches with [pcolor = lime] ) [distance myself] ;
;set heading 180
face turn-back
jump random-float 5 ]
move-up ;Flies tend to move up through all branches by short hops. Need a while loop.
; Move down if they reach the top of tree
let canopy patch-at-heading-and-distance 0 1
let canopy-left patch-left-and-ahead 45 1
let canopy-right patch-right-and-ahead 45 1
if canopy != lime or canopy-left != lime or canopy-right != lime
[
move-down
]
end
to move-up
ask flies [
set heading one-of [0 30 -30]
]
end
to move-down
ask flies [
set heading one-of [180 120 -120]
]
end
to stay
set count-down count-down - 1 ;;decrement timer
set label count-down
if count-down = 0
[
rt random 50 lt random 50 jump random-float 1
set label ""
reset-count-down ;;it's another procedure
]
end
to reset-count-down
set count-down 30
end
I am sorry if you are confused by my codes. I appreciate your help. Thanks.
Kind Regards,
Ming
From your description, I think you almost certainly don't want a while loop. In a NetLogo model's go procedure, you're only specifying what happens in a single tick. So you would only use while if need it to express something that happens all in a single instant, not a process that unfolds over multiple ticks.
(Agree with Frank this is too much code to post to have a good chance of getting help. It would take quite a while for me to read and study this much code, let alone try to help you with it. In this answer I've tried to extract and address a single aspect.)