Reputation: 11
I am currently building a model for people walking on a certain path (road patches, color = white). The agents' movement will only be limited on the white patch and when they encounter black patch they will rotate 180 deg.
The problem I found was when I tried to set the heading of the agents. I want the heading to walk to the nearest red patch (destination), but when I use:
set heading towards min-one-of patches with [pcolor = red ] [ distance myself ]
the agents wont move from their patch. It turned out that the "heading" generated by the above code has the value of -360 to 360 with decimals in it. The walking procedure that I have built only allows heading with multiplies of 90 (-360, -180 ... 90, 180, 270, 360). This is the full code for my walking procedure:
globals [ flagl flagr ]
ask agents [
;reset flag
set flagr 0
set flagl 0
; check and note if there is a path on the left or the right
ask patch-left-and-ahead 90 1 [if (pcolor = white ) [set flagl 1]]
ask patch-right-and-ahead 90 1 [if (pcolor = white ) [set flagr 1]
]
;in T-junction, decide to turn left or right (random)
if((flagl = 1) and (flagr = 1))
[
ifelse random 100 > 50
[set heading heading - 90]
[set heading heading + 90]
]
;if it's only applicable to turn right, then turn right
if((flagl = 0) and (flagr = 1)) [set heading heading + 90]
;if it's only applicable to turn left, then turn right
if((flagl = 1) and (flagr = 0)) [set heading heading - 90]
;return if there's no mor path
if [pcolor] of patch-at-heading-and-distance heading 1 = black [rt 180]
;agent movement
**;face min-one-of patches with [pcolor = red ] [ distance myself ]**
fd 1
;stopping procedure
if [pcolor] of patch-here = red [fd 0]
]]
I tried to round the heading generated by #1 like this:
let direction heading towards min-one-of patches with [pcolor = red ] [ distance myself ]
if direction != mod 90
set direction 90 * round(arah/ 90)
However it gives error notice since "let" command cannot take that kind of input.
This is the screenshot of the map I have built: Map
How to solve this problem?
Upvotes: 1
Views: 660
Reputation: 10336
This might get you started- with minimal checking it seems to do the trick, but you will probably want to check for exceptions.
The cardinal-4
reporter takes whatever input is given and checks if the modulo is equal to 0. If not, it will check if modulo is less than/equal to 45- if so, subtracts that value from the direction (dir
). If modulo is greater than 45, the subtract the modulo from the direction and add 90.
The check
procedure just prints the reporter output for the values listed.
to setup
ca
reset-ticks
end
to-report cardinal-4 [ heading-input ]
let dir heading-input
let remain dir mod 90
if remain != 0 [
ifelse remain <= 45 [
set dir dir - remain
]
[
set dir dir - remain + 90
]
]
report dir
end
Edit: improved check
procedure:
to check
let testVals [ -361 -359 -271 -269 -181 -179 -91 -89 -1 0 1 89 91 179 181 269 271 359 360 361 ]
print map [ i -> ( word i " becomes " cardinal-4 i "\n" ) ] testVals
end
Upvotes: 2