Netlogo Mekka Model - need directions - netlogo

I'm working on this assignment for my university with Netlogo and I'm really stuck.
I just started out using Netlogo and I'm trying to recreate Mekka, together with some pilgrims.
I've been trying out a lot of different codes, adding new ones, trying it out, deleting some, but this is what I came up with this far:
turtles-own
[direction ;; 1 follows right-hand wall, -1 follows left-hand wall
way-is-clear? ;; reporter - true if no wall ahead
checked-following-wall?]
globals [halfedge]
breed [agents agent ]
agents-own [ around visible ]
to setup
create-agents 500 [
set color green
set size 2
; distribute agents randomly
setxy pxcor = halfedge pycor = halfedge
set heading random 360
; ensure that each is on its own patch
while [any? other agents-here] [ fd 1 ]
]
end
to bounce
if [pcolor] of patch-at dx 0 = blue [
set heading (- heading)
]
if [pcolor] of patch-at 0 dy = blue [
set heading (180 - heading)
]
end
to go
ask agents [ count-those-around ]
ask agents [ move ]
end
; store the number of agents surrounding me within
; local-radius units
; and the agents that I can see within visible-radius
to count-those-around
set around count agents with [self != myself] in-radius
local-radius
set visible agents with [self != myself] in-radius
visible-radius
end
to move
;; turn right if necessary
if not wall? (90 * direction) and wall? (135 * direction) [ rt 90 * direction ]
;; turn left if necessary (sometimes more than once)
while [wall? 0] [ lt 90 * direction ]
;; move forward
fd 1
end
; face towards the most popular local spot
to face-towards
face max-one-of visible [around]
end
; face away from the most popular local spot
to face-away
set heading towards max-one-of visible [around] - 180
end
to setup-center
clear-all
set halfedge int (edge / 2)
ask patches[
if (pxcor = (- halfedge) and pycor >= (- halfedge) and pycor <= (0 + halfedge) )
[set pcolor blue] ;; ... draws left edge in blue
if ( pxcor = (0 + halfedge) and pycor >= (- halfedge) and pycor <= (0 + halfedge) )
[set pcolor blue] ;; ... draws right edge in blue
if ( pycor = (- halfedge) and pxcor >= (- halfedge) and pxcor <= (0 + halfedge) )
[set pcolor blue] ;; ... draws bottom edge in blue
if ( pycor = (0 + halfedge) and pxcor >= (- halfedge) and pxcor <= (0 + halfedge) )
[set pcolor blue] ;; ... draws upper edge in blue
]
end
The idea is that first, a square is setup resembling the kaaba.
After that, the turtles are set up.
They are supposed to all walk around the wall in a counter-clockwise direction.
There's supposed to be one 'leader' that would lead all the pilgrims around the kaaba.
Right now the kaaba is successfully drawn, the only problem is that turtles are not supposed to be spawn in there or run into it (therefore the bump code).
Also, they are randomly going around, and I have no idea how to make them move in a Counter-Clickwise formation, following one differently coloured leader.
Could any of you guys help me out? I would be eternally thankful!

You may be trying to learn too much all at once by writing a big program all at once.
Start by writing a really small program; get it working; attempt to make a very small improvement to it, and get that working; and so on. If at any point you get stuck, come here, show your code with has at most one thing broken about it, and ask one question about the one issue in particular that you're currently stuck on. That's the most effective way to get help.
A few random coding tips:
This isn't valid code:
setxy pxcor = halfedge pycor = halfedge
setxy expects two numbers, but you're passing it two booleans: pxcor = halfedge is true or false, and pycor = halfedge is true or false, too. I think you might mean just setxy halfedge halfedge.
agents with [self != myself] can be replaced with simply other agents.

Related

Divide regions accordingly to physical features

I'm working on a smaller project and got stuck on an issue, I'm not really sure if it's possible to solve it in NetLogo but I want to give StackOverflow a go!
I got a model that divides the world into different parts and randomly add physical features (such as rivers). If a feature goes through the whole region, I want it to separate the region and make into two regions. As an example, in the picture below, I want to separate the purple region into two unique regions accordingly to the physical feature (black).
The code I used to generate the picture above, can be found below.
to setup
ca
;Setting world.
resize-world 0 19 0 19
;Creating regions.
let x 5
let y 5
let col 45
while [y <= max-pycor + 1][
while [x <= max-pxcor + 1 ][
ask patches with [pxcor < x and pxcor >= x - 5 and pycor < y and pycor >= y - 5][
set pcolor col
]
set x x + 5
set col col + 10
]
set x 5
set y y + 5
]
;Generating physical features.
ask n-of 5 patches[ sprout 1[
set pcolor black]
]
let i 0
while [ i < (max-pycor * 2 )][
ask turtles [
fd 1
set pcolor black
ifelse (random 20 <= 1)
[
rt one-of [-90 0 90]
forward 1
]
[
fd 1
set pcolor black
fd 1
set pcolor black
]
set pcolor black
set i i + 1]
]
ask turtles [die]
end
My strategy for handling this is to realize that all we really need to do is "flood" a patch out by color and tag all the found adjacent patches, then repeat for any un-tagged, non-black patches until they are all done.
NetLogo does not have a "flood" command to get all patches adjacent to a patch meeting a criteria, so we make a special reporter of our own to handle it, patches-adjacent. Then it's just easy to ask those patches-adjacent to set their region to the currently chosen region.
I don't love this code, it's a little finicky and would be prone to infinite loops if tweaked incorrectly, but it should work. I bet there is a cleaner way to do this that I'm not thinking of at the moment.
; add a variable to track the different regions
; the default value will be `0` for each patch when `clear-all` is called
patches-own [ region ]
to set-regions
let current-region 1
; only act on non-black patches that haven't yet been assigned a region
let untagged patches with [ region = 0 and pcolor != black ]
while [any? untagged] [
ask one-of untagged [
ask patches-adjacent [
set region current-region
]
]
; update the region and the untagged patches we have left to process
set current-region current-region + 1
set untagged patches with [ region = 0 and pcolor != black ]
]
; this is just to get a view of the regions to quickly see if our code worked, it can be removed
ask patches [ set plabel region ]
end
to-report patches-adjacent
report patches-adjacent-ex (patch-set self) pcolor
end
to-report patches-adjacent-ex [found pc]
let newly-found neighbors4 with [ (not member? self found) and pcolor = pc and region = 0 and pcolor != black ]
set found (patch-set found newly-found)
ask newly-found [
; use recursion to find the patches adjacent to each newly-found one
; relying on updating the `found` agentset as we go to avoid duplicates
; or looping forwarder
set found (patches-adjacent-ex found pc)
]
report found
end
I solved this by using the Patch Clusters model that can be found in the NetLogo model library.

Patch network to "connect the dots" and assess overall area belonging to an agent's "home range"

I have agents moving through a landscape with varying resources. Say my agent begins in the center, and then moves around the landscape in a curved line. I would like to somehow make a patchset or other grouping of ALL the patches that encompass the area within the patches through which the agent moved, simulating a home range calculation. I haven't been able to think conceptually of how to do this so I have no code to show, but any help is much appreciated.
The most efficient way is probably just to keep track of the min/max of the coordinates of the patches visited by turtles. Here is a simplistic example:
turtles-own [ min-x max-x min-y max-y ]
to setup
clear-all
create-turtles 1
reset-ticks
end
to go
ask patches [ set pcolor black ]
ask turtles [
rt random 30 lt random 30 fd 1 ; move randomly
update-min-max
ask home-range [ set pcolor [ color ] of myself - 2 ]
]
tick
end
to update-min-max ; turtle command
set min-x min (list min-x pxcor)
set min-y min (list min-y pycor)
set max-x max (list max-x pxcor)
set max-y max (list max-y pycor)
end
to-report home-range ; turtle reporter
report patches with [
pxcor >= [ min-x ] of myself and
pxcor <= [ max-x ] of myself and
pycor >= [ min-y ] of myself and
pycor <= [ max-y ] of myself
]
end
This assumes that the world doesn't wrap.

In an «ask turtles» method: How can I read a variable of a patch in a relative angle and distance from a turtle?

I want [turtles with [shape = "sheep"]] to move either to the lefthand side or the righthand side, depending on how many [attractive (green) patches] are around a certain relative patch.
How the turtles with [shape = "sheep"] should count the patches (yellow)
The (incorrect) code looks like this:
to move-sheep
ask turtles with [shape = "sheep"] [
right random (16 + (count neighbors4 with [pcolor = green] patch-right-and-ahead 60 2)^ 2)
left random (16 + (count neighbors4 with [pcolor = green] patch-right-and-ahead -60 2)^ 2)
forward 1
#(some other commands…)
]
end
Thank you ^^
It would be much easier if you actually told us what the problem is. You say your code is wrong, but not how you know it's wrong. Is it reporting an error (and, if so, what is the error and which line is reporting it)? Is the moving turtle going the wrong way?
Regardless, the easiest way to approach this is to do something smaller before trying to move. If you simply count the number of green patches and print that out, you can test the code. Once you introduce movement, how will you tell if it counted correctly?
I am still not entirely sure what you are asking. But I think this code might help you diagnose your problem. It tells you what the count is around the target patches, so you can see if it is doing the correct count. Once you know the counting works, you can then modify for movement.
to testme
clear-all
ask patches [set pcolor one-of [yellow green]]
create-turtles 1 [set heading 30 set color black]
ask one-of turtles
[ ask patch-right-and-ahead 60 2 [set pcolor red]
type "Right: "
print count ([neighbors4] of patch-right-and-ahead 60 2) with [pcolor = green]
ask patch-right-and-ahead -60 2 [set pcolor red]
type "Left: "
print count ([neighbors4] of patch-right-and-ahead -60 2) with [pcolor = green]
]
end

unable to make non-stationary turtles change their direction if an obstacle a patch ahead

If any one please give some time.
I have an area(say a colony) with boundary wall as black patches and at some point within the boundary there is one building with building wall as blue patches. People(breed) are normally moving inside boundary and the building as well. Also they are entering and going out of the boundary. Due to some reason (suppose rumor) and after certain condition (if more than 15 person hears the rumor) they starts moving randomly with any of the headings 0, 90, 180 and 270. So, the problem I am unable is, to apply check on the turtles(people) randomly moving to change their heading or turn back if they sense the boundary or wall a patch ahead.
I tried following ways but not working, they simple passes form these patches
1) Asked the turtles if heard-rumor? and times-heard > 1 [
if [pcolor] of patch-ahead 1 = blue [set heading [heading] of self - 180]
if [pcolor] of patch-ahead 1 = black [set heading [heading] of self - 180] ]
2) set patches with boundary-wall [set pcolor black] and building-wall [set pcolor blue] and then set patch variables boundary-wall? And building-wall? true on these patches. Further asked the turtles
if heard-rumor? and times-heard > 1 [
if boundary-wall? or building-wall? [ set heading [heading] of self - 180 ] ]
The procedure sequence is
to go
ask people [ ;breed
fd speed
spread-rumor
people-wander ]
end
So after spread-rumor function,
to people-wander
if heard-rumor? and times-heard > 1 and inside-boundary?
[
if people-heard-rumor > 10 [ set heading one-of (list 0 90 180 270) ] ];random 360
;people-heard-rumor is a count how many have received rumor
if heard-rumor? or fear-worst? [
; if [pcolor] of patch-ahead 1 = blue [set heading [heading] of self - 180]]
; if [pcolor] of patch-ahead 1 = black [set heading [heading] of self - 180]]
boundary-wall? or temple-wall? [set i? true set heading [heading] of self - 180 show 5] ]
end
I don’t know what wrong I am doing. But surely I am not using proper way. Any help is deeply thankful.
You start out with fd speed so your people will go right through the barriers on that command without ever testing for a barrier. Note that even if you were to test 1 patch ahead before doing that, if speed can be greater than 1, you could still go right through the barriers. Furthermore, in a corner a person might have a barrier both in front of it and behind it, so reversing course can also be a problem.
Btw, [heading] of self is the same as heading, and to turn around it is more natural to say rt 180.
EDIT (in response to comment):
Here is a simple example of moving step by step, checking along the way:
to fd-with-checks [#speed]
repeat #speed [
ifelse (isbarrier? patch-ahead 1) [
stop
] [
fd 1
]
]
end
to-report isbarrier? [#patch]
report pcolor = blue or pcolor = black
end

Creating overlapping agents in a line

Using the below code I get agents are like this:
to setup
ask breadth-patches [sprout-walls wall-agents[set color 2]]
ask length-patches [sprout-walls wall-agents[set color 2]]
ask gap-patches [sprout-walls wall-agents[set color 2]]
ask length-patches[align-inside-at-top]
ask breadth-patches [align-inside-at-right-left]
ask gap-patches[align-inside-at-top]
end
to align-inside-at-top ;; patch procedure
let counter count walls-here ;; we will use this as a count-down, after using it in some calculations
if counter > 0 ;; could assume there are turtles, but we are not.
[ let gap1 1 / counter ;; size of turtles, gap between turtles
let half-gap gap1 / 2 ;; half-size of turtles
let ytop 0
if-else(pycor < 0)[set ytop pycor - .5 - half-gap]
[set ytop pycor + .5 - half-gap]
let xleft pxcor - .5 - half-gap
ask walls-here
[ set size gap1
set ycor ytop
set xcor xleft + gap1 * counter
set counter counter - 1 ;; so we're placing them from right to left
; set ycor ycor + 0.125
]
]
end
to align-inside-at-right-left ;; patch procedure
let counter count turtles-here ;; we will use this as a count-down, after using it in some calculations
if counter > 0 ;; could assume there are turtles, but we are not.
[ let gap1 1 / counter ;; size of turtles, gap between turtles
let half-gap gap1 / 2 ;; half-size of turtles
let ytop pycor + .5 + half-gap
let xleft 0
if-else (pxcor < 0)[
set xleft pxcor + .5 - half-gap]
[ set xleft pxcor - .5 + half-gap
]
ask turtles-here
[ set size gap1
set ycor ytop - gap1 * counter
set xcor xleft ;+ gap * counter
set counter counter - 1 ;; so we're placing them from right to left
]
]
end
Note: The gap in the rectangle is due to the following code
ask patches with [pxcor > (gap * (-1)) and pxcor < gap and pycor =(breadthrec - 1)][ask walls-here[die]]
Here, gap = 1 ,i.e, a width of 1 patch.
So the input parameter is the wall-agents which specifies the number of agents to created per patch along the length and breadth patches.
I wish to change to create overlapping agents as in the figure below(Sorry the figure is not so perfect, but I hope it explains it). Please help on how to achieve this.
This is a lot of code to ask anybody to debug for you.
I would suggest solving a simpler version of the problem first. Do you have code that can create wall-agents turtles in a single patch, evenly spaced along a line? Once you had a working code that did that, then you could attempt to generalize it to your more complex problem.
If you run into trouble writing that simpler version, you'll have a smaller question to ask here on Stack Overflow that will be much easier for someone to answer than your current, very large question.
If you are able to write the simpler version, don't throw it away — keep it, so you can go back to it if you need to. Then tackle the bigger problem.
You might even be able to take the simpler version, put it into a procedure, and then call that procedure from your larger solution. Making small procedures that work, and then calling those smaller procedures from other ones, is often a good way to break a problem down into manageable parts.