Netlogo turtle skips specific patch - netlogo

I am trying to instruct turtles to visit all green patches.
There is a behavior which I can't get my head around: patch 0,0 is always avoided if the location of origin = center (see screenshot with 0,0 colored blue), and the lower left corner if location of origin = corner.
Why is this? What error am I making here?
;;==========================================================
globals [
memory
target
]
patches-own [visit-counter]
;;==========================================================
to setup
ca
resize-world -6 6 -6 6
set-patch-size 40
create-turtles 1 [
set memory (list patch-here)
setxy random-pxcor random-pycor
set size 1
set color blue
]
ask patches [if random 100 < 40 [set pcolor green]]
ask patch 0 0 [set pcolor green]
ask patches [set visit-counter 0]
reset-ticks
end
;;==============================================
to go
ask turtles [choose-target]
tick
if ticks > 500 [stop]
end
;;==============================================
to choose-target
pd
;; set of unvisited patches
let unvisited patches with [not member? self [memory] of myself]
;; set of green patches that are not visited
let targets patches with [(member? self unvisited) and (pcolor = green)]
;; select target and move there
set target one-of targets with-min [distance myself]
ifelse target != nobody [
face target
fd 1
set visit-counter (visit-counter + 1)
set memory lput patch-here memory
]
[die
]
end

When you initialise the variable 'memory', you have set memory (list patch-here). At that point, the turtle is sitting on patch 0 0, so the origin patch is in the memory. Your code for finding targets excludes those already in the memory let unvisited patches with [not member? self [memory] of myself]. It is therefore ineligible to be chosen as a target.

Related

How to give property to agents Netlogo

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

How to force turtles to move only in a half of the world?

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.

Imported Patch colors not working correctly in NetLogo

I've been trying to get my turtles to 'bounce' off a wall using Netlogo.
I've imported a png file that has the colors of the different surfaces (walls, interface, liquid, heater eventually there will be a few more). I used MSPaint and the colormap from netlogo color chart to create my shapes (a purple square, with brown on the side borders, red border on the bottom and blue border on the top)
What I'm trying to do is have the turtles start on the liquid patches and move in straight lines until they bump into a surface (different colored wall). If they bump into a wall, they should 'bounce' off in a random direction, if they hit the heater, their temperature should go increase and they should also bounce off of the heater surface. If they bump into the interface and their temperature is above 100, they should move through the interface and then move around above the interface (basically teleport up a few pixels).
The issue I'm having is that the turtles move around and they appear to be bouncing off the walls just fine, but they seem to be oblivious to the colors of the heater and the interface. I'm sure I'm missing something basic or obvious, but I've been struggling for three days on this same quirk. Any help would be greatly appreciated.
Here is the code I have right now:
(in this code I have it set to just 'teleport' through the interface regardless of the temperature of the water)
globals[ liquid-color heater-color wall-color reflection-color air-color interface-color
liquid heater wall reflection air interface]
breed [h2o water]
to setup
clear-turtles
reset-ticks
clear-all-plots
import-pcolors "boilermap.png"
set liquid-color 115
set heater-color 19
set wall-color 35
set interface-color 105
setup-patches
create-molecules
end
to setup-patches
set heater patches with [pcolor = heater-color]
set heater-color 19
ask heater [set pcolor 19]
set interface patches with [pcolor = interface-color]
set interface-color 105
ask interface [set pcolor 105]
set liquid patches with [pcolor = liquid-color]
set liquid-color 115
ask liquid [set pcolor 115]
set wall patches with [pcolor = wall-color]
set wall-color 35
ask wall [set pcolor 35]
end
to create-molecules
create-h2o (totalmoles * h20number / 100)[
set shape "circle"
set color black
set size 2
set temperature 20
setxy random xcor random ycor
move-to one-of patches with [pcolor = liquid-color]
]
to go
ask h2o [
(ifelse
pcolor = liquid-color[fd 1 ];ifblock
pcolor = heater-color [set temperature temperature + 5]
pcolor = interface-color [set ycor ycor + 100] ;just trying to get them to jump here, regardless of their temperature
;elseblock
[ bk 1
rt random 180]
)]
end
Diesel, you have a great start on this! I put some code below that answers your questions.
By the way, the title on your question doesn't really match what your actual problem was: imported patch colors not working correctly
I suspect the reason your code ignores the heater and interface is that they imported as pcolors that don't match the ones you expected. I added a verify-colors command that checks to see if the imported colors are correct. I also added an option to generate a new boiler image you can work with in case importing still causes more problems.
Also, I notice you are adding 100 to ycor when your molecule hits the interface. It's possible this moves the molecule entirely up out of view, which could be confusing, as the default view is only 32 units high. I changed the 100 to 5 to keep the molecule in view.
I cleaned up a few more things and confirmed the model ran successfully. The handling of correct bouncing off walls and off the heater was not addressed -- that's your job!
Here's the things I tweaked in your code:
;;
;; added h2o-own section so molecules each have a temperature
;; added a user-choice of whether to import the boilermap.png or create a new one here
;; if importing, verify the colors exactly match the valid colors
;; added "make-drawing" and "verify-colors" sections at the end
;; moved reset-ticks to the end of setup, its usual location
;; added ticks to the end of the go section !!
;; added set-aircolor grey ( it wasn't defined )
;; cleaned out unneeded commands from the setup-patches section. You already have the
pcolors imported, so you don't need to set them again.
;; added "set label temperature" to the create-molecules section as well as to the place
;; where temperature is increased at the heater, so each molecule shows its current temperature
I tested it with interface variables h2o-number =100 and total-moles either 1 or 5 and speed set to very slow. It works!
globals[ liquid-color heater-color wall-color reflection-color air-color interface-color
liquid heater wall reflection air interface]
breed [h2o water]
h2o-own [
temperature
]
to setup
clear-turtles
clear-all-plots
set liquid-color 115
set heater-color 19
set wall-color 35
set interface-color 105
set air-color grey
if-else user-yes-or-no? "import boilermap.png?"
[
import-pcolors "boilermap.png"
verify-colors ;; check the command section for counts of pcolors
]
[
make-drawing ;; just make a new image of a boiler
]
setup-patches
create-molecules
reset-ticks ;; usually, do this as the last step in setup
end
to setup-patches
set heater patches with [pcolor = heater-color]
set interface patches with [pcolor = interface-color]
set liquid patches with [pcolor = liquid-color]
set wall patches with [pcolor = wall-color]
end
to create-molecules
no-display
create-h2o (totalmoles * h20number / 100)[
set shape "circle"
set color black
set size 2
set temperature 20
setxy random xcor random ycor
move-to one-of patches with [pcolor = liquid-color]
set label temperature
]
display
end
to go
ask h2o [
(ifelse
pcolor = liquid-color[fd 1 ]
pcolor = heater-color [ set temperature temperature + 5 set label temperature set heading 0 forward 1]
pcolor = interface-color [set ycor ycor + 5 forward 1 ]
pcolor = wall-color and pxcor < 0 [set heading 135 forward 1]
pcolor = wall-color and pxcor > 0 [set heading 220 forward 1]
[ bk 1
rt random 180]
)]
tick ; DONT FORGET THIS !!
end
;; ========================== new utility functions ===
to make-drawing
no-display
ask patches with [ pycor > 1] [ set pcolor air-color]
ask patches with [ pycor < 1] [set pcolor liquid-color]
ask patches with [ abs pycor <= 1] [ set pcolor interface-color]
ask patches with [ pycor < (min-pycor + 4)] [ set pcolor heater-color]
ask patches with [ pxcor > (max-pxcor - 2)] [ set pcolor wall-color]
ask patches with [ pxcor < (min-pxcor + 2)] [ set pcolor wall-color]
ask patches with [ pycor > (max-pycor - 2)] [ set pcolor wall-color]
ask patches with [ pycor < (min-pycor + 2)] [ set pcolor wall-color]
display
end
to verify-colors ;; see what we imported
let good-colors (list
liquid-color
heater-color
wall-color
interface-color
air-color )
let good-count count patches with [member? pcolor good-colors]
let bad-count count patches - good-count
type "good patch count " type good-count type ", bad patch count: " print bad-count
if bad-count > 0 [ if "no" = user-yes-or-no? " bad patch colors, should I continue?" [stop] ]
end

Netlogo: find next target discounting previous targets

I'm trying to get my agents to calculate the next patch target once they have reached their first target. A target is defined as the (highest patch influence value / distance to agent). The next target needs to be calculated using this same procedure, but also discounting any previous targets from the equation.
I have attempted to create a patch-set to include all targets, although I'm not sure if it works.
My issue is how to create a to-report function that calculates the next highest-influence-value. I've gotten completely stuck with this final part of my procedure.
My initial reporter function is:
to-report highest-influence
let available-target patches with [influence > 0] ;and not any? patches with [pcolor = green]
report max-one-of available-target [influence / distance myself]
end
But I'm not sure how to have the next reporter function use the same parameters while also discounting any previous targets
to-report next-highest-influence
; patches with [influence > 0] and not part of patch set
end
Any help would be greatly appreciated. I've provided the full code.
breed [walkers walker]
walkers-own [traveled? ;; parameter to keep track of if a walker has traveled to a target yet or not
target ]
patches-own [influence influence-set] ;highest-influence
to setup
clear-all
reset-ticks
define-patches
create-walkers num-walkers
ask walkers [
setxy 0 0
set heading 90
let streets neighbors with [pcolor = black]
ifelse any? streets in-cone 1 25
[fd 1]
[move-to one-of streets in-radius 1]
set traveled? false ;; so that walkers know they have not yet moved to a target
]
ask walkers [
define-target ]
end
to define-patches
ask n-of 100 patches [
set pcolor white
]
ask n-of 40 patches with [pcolor = white] [set influence random 5 set pcolor blue set plabel influence]
ask patches [set influence-set patches with [pcolor = green] ]
end
to define-target ;; this defines the initial destination of walkers
if traveled? = false [
set target highest-influence
ask target [set pcolor green]
face target ]
end
to new-target ;; this defines subsequent desinations after walkers have reached inital target
if traveled? = true [
set target next-highest-influence
ask target [set pcolor green + 2]
face target ]
end
;;;;;;;;;;;;run-time procedure;;;;;;;;;;
to go
ask walkers [
if distance target > 1
[ travel-walkers
leave-a-trail
set traveled? true ]
if distance target = 1
[ stop
new-target
travel-walkers
leave-a-trail
]
]
tick
end
to travel-walkers
ask walkers [
move-towards-target
]
end
to move-towards-target
ask walkers [
ifelse [pcolor] of patch-ahead 1 != white or any? other turtles-here
[ Move-Function ]
[ Avoid-Function ]
]
end
to Move-Function
let t target
face min-one-of all-possible-moves [distance t]
fd 1
end
to Avoid-Function
let t target
face min-one-of all-possible-moves [distance t]
end
to leave-a-trail
ask patch-here [set pcolor grey]
end
;;;;;; reporter calculations ;;;;;;
to-report highest-influence
let available-target patches with [influence > 0] ;and not any? patches with [pcolor = green]
report max-one-of available-target [influence / distance myself]
end
to-report next-highest-influence
; patches with [influence > 0] and not part of patch set
end
to-report all-possible-moves
report patches in-radius 1 with [pcolor != white and distance myself <= 1 and distance myself > 0 and plabel = "" ]
end
You can make use of the member? primitive to do that. Check out the simplified toy model below (I didn't use your code as I'm not sure how you'd want to implement and there are some interface pieces i would need to set up to run it. Check out the MCVE guidelines).
turtles-own [ visited-list ]
patches-own [ influence ]
to setup-member?
ca
crt 1 [ set visited-list [] ]
ask patches [ set influence 0 ]
ask n-of 5 patches [ set influence 5 + random 50 ]
reset-ticks
end
to go-member?
ask turtles [
let target highest-influence
ifelse target != nobody [
face target
ifelse distance target > 1 [
fd 1
] [
move-to target
ask target [ set pcolor red]
set visited-list lput target visited-list
]
] [ print "No targets remaining." ]
]
tick
end
to-report highest-influence
let to-visit patches with [
influence > 0 and
not member? self [visited-list] of myself ]
report max-one-of to-visit [ influence / ( distance myself )]
end
The reported returns the patch with the highest influence/distance value that is not a member of the turtle's visited-list. Initially, no patches are a member of the list, but as the turtle visits each target, it adds the target to the visited-list so that patch is no longer considered.

Define home area-turtles?

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