I'm very new to netlogo and am wondering how I can set a group of patches to be an own variable to a certain breed. For example, let's say I have:
breed [ buildings building ]
buildings-own [ my-patches ]
I want to be able to have a set of patches (let's say a rectangle, so constrained by some coordinates) that are assigned to each individual building's my-patches field. How would I do this?
First thing you need to know is that you can't have breeds of patches. While you don't say that's what you want, I just want to make sure you are aware of this.
Have a look at this code. It is a complete program that creates some turtles (called realtors) and assigns them each some patches. It then turns those patches the same colour as the realtor.
breed [realtors realtor]
realtors-own [my-patches]
to setup
clear-all
create-realtors 10
[ setxy random-xcor random-ycor
set size 2
set shape "circle"
set my-patches n-of 5 patches in-radius 3
]
ask realtors [ask my-patches [set pcolor [color] of myself ] ]
reset-ticks
end
You can run it by creating a button for 'setup' or simply typing setup in the command centre.
Welcome to Stack Overflow and Netlogo! Given your breed and buildings-own as above, you can simply use set to assign the patch-set that you want a building's my-patches variable to hold.
to setup
ca
ask patches with [ pxcor mod 10 = 0 and pycor mod 10 = 0 ] [
sprout-buildings 1 [
set shape "square"
set heading 0
set size 1.5
set my-patches patches with [
pxcor > [pxcor] of myself - 3 and
pxcor < [pxcor] of myself + 3 and
pycor > [pycor] of myself - 3 and
pycor < [pycor] of myself + 3
]
ask my-patches [
set pcolor [color] of myself - 2
]
]
]
reset-ticks
end
Related
I'm stumped with an issue in my model. I have a model that looks to simulate an office environment, where there are two breeds: employees and citizens. The employees stay in the office, denoted by grey coloured patches, and the citizensstay in the outside world denoted by black colour patches.
In the middle of the world patch 0 0 there is an office, where employees go to pick up money. There are 4 service-desks where both employees and citizens are to meet for a transfer of money to occur. Here is the full code:
globals [ office-space ]
breed [ offices office ]
breed [ service-desks service-desk ]
breed [ employees employee ]
breed [ citizens citizen ]
offices-own [ money ]
employees-own [ money-held ]
citizens-own [ money-received ]
to setup
clear-all
create-offices 1
ask offices [
set shape "building institution"
set size 4
set color yellow
set money num-of-money ]
create-employees num-of-employees
ask employees [
set shape "person"
set size 1.5
set color blue
setxy random-xcor random-ycor ]
create-citizens num-of-citizens
ask citizens [
set shape "person"
set size 1.5
set color white
setxy random-xcor random-ycor ]
;; create four service desks
ask patch 0 8 [
sprout 1 [
set breed service-desks
set shape "building institution"
set color pink
set size 3 ]
]
ask patch 0 -8 [
sprout 1 [
set breed service-desks
set shape "building institution"
set color pink
set size 3 ]
]
ask patch -8 0 [
sprout 1 [
set breed service-desks
set shape "building institution"
set color pink
set size 3 ]
]
ask patch 8 0 [
sprout 1 [
set breed service-desks
set shape "building institution"
set color pink
set size 3 ]
]
;; create 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 ;; sets all employees randomly within the grey square
place-on-color-citizens ;; sets citizens randomly outside of the grey box
reset-ticks
end
to place-on-color-employees
let _patches (patches with [pcolor = grey])
ask employees [
move-to one-of (_patches with [not any? turtles-here])
]
end
to place-on-color-citizens
let _patches (patches with [pcolor = black])
ask citizens [
move-to one-of (_patches with [not any? turtles-here])
]
end
to go
employee-movement
employee-take-money
citizen-movement
tick
end
to employee-movement
ask employees [
ifelse [pcolor] of patch-ahead 1 = black
[ rt random-float 360]
[ forward 1 ]
let target one-of citizens
if money-held > 0 [
set heading (towards target)
]
]
end
to citizen-movement
;; citizens walk only in the black patches, they do not go into the office area
ask citizens [
ifelse [pcolor] of patch-ahead 1 = grey
[ rt random-float 360]
[ forward 1 ]
;; if they have no money, then the citizens will walk to one of the service-desks
let target one-of service-desks
if money-received = 0 [
set heading (towards target )
]
]
end
to employee-take-money ;; asks employees to go to the main office and get money
ask employees [
if any? turtles-here with [ shape = "building institution" and color = yellow] [
set money-held money-held + 1
set color green ]
]
end
The issue I have is that within the employee-movement function, the employees will not move towards their targets. Whereas, the citizens will move to their targets. The code for both breeds is basically the same. The employees tend to congregate around the central patch, rather than moving to the targets.
Edited after receiving the full code:
The problem lies with how you define target as a local variable (let target one-of service-desks) each time you call the code. However, since there is more than one service-desk, nothing is forcing them to choose the same service-desk each time. This means that the employees, who are standing in the middle of the four service-desks, are basically taking a step in a random direction at each tick. The citizens on the other hand stand outside of the square on which the service-desks are located. Because of that, all of the service-desks are roughly in the same direction for them, so their general movement also goes in that direction.
I see two different options for working around this. The first one is to not use let target one-of service-desks but use let target min-one-of service-desks [distance myself]. This moves them to the closest service-desk rather than to a random service desk.
The other option would be to set target as a turtles-own variable, and not letting them choose a new one all the time.
Finally I streamlined your setup a little bit, reducing the amount of code you needed.
globals [
office-space
num-of-money
num-of-employees
num-of-citizens
]
breed [ offices office ]
breed [ service-desks service-desk ]
breed [ employees employee ]
breed [ citizens citizen ]
offices-own [ money ]
employees-own [ money-held ]
citizens-own [ money-received ]
to setup
clear-all
set num-of-money 100
set num-of-employees 5
set num-of-citizens 5
create-offices 1 [
set shape "building institution"
set size 4
set color yellow
set money num-of-money
]
create-employees num-of-employees [
set shape "person"
set size 1.5
set color blue
setxy random-xcor random-ycor
]
create-citizens num-of-citizens [
set shape "person"
set size 1.5
set color white
setxy random-xcor random-ycor
]
;; create four service desks
let service-desk-patches (patch-set patch 0 8 patch 8 0 patch 0 -8 patch -8 0)
ask service-desk-patches [
sprout-service-desks 1 [
set shape "building institution"
set color pink
set size 3
]
]
;; create 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 ;; sets all employees randomly within the grey square
place-on-color-citizens ;; sets citizens randomly outside of the grey box
reset-ticks
end
to place-on-color-employees
let _patches (patches with [pcolor = grey])
ask employees [
move-to one-of (_patches with [not any? turtles-here])
]
end
to place-on-color-citizens
let _patches (patches with [pcolor = black])
ask citizens [
move-to one-of (_patches with [not any? turtles-here])
]
end
to go
employee-movement
employee-take-money
citizen-movement
tick
end
to employee-movement
ask employees [
ifelse [pcolor] of patch-ahead 1 = black
[ rt random-float 360]
[ forward 1 ]
let target min-one-of citizens [distance myself]
if money-held > 0 [
set heading (towards target)
]
]
end
to citizen-movement
;; citizens walk only in the black patches, they do not go into the office area
ask citizens [
ifelse [pcolor] of patch-ahead 1 = grey
[ rt random-float 360]
[ forward 1 ]
;; if they have no money, then the citizens will walk to one of the service-desks
let target min-one-of service-desks [distance myself]
if money-received = 0 [
set heading (towards target )
]
]
end
to employee-take-money ;; asks employees to go to the main office and get money
ask employees [
if any? offices-here [
set money-held money-held + 1
set color green ]
]
end
I´m setting up some turtles randomly on the the map, then they have to change the color of the patches to show that they cultivated however some times they overlap and change the color of other turtles. To solve this i asked not any? other turtles in-radius 6 to force them to be apart, but this is not elegant nor efficient. What would be a better way to give each turtle their own patch to make a more populated world.
to setup
ca
resize-world 0 100 0 100
create-turtles 50
[ set size 1
set color 135
setxy random-xcor random-ycor
move-to one-of patches with [not any? other turtles in-radius 6]
ask patches in-radius (2 + random 2) [set pcolor 35]
]
end
to go
ask turtles[ ask patches in-radius 4 with [pcolor = 35]; falta representar las cosechas 4-2-3-3
[ set pcolor 42]]
end
The go is using the fact that there are no turtles in a radius of 6, but if i wanted to get them closer or change the color on different ticks this would be bad.
Thanks. If more is need please let me know.
You can give the turtles a new turtles-variable that you can assign a patch-set to. This is done by using turtles-own at the start of your program.
The turtle then remembers which patches were assigned to this variable and can access them again at a later time. This way, when it comes time to change patch colors, they only change the colors of patches within their original radius and not of the patches in the extended radius.
turtles-own [territory]
to setup
ca
resize-world 0 100 0 100
create-turtles 50
[ set size 1
set color 135
setxy random-xcor random-ycor
set territory patches in-radius (2 + random 2)
ask territory [set pcolor 35]
]
end
to go
ask turtles [ ask territory ; falta representar las cosechas 4-2-3-3
[ set pcolor 42]]
end
As an alternative solution, here it is not the turtles that remember which patch they own, but the patches that remember which turtle owns them. In the case I use here, patches can only be owned by a single turtle.
Here, I give each patch a patch-variable using patches-own. I then let the turtles tell the patches within their radius to choose that turtle as their owner ask patches ... [set owner myself]. Myself is a reporter that refers not to the patch carrying out the command, but to the turtle that asked the patch to carry out the command.
patches-own [owner]
to setup
ca
resize-world 0 100 0 100
create-turtles 50 [
set size 1
set color 135
setxy random-xcor random-ycor
ask patches in-radius (2 + random 2) [
set owner myself
set pcolor 35
]
]
end
to go
ask turtles [ ask patches in-radius 4 with [owner = myself] ; falta representar las cosechas 4-2-3-3
[ set pcolor 42]
]
end
If multiple turtles try to be the owner of the same patch, the last one becomes the owner. This is because each turtle completely overwrites the previous owner value.
If you still want an option for multiple owners, you can work with a turtle-set instead. This requires a few different primitives.
In setup, you have to define owners as an empty turtle-set in order for the rest to work, using set owners (turtle-set).
To then assign a turtle to owners, you use set owners (turtle-set owners myself). This changes the owners turtle-set to add the turtle calling the patch to the set.
Finally, you can no longer ask patches to with [owner = myself] to change color since owners is now a turtle-set, not a turtle. Instead, you use the member? primitive that looks if a turtle is part of a turtle-set.
patches-own [owners]
to setup
ca
resize-world 0 100 0 100
ask patches [set owners (turtle-set)]
create-turtles 50 [
set size 1
set color 135
setxy random-xcor random-ycor
ask patches in-radius (2 + random 2) [
set owners (turtle-set owners myself)
set pcolor 35
]
]
end
to go
ask turtles [
ask patches in-radius 4 with [member? myself owners] ; falta representar las cosechas 4-2-3-3
[ set pcolor 42]
]
end
im trying to show a cultivation process. At setup im creating the farmers and giving them a random farm size (with the splotch) then, at go, im telling them that if they have enought money all patches near them that are the splotch turn into green, representing cultivation. But its just changing one pixel and not all round it. It most be someting small but i cant see it. Thanks in advance for the help
.
breed [cercas cerca]
breed [medios medio]
breed [lejos lejo]
patches-own[calidad
cercanialago
cultivado
]
turtles-own [ingresos
gastos]
create-cercas 10 + random 10
[ set size 1 ;; easier to see
set color 135
setxy random xcor random ycor
move-to one-of patches with [not any? other turtles in-radius 3 and pcolor = 57]
set heading random 45 + 45
set ingresos 1000000 + random 6000000
]
ask turtles
[ ask patches in-radius (1 + random 3)
[ set pcolor 35 ] ]
to go
ask cercas [
ifelse ingresos > 2000000 [if any? patches in-radius 4 with [pcolor = 35] [if ticks mod 3 = 0 [set pcolor 62] ]]
[]
] ```
Your cercas are a breed of turtles.
A useful feature of NetLogo is that any turtle can directly read and modify the variables of the patch it is on (i.e. without the need to invoke such patch).
So when you ask a turtle to set pcolor 62, it will automatically refer to pcolor of the patch it is on.
If we eliminate all of the conditions from your last block of commands, we have:
ask cercas [set pcolor 62]. This is what you are asking cercas to do: simply changing the pcolor of the patch they are on.
The fact that you use patches in-radius 4 in the condition for the first if statement does not influence the ask cercas [set pcolor 62] part. The condition is one thing, the command to be executed if the condition holds true is a separate thing.
Therefore you should make cercas ask patches in-radius 4 to change their pcolors.
I am attempting to code a path-finding behavior wherein agents will locate an optimal patch in the environment and navigate their way around fences to reach said patch. I've created a patch variable 'f', which is set to 1 to indicate fences and 0 for any other patch.
I want to make these fences impassable (i.e. I want them to be patches the agents will not use for movement), but agents still seem to be able to travel on them to some extent and in some cases are even able to fully cross them.
Here is a picture of an agent crossing a barrier I don't want it to cross
Relevant decision-making code for the agents is as follows:
{let moveset patches in-radius 30 with [f = 0 and n > 0]
let target max-one-of moveset [n]
ifelse patch-here != target
[
set heading towards target
]
[]
let chance random-float 10
if chance >= 5 [let pick -145]
if chance < 5 [let pick 145]
ask patches in-radius 1
[if f = 1
[ask myself
[set heading towards min-one-of patches [distance myself] + 180 - random 10 + random 10 ]
]
]
fd 1}
For clarity, 'n' is simply a variable to denote the patch I want my agent to locate and venture to.
Is anyone aware of a simple way in NetLogo to exclude certain patches as viable zones for movement in the decision making process (i.e. hard barriers)?
If you haven't yet, have a look at the "Look Ahead" example in the Models Library- it's a simple demonstration of using patch color to control turtle movement. Some code based on that model is below. With this setup:
breed [ seekers seeker ]
breed [ goals goal ]
patches-own [ steps-from-goal ]
to setup
ca
ask patches [
set steps-from-goal 999
]
ask patches with [ pxcor mod 10 = 0 ] [
set pcolor red
]
ask patches with [ pycor mod 10 = 0 ] [
set pcolor black
]
ask one-of patches with [ pcolor = black ] [
sprout-seekers 1 [
set color blue
pd
]
]
ask one-of patches with [ pcolor = black ] [
sprout-goals 1 [
set color white
set shape "circle"
]
]
reset-ticks
end
You can have the seekers breed wander around the black squares until they share a patch with a goal turtle:
to random-wander
ask seekers [
if any? goals-here [
stop
]
rt random 61 - 30
ifelse can-move? 1 and [pcolor] of patch-ahead 1 = black [
fd 1
] [
rt one-of [ 90 -90 ]
]
]
tick
end
However, note that turtles can still 'jump' corners of patches using this method, because they are able to assess the patch-ahead 1 at any angle- so, a patch one space ahead of a turtle may be assessed across the corner of another patch. The turtle should never actually land on the forbidden patch, but you may notice that their path can cross those blocked patches.
Edit:
See simplified code that "traps" a turtle in a square cage:
to setup
ca
crt 1 [
setxy 5 5
set heading 180
repeat 4 [
repeat 10 [
ask patch-here [ set pcolor red ]
fd 1
]
rt 90
]
die
]
crt 1 [ pd ]
reset-ticks
end
to go
ask turtles [
rt random 61 - 30
ifelse can-move? 1 and [pcolor] of patch-ahead 1 = black [
fd 1
] [
rt one-of [ 90 -90 ]
]
]
tick
end
After 1100 ticks:
After 13300 ticks:
I am very new to netlogo. I have searched every question here before I posted this.
I have the following code which sprouts a given number of horses:
ask n-of Number-horses patches with [grass? = "Yes"]
[sprout-horses 1 [set color 25 ]]
The person can change the number of horses using the slider but I would like each horse to have its own area/range/radius.
They can only move within this radius/area and they cannot meet each other.
From what I've read it's got something to do with the distance function?
You can find a similar problem here which has examples too :
Spacing agents in NetLogo based on territory size
There are several ways that you can assign a territory zone to each horse, but all methods that I know have two steps, first step is in order to make sure initial home area of horses are separated from each other , So we need to create horses only in patches which has a certain distance from another patch which has a horse on it,I did not follow your method that asked patches to sprout horses and instead I created them without asking patches.
I was not sure how you defined grass? Variable for each patch but I have assigned a number of patches with grass? = true and others false.
Second step is to set home-area property of each horse. If initially you moved them far away from each other they will have separate territories.
I have included a few examples here :
First to use in-radius for both steps:
Breed [Horses horse]
Horses-own [home-area]
patches-own [grass?]
globals [Zone-Radius]
to setup
clear-all
reset-ticks
set Zone-Radius 2
ask patches
[
ifelse pxcor mod 5 = 3
[ set Grass? true ]
[ set Grass? false ]
]
create-horses Number-horses
[ Move-to one-of patches with [Grass? and not any? other horses in-radius (Zone-Radius + 1)]
set home-area patches in-radius Zone-Radius
set color 25
]
end
to go
ask horses [
ifelse member? patch-ahead 1 home-area
[rt random 10 fd 1 ] ; move if next patch is in their zone
[rt random 180]
]
tick
end
In this example horses only move in the patches in their radius 2. But you can change that base on your model requirements.
In the second method you can use distance for the first step (finding empty patches with enough distance to current patch) and radius for second one (assigning home-area to each horse).
Move-to one-of patches with [Grass? and not any? other horses with [distance myself < (Zone-Radius + 1)]]
set home-area patches in-radius Zone-Radius
If you use higher distance for finding empty patches you will have completely seprated zones. Finally , you can use distance for both steps:
Move-to one-of patches with [Grass? and not any? other horses with [distance myself < (Zone-Radius + 1)]]
set home-area patches with [distance myself < Zone-Radius]
I just did it another way:
Breed [Horses horse]
Horses-own [home-area]
patches-own [ concession? forest? parks?]
globals [Zone-Radius]
to setup
clear-all
reset-ticks
set Zone-Radius 2
ask n-of 500 patches [ set concession? "No" ]
ask n-of 500 patches[ set forest? "Yes" ]
ask n-of 500 patches[ set parks? "Yes"]
let i 0
while [i < Number-horses]
[
ask one-of patches with [(concession? = "No" or forest? = "YES" or parks? = "YES" ) and (not any? horses in-radius (Zone-Radius + 2) )]
[
sprout-horses 1 [
set home-area patches with [distance myself < Zone-Radius]
let w who
ask home-area [set pcolor red]
set color 25 ]
]
set i (i + 1)
]
end
to go
ask horses [
ifelse member? patch-ahead 1 home-area [rt random 10 fd 1 ] [rt random 180]
]
tick
end
As you can see I used while and a condition to ask patches one by one, I might be mistaken but when I ask all the n-of Number-of-horses patches with [YourCondition][...] I get the wrong results and distance between horses is not effective, maybe they are created all at the same time and therefore upon creating a horse there was no horse nearby!? I am new to these concepts and might be wrong.
This is the code and view for the one which asks patches to create horses at once here :
Breed [Horses horse]
Horses-own [home-area]
patches-own [ concession? forest? parks?]
globals [Zone-Radius]
to setup
clear-all
reset-ticks
set Zone-Radius 2
ask n-of 500 patches [ set concession? "No" ]
ask n-of 500 patches[ set forest? "Yes" ]
ask n-of 500 patches[ set parks? "Yes"]
ask n-of number-horses patches with [(concession? = "No" or forest? = "YES" or parks? = "YES" ) and (not any? horses in-radius (Zone-Radius + 2) )]
[
sprout-horses 1 [
set home-area patches with [distance myself < Zone-Radius]
let w who
ask home-area [set pcolor red]
set color 25 ]
]
end
to go
ask horses [
ifelse member? patch-ahead 1 home-area [rt random 10 fd 1 ] [rt random 180]
]
tick
end