Print "no patch" when there is no more patches to occupy - netlogo

I want to print "no path" when there is no more patches to occupy instead of warned by an Error "MOVE-TO expected input to be an agent but got NOBODY instead.". I did several things but did not work. Lastly, I did the following;
ask migrants
[let pot-target patches with [value < 11 and not any? turtles-here]
let target pot-target with [count neighbors with [any? turtles-here with [value < 11]] >= 1]
if target = 0 [print (word "no patch")]
if (target != 0 and (status != "resident")) [move-to min-one-of target [value]
set status "resident"
set color blue]
]
Here is the complete code
breed [migrants migrant]
breed [residents resident]
patches-own [value]
turtles-own [income
status]
to setup
ca
let total problo + probmid + probhi
if (total != 100)
[print (word "prob is more than 100")]
ask patches [set value random-normal 10 3
let patch-value value
set pcolor scale-color (gray - 5) patch-value 10 3]
ask patches
[if random 100 < 3
[sprout-residents 1
[set color red
set shape "default"
set size 1
set status "resident"
]
]
]
end
to go
ask patches
[if random 100 < 1
[sprout-migrants 1
[set color green
set shape "default"
set size 1
set status "migrant"
set-move
]]]
end
to set-move
ask migrants
[let pot-target patches with [value < 11 and not any? turtles-here]
let target pot-target with [count neighbors with [any? turtles-here with [value < 11]] >= 1]
if target = 0 [print (word "no patch")]
if (target != 0 and (status != "resident")) [move-to min-one-of target [value]
set status "resident"
set color blue]
]
end

You're mixing up an agentset and the count of the agents in that agentset. This line:
let target pot-target with [count neighbors with [any? turtles-here with [value < 11]] >= 1]
returns an agentset. So your variable "target" is all the patches that meet your conditions. If there are no patches that meet your conditions, then the agentset is not 0, but the count of the agentset is.
So you need to replace if target = 0 [print (word "no patch")] with if count target = 0 [print (word "no patch")] or with if not any? [print (word "no patch")].

Related

Netlogo: agentset of patches to single agent

I have a list of turtles (carriers) that i'm trying to narrow down in my go method.
Here is my program:
globals [
metal-sheets
cut-sheets
standard-skeleton
finished-standard-skeleton
prestige-skeleton
finished-prestige-skeleton
]
breed[carriers carrier]
turtles-own [
on-job?
]
patches-own [
processing-time
machine-type ;;cutter, standard-welder, prestige-welder, riveter
status ;;import, export, pending
]
to setup
clear-all
set-default-shape carriers "circle"
create-carriers number-of-carriers ;;number-of-carriers is a slider
[set color grey
set on-job? false
setxy random-xcor random-ycor]
setup-patches
reset-ticks
end
to setup-patches
ask patches [
if pxcor = 1 and pycor = 1 [set machine-type "cutter"]
if pxcor = 1 and pycor = 5 [set machine-type "standard-welder"]
if pxcor = 5 and pycor = 1 [set machine-type "prestige-welder"]
if pxcor = 5 and pycor = 5 [set machine-type "riveter"]
if machine-type = "cutter"
[set pcolor red
set status "import"]
if machine-type = "standard-welder"
[set pcolor green
set status "import"]
if machine-type = "prestige-welder"
[set pcolor blue
set status "import"]
if machine-type = "riveter"
[set pcolor yellow
set status "import"]
]
end
to Go
let cutter patches with [machine-type = "cutter"]
let standard-welder patches with [machine-type = "standard-welder"]
let prestige-welder patches with [machine-type = "prestige-welder"]
let riveter patches with [machine-type = "riveter"]
let free-carriers carriers with [on-job? = false]
let closest-carrier min-one-of free-carriers [distance cutter] ;;Distance expects agent, got agentset
ask closest-carrier [
set color green
]
end
I'm getting an error on the line let closest-carrier min-one-of free-carriers [distance cutter] saying that distance expected a agent but got a agentset although there only is one agent in the set.
The full error message is:
DISTANCE expected input to be an agent but got the agentset (agentset, 1 patch) instead.
How do narrow down the patches to one patch?
It doesn't matter if there happens to be only one agent in the agentset, it is still an agentset. Put a one-of in front, which selects one agent from the agentset and therefore changes the way the code interprets the code

Move turtle to a patch with some neighbors of same type of turtle and stay there

I tried to move a turtle to a patch where there 2 turtles with the same type (e.g income) as its neighbor and stay there. I did the following code
to set-move
let target []
ask turtles with [income = "low"]
[ let potential-target1 patches with [value < buymiddle and any? turtles-here = false]
set target potential-target1 with [length remove-duplicates [any? turtles-here with [income = "low"]] of neighbors = 2]
set target min-one-of potential-target1 [value]
if target != nobody and any? turtles-on neighbors
[ move-to target ask patch-here [set empty false]]]
but it seems did not work. Some turtles still move around after choosing a patch. Some turtles do not choose a patch where there two neighbors of its group.
How to specify a patch with two neighbors of certain groups of turtles?
breed [agens agen]
patches-own [value
empty]
turtles-own [income
myHouses
]
to setup
ca
;;Check inputs
let total-prob prob-low + prob-mid + prob-high
if (total-prob != 100 )
[
print (word "Adoption types must sum to 100, but instead sum to " total-prob)
stop
]
ask patches [set value random-normal 10 3]
ask patches [ifelse (value < 8)[ set pcolor green ]
[ifelse (value < 11)[ set pcolor blue]
[if value < 15[ set pcolor gray]]]]
end
to go
ask patches [
if random 100 < 3 [sprout-agens 1 [set color red
set shape "default"
set size 1
set-income
set-move]]]
end
to set-move
let target []
ask turtles with [income = "low"]
[ let potential-target1 patches with [value < buymiddle and any? turtles-here = false]
set target potential-target1 with [length remove-duplicates [any? turtles-here with [income = "low"]] of neighbors = 2]
set target min-one-of potential-target1 [value]
if target != nobody and any? turtles-on neighbors
[ move-to target ask patch-here [set empty false]]]
ask turtles with [income = "middle"]
[ let potential-target2 patches with [(value > buymiddle and value < buyhigh) and any? turtles-here = false]
let target2 potential-target2 with [length remove-duplicates [any? turtles-here with [income = "middle"]] of neighbors = 2]
set target2 min-one-of potential-target2 [value]
if target2 != nobody and any? turtles-on neighbors
[ move-to target2 ask patch-here [set empty false]]]
ask turtles with [income = "high"]
[ let potential-target3 patches with [(value > buyhigh) and any? turtles-here = false]
let target3 potential-target3 with [length remove-duplicates [any? turtles-here with [income = "high"]] of neighbors = 2]
set target3 min-one-of potential-target3 [value]
if target3 != nobody and any? turtles-on neighbors
[ move-to target ask patch-here [set empty false]]]
end
to set-income
let kind-prob (random 100)
let cumulative-prob prob-low
ifelse (kind-prob < cumulative-prob)[set income "low" set color red]
[set cumulative-prob cumulative-prob + prob-mid
ifelse (kind-prob < cumulative-prob)[set income "middle" set color pink ]
[set cumulative-prob cumulative-prob + prob-high
if income < cumulative-prob [set income "high" set color blue]
]]
end
Let's look at the first line in the ask block of your first code segment.
let potential-target1 patches with [value < buymiddle and any? turtles-here = false]
is the same as
let potential-target1 patches with [value < buymiddle and not any? turtles-here]
so that your potential-target1 patchset will have no turtles. That will make the subsequent lines irrelevant. But lets say that we make that line
let potential-target1 patches with [value < buymiddle and any? turtles-here]
In next line,
set target potential-target1 with [length remove-duplicates [any? turtles-here with [income = "low"]] of neighbors = 2]
[any? turtles-here with [income = "low"]] of neighbors yields a list of eight true/false values, true if a neighboring patch has any turtles with income = low, and false if it doesn't. Then you reduce duplicates in that list, and end up with either a single [true] (if all are true), a single [false] (if all are false), or a true and a false [true false] or [false true] if some are true and some false. You then look at the number if entries in that reduced list and compare it to 2. That will occur when at least one neighbor has such turtles and at least one does not. I suspect that is not what you want. If you want exactly two neighboring patches to have at least one turtle with income = low, then something like
count neighbors with [any? turtles-here with [income = low]] = 2
should do that. If on the other hand you want neighbors with exactly two turtles with income = low, then you would want
neighbors with [count turtles-here with [income = low] = 2]
It's not clear to me which you are after.
After seeing the question below, I gather that Dudi is looking for the first interpretation. If so, then finding among all the candidates the patch with the lowest value would be (as they had done in their original code)
let potential-targets patches with [count neighbors with [any? turtles-here with [income = low]] = 2]
let target min-one-of potential-targets [value]

There are still some patches that turtle can move on to but ERROR

I ask a turtle A to move to patch that has a neighbor that has the same type of turtle with the turtle A. It is working well until the ERROR (MOVE-TO expected input to be an agent but got NOBODY instead) comes out. Visually there are still some available patches. How to code so that all available patches are occupied and report or stop the program when there is no more patch to occupy? Any comments will be really helpful. I did the following:
to set-move
ask migrants
[let pot-target patches with [value < 11 and not any? turtles-here]
let target pot-target with [count neighbors with [any? turtles-here with [value < 11]] = 1]
ifelse target != 0 and (status != "resident") [move-to min-one-of target [value]
set status "resident"
set color blue]
[]
]
end
This is the full code
breed [migrants migrant]
breed [residents resident]
patches-own [value]
turtles-own [income
status]
to setup
ca
let total problo + probmid + probhi
if (total != 100)
[print (word "prob is more than 100")]
ask patches [set value random-normal 10 3
let patch-value value
set pcolor scale-color (gray - 5) patch-value 10 3]
ask patches
[if random 100 < 3
[sprout-residents 1
[set color red
set shape "default"
set size 1
set status "resident"
]
]
]
end
to go
ask patches
[if random 100 < 1
[sprout-migrants 1
[set color green
set shape "default"
set size 1
set status "migrant"
set-move
]]]
end
to set-move
ask migrants
[let pot-target patches with [value < 11 and not any? turtles-here]
let target pot-target with [count neighbors with [any? turtles-here with [value < 11]] = 1]
ifelse target != 0 and (status != "resident") [move-to min-one-of target [value]
set status "resident"
set color blue]
[]
]
end
This line: let target pot-target with [count neighbors with [any? turtles-here with [value < 11]] = 1] identifies the patches where there is exactly 1 neighbour meeting those conditions. So a patch with 2 such neighbours is would not be available. From your description I think you really want >= instead of =:
let target pot-target with [count neighbors with [any? turtles-here with [value < 11]] >= 1]

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.

Changing patch colors except one color

I'm creating a program in Netlogo which has shoppers (turtles) moving through a grocery store layout. When they step on a patch it increases in color and when it has no agent on it, it decreases in color, as this will show the paths shoppers take through a store.
My code is:
ask turtles
[ rt random 360
fd 1
set pcolor pcolor + 1 ]
ask patches with [ (pcolor > 9.9) or (pcolor < 0.1) ]
[set pcolor 0]
ask patches with [ (count turtles-here = 0) and (pcolor <= 9.9) and (pcolor > 0) ]
[ set pcolor pcolor - 0.1 ]
However, as the aisle patches are blue this is turning them back to black as well. I was wondering what code I could use so patches with pcolor = 105 will stay blue and not change to black?
Don't change the color of the patches with pcolor = 105. You'll just need to add an additional condition to anywhere you modify the patch color.
ask turtles
[ rt random 360
fd 1
if pcolor != 105[set pcolor pcolor + 1 ]
]
ask patches with [ pcolor != 105 and ((pcolor > 9.9) or (pcolor < 0.1))]
[set pcolor 0]
ask patches with [pcolor != 105 and (count turtles-here = 0) and (pcolor <= 9.9) and (pcolor > 0) ]
[ set pcolor pcolor - 0.1 ]