I have added 4 different user input sliders into net-logo. Yellow, red and green should represent percentages of the total patches grid, whilst the blue one is on a set amount of 0-10 (non-percentage). The % sliders vary in value for both green red and yellow. When I'm setting up the grid with the following code, only the blue patches are being inserted in the grid. I'm also looking to continuously have the same % of each colored patch throughout the simulation. Any help is appreciated as I've been trying this one for a good couple hours without any luck googling.
let total 961
let p-yellow yellow-patches-amount-% * 100 / total
let p-green (green-patches-amount-% * 100) / total
let p-red (red-patches-amount-% * 100) / total
let p-blue blue-patches-amount
let patch-yellow p-yellow
ask patches with [pcolor = black] [
if count patches with [pcolor = blue] < p-blue [
ask n-of p-blue patches [set pcolor blue]
]
]
ask patches with [pcolor = black] [
if count patches with [pcolor = yellow] < p-yellow [
ask n-of p-yellow patches [set pcolor yellow]
]
]
end
Your problem is how you define p-yellow, and how you use your percentage.
Let's say yellow-patches-amount-% is 50. Multiply that by 100 and you get 5000. divide that by 941 and you get 5.3 yellow patches. That number is then rounded down by n-of.
The correct way of using percentages here is:
let p-yellow yellow-patches-amount-% / 100 * total
Then there are a few problems with how you recolor your patches. I will address them one by one.
In your code, you have a ask patches [ ask patches [...]] construction. This is almost always a horrible idea, since it means that every patch can be asked to do something patch number of times, instead of just once. Letting one agent ask all agents to do something can be okay. Letting all agents ask one agent to do something can be okay. But letting all agents ask all agents to do something will almost always lead to code not doing what you want. I simplified the code you were using to illustrate this.
to setup
ca
let total count patches ;1089 in this case
let p-yellow 5 * total / 100 ;54.45 in this case
ask patches with [pcolor = black] [
if count patches with [pcolor = yellow] < p-yellow [
ask n-of p-yellow patches [set pcolor yellow]
show count patches with [pcolor = yellow] ;first 54, next 108 or a bit lower
]
]
end
With this setup, you would want 54 patches to become yellow. The first black patch that you call upon will now count all yellow patches, which is 0. Because of that, it now asks p-yellow, rounded down, random patches to turn yellow. Now the second black patch comes up and counts all yellow patches. It comes up with 54, which is lower than 54.45, so again it asks 54 random patches to turn yellow. By now you have more than 54.45 yellow patches so all subsequent patches count them but no longer ask any patches to change color. But that still means you turned a patch yellow 108 times instead of 54 times.
Even though you turned a patch yellow 108 times, you didn't necessarily turn 108 different patches yellow. If you ask n-of p-yellow patches [set pcolor yellow] once, then each patch can only be turned yellow once. This breaks down if you do it multiple times, since now ask n-of p-yellow patches [set pcolor yellow] can also ask a patch that you previously turned yellow to turn yellow again. This can be avoided by using ask n-of p-yellow patches with [pcolor = black] [set pcolor yellow]. It is especially important since you are working with multiple colors.
Finally, the if count patches with [pcolor = yellow] < p-yellow construction makes sense if you are turning patches yellow one by one until you have >= p-yellow patches. The moment you turn more than 1 patch yellow at the same time, this sort of construction can easily let you overshoot your target.
With that in mind, I have two different suggestions for you
to setup-1
ca
let total count patches ;1089 in this case
let p-yellow 5 * total / 100 ;54.45 in this case
ask n-of p-yellow patches with [pcolor = black] [set pcolor yellow] ;54 in this case
end
to setup-2
ca
let total count patches ;1089 in this case
let p-yellow 5 * total / 100 ;54.45 in this case
while [count patches with [pcolor = yellow] < p-yellow] [
ask one-of patches with [pcolor = black] [set pcolor yellow]
] ;55 in this case
end
setup-1 simply turns the required number of patches yellow all at once and is done with it.
setup-2 turns black patches yellow one by one, until the count of yellow patches exceeds p-yellow. Note that this will get you 55 yellow patches instead of 54, since p-yellow > 54. If you would want it to be rounded down instead, you could use floor, which rounds a value down to the nearest integer:
[count patches with [pcolor = yellow] < floor p-yellow]
Related
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 created a world divided in two parts with the command ask patches with [ pxcor < 0] [set pcolor blue] ask patches with [pxcor > 0] [set pcolor green] .
In one of this there're 100 turtles, who 5 are infected and the same in the other part.
My problem is to force the turtles to move only in their part of the world. So I want that turtles with pcolor = blue move randomly in the second and third quadrant (pxcor <0) and turtles with pcolor = green in the first and fourth quadrant (pxcor> 0). how do I do?
This is the code:
turtles-own
[
sick?
sick-time]
to setup
ca
ask patches with [ pxcor < 0 ] [set pcolor blue] ; we want divide the world in two parts: the blue one in the north of Italy
ask patches with [pxcor > 0 ] [set pcolor green]; the white one is the south of Italy
ask patches with [pxcor = 0 ] [set pcolor white ] ; represent the border
create-turtles 200 ; we create a population made up for 200 people
[ set size 1
set shape "person"
set sick-time 0
get-healthy]
ask n-of 100 turtles ; 100 of this one live in north of Italy
[setxy 12 random-ycor ]
ask n-of 100 turtles ; another 100 in the south
[setxy -12 random-ycor
]
ask n-of 5 turtles with [pcolor = blue] ; we want infect 5 people for each world
[get-sick ]
ask n-of 5 turtles with [pcolor = green]
[get-sick ]
reset-ticks
end
to get-healthy
set sick? false
set color white
end
to get-sick
set sick? true
set color yellow
set shape "circle"
set sick-time sick-time + 1
end
to go
ask turtles
[
move ]
tick
end
to move
rt random-float 360
fd 1
end
Your movement procedure looks like:
to move
right random-float 360
forward 1
end
If you want them to just stay where they are if moving would take them into the wrong half, then you can use patch-ahead to test the patch they'd be moving to. I think what you want is that they don't go to a different coloured patch. One way is:
to move
right random-float 360
if [pcolor] of patch-ahead 1 = pcolor [forward 1]
end
[pcolor] of patch-ahead 1 returns the colour of the patch that is one distance unit ahead, so where the turtle is trying to move to. pcolor is the colour of the patch that the turtle is currently standing on.
I want to change color of patches to green under these conditions:
-IF there are any two blue patches on same column and their distance is smaller than 25 AND
-IF there are any yellow patches on same column and between these selected blue patches
-Then change color of all patches satisfying these conditions to green.
I am struggling to make it in NetLogo, tried using nested loop but couldn't find a way. Thank you for any help. And I have added a sample image which I want to achieve and marked example blue patches.
As addition, to show what I want to do in code (sorry about code):
if any? patches with [pcolor = blue and
(if any? patches with [pcolor = blue and pycor = ?(selected_first_blue's_pycor)
if any? patches with [pcolor = yellow and pycor < ??(selected_first_blue's_pycor) and pycor > ?(selected_second_blue's_pycor)))
[ask patches [set pcolor green]]
The way you are approaching it, you need fairly convoluted statements like:
let upper-blues patches with [color = blue and
any? other patches with [color = blue and pxcor = [pxcor] of myself
and pycor < [pycor] of myself and pycor > [pycor] of myself - 25]
I believe this would be much easier to take the perspective of the patch you want to potentially turn green. If I have interpreted your conditions correctly, that patch needs to work out the closest yellow patch above/below/at and then check if there are two blue patches bracketing both the yellow and itself with the blue patches sufficiently close to each other. I assume you have wrapping turned off.
Here is a complete model that puts in a red turtle instead of turning the patch green so you can see whether it is identifying the correct patches.
to setup
clear-all
ask patches [set pcolor white]
ask n-of 100 patches [set pcolor blue]
ask n-of 100 patches [set pcolor yellow]
end
to convert-to-green
let turn-green nobody
ask patches
[ let my-column patches with [pxcor = [pxcor] of myself]
let above-yellow min-one-of my-column with [pcolor = yellow and pycor >= [pycor] of myself][pycor]
let above-blue ifelse-value (above-yellow != nobody) [min-one-of my-column with [pcolor = blue and pycor > [pycor] of above-yellow][pycor]][nobody]
let below-yellow max-one-of my-column with [pcolor = yellow and pycor <= [pycor] of myself][pycor]
let below-blue ifelse-value (below-yellow != nobody) [max-one-of my-column with [pcolor = blue and pycor < [pycor] of below-yellow][pycor]][nobody]
if above-blue != nobody and below-blue != nobody and ([pycor] of above-blue - [pycor] of below-blue < 25)
[ set turn-green (patch-set self turn-green)
]
]
ask turn-green [sprout 1 [set color red]]
end
Once you are satisfied it is working correctly, change ask turn-green [sprout 1 [set color red]] to ask turn-green [set pcolor green].
This code checks each patch in random order and adds it to the set of patches (called turn-green) if the conditions are satisfied. Once all patches have been tested, the set of selected patches then change their colour. This avoids issues of yellow or blue patches turning green and not being available for later patches to check against.
In setup, I am trying to set an exact percentage of the overall patches red pcolor or green pcolor.
I am using the standard patch environment, with 1089 total patches.
I have two sliders:
slider1 (for setting up to 250 green turtles)
slider 2 (for setting up to 250 red turtles)
Is there a way to set an exact percentage of the 1089 total patches red and the remaining percentage green?
Adapting code from a helpful Q&A previously posted on this site, I have this draft coding:
to color-patches
let total slider1 + slider2
let p-red slider1 / total
let p-green slider2 / total
ask patches [
let x random-float 1.0
if x <= p-red [set pcolor red]
if x <= p-green [set pcolor green]
]
end
Any helpful advice would be much appreciated.
You want n-of!
ask n-of (p-red * count patches) patches [ set pcolor red ]
ask patches with [ pcolor != red ] [ set pcolor green ]