Netlogo : inequality doesn't work properly under foreach - list

It supposes to be a simple code, but I don't know why it doesn't work properly.
I want to change a color of non-white turtle back into white if a condition is fulfilled. I put inequality as the condition.
for example, if the amount of red turtle > = 5, then [ do something ].
No error message for the code, but I found that [ do something ] codes are executed before the condition is fulfilled. For example, it is executed when the amount of turtle is 1 or 4. And I also found that there are moments when it reach > = 5, [ do something] code is not executed.
Below is the code
to seize-value
ask consumers [set type-of-value ( list blue red green) ]
foreach type-of-value [
if count consumers with [color = ?] > = 5 [
let z consumers with [color = ?]
ask z [ set color white ]
ask consumers with [color = white] [set value? false]
ask one-of cocreation-patches [ sprout 1 [gen-prevalue]]
]]
end
I've tried using a single color, instead of a list of color (without - foreach) it doesn't work either.
Can anyone help with this?
Thank you

You have something like the following at the top of your code to set up type-of-value as an agent variable:
breed [ consumers consumer ]
consumers-own [ type-of-value ]
However, you are treating it as a global variable in your code. First you say ask consumers [set type-of-value ( list blue red green) ] to set the AGENT variable called type-of-value to the list of colours. But you end that ask [] statement before starting the foreach.
Unless the consumers have different lists of colours, what you really want is something more like this (untested). Note that I have also removed your multiple creations of the same agentset (for efficiency):
globals [ type-of-value ]
to setup
clear-all
...
set type-of-value ( list blue red green)
...
reset-ticks
end
to seize-value
*type "seize-value on tick " print ticks
foreach type-of-value
[ let changers consumers with [color = ?]
*print ?
*print count changers
if count changers >= 5
[ ask changers
[ set color white
set value? false
]
ask one-of cocreation-patches [ sprout 1 [gen-prevalue] ]
]
]
end
UPDATE for debugging I have added three lines that will output key information for debugging. They are marked with an asterisk (*). Add those lines (without the *) and look at the output.

Related

Let agents follow its neighbour but got the error "FACE expected input to be an agent but got NOBODY instead."

I try to move each agents to its related agents (defined by high trust connection and in my view) if there are any such agents, and else move the agent to one of its neighbours. However, I get the error "FACE expected input to be an agent but got NOBODY instead." and I don't know how to solve it. I think the use != nobody might cause the error. Any suggestions on how to solve this?
This is my code:
breed [ persons a-person ]
undirected-link-breed [ connections connection ]
connections-own [ trust ]
persons-own [ neighbours ]
to setup
clear-all
create-persons 10
[ setxy random-xcor random-ycor ]
setup-connections
reset-ticks
end
to setup-connections
ask persons
[
create-connections-with other persons
[ set trust 0.6 ]
]
end
to go
setNeighbours
movePersons
tick
end
to setNeighbours
ask persons [ set neighbours other persons in-cone 4 360 ]
end
to movePersons
ask persons
[
let highlyRelatedPersons (turtle-set [other-end] of my-out-connections with [trust = 0.6]) in-cone 4 360
let relatedPersons (turtle-set [other-end] of my-out-connections with [trust = 0.6])
ifelse any? highlyRelatedPersons
[
face one-of highlyRelatedPersons
]
[
let weaklyRelatedNeighbour one-of neighbours with [not member? self highlyRelatedPersons] ;select one of my neighbours that is not a highlyRelatedPerson
ifelse weaklyRelatedNeighbour != nobody
[
face weaklyRelatedNeighbour
]
[
face one-of relatedPersons
]
]
]
end
You are correct in what is causing the error
highlyRelatedPersons is an agentset and while an agentset can be empty, an agentset can never be nobody. one-of highlyRelatedPersons however, will be nobody if the agentset is empty, so you could use ifelse (one-of highlyRelatedPersons != nobody).
That said, is easier to just check if the agentset is empty by using any?:
ifelse any? highlyRelatedPersons
Your code also never actually creates any links for highlyRelatedPersons and relatedPersons is always empty. This means that the code will always return false on the first ifelse and move on to the second. Generally most turtles will have neighbours they can face, but sometimes there are none so they try to face one-of relatedPersons, which again causes a crash since relatedPersons is an empty agentset.

Netlogo: How can I add some conditions by using the with, if statement or else?

I would like to count the number of turtles stopped on the road, and I want to take that X coordinate information and let it be the queue length. The following is the sample program.
ask turtles with [ not right-end ] ;a flag "right-end" to the red turtle for differentiation to the other blue turtles
[
ask turtles with [ speed = 0 ] ;the speed is 0 means stopped
[
set top max-one-of turtles [who] ;get a turtle with biggest id
set topx [xcor] of top
set L count turtles with [xcor > topx] ; L is the queue length of Little's Law
]
]
I am having trouble understanding exactly what you want to do, but I think it is something like this:
to-report countRightmost ;global context
let ts (turtles with [speed = 0 and not right-end] )
let top max-one-of turtles [who]
let topx [xcor] of top
report count ts with [xcor > topx]
end

How to add 'priorities' to the primite 'n-of' in NetLogo?

I have patches with 3 colors (yellow, green, and red). The green ones have a 'rank' value. I would like to ask a given number ('n-cells') of either yellow or green patches ('candidate-cells') to turn red. I am aware I can do that randomly using the primitive 'n-of', like this:
let candidate-cells ( patches with [ pcolor = yellow or pcolor = green ] )
ask n-of n-cells candidate-cells [ set pcolor red ]
But I would like add priorities to the patches that will be turned red. First, I would like yellow patches to turn red (randomly) but if there are still patches to be turned red after all patches yellow have, I would like green patches with highest 'rank' value to turn red until the number of turned patches reaches the 'n-cells' number. I think this piece of code should work till up its last line:
let candidate-yellow-cells ( pcolor = yellow )
let candidate-green-cells ( pcolor = green )
ask n-of n-cells candidate-yellow-cells [ set pcolor red ]
if n-cells > candidate-yellow-cells [
let left-cells ( n-cells - candidate-yellow-cells )
ask n-of left-cells candidate-green-cells [ set pcolor red ]
But still, I am using 'n-of' again for the green cells, I wonder how could I replace that by something that would pick the 'left-cells' as the green patches with highest 'rank' value. Thank you in advance.
This example should get you there:
globals [n-cells]
patches-own [rank]
to setup
set n-cells 500
ask patches [
set pcolor one-of [yellow green red]
set rank random 3
]
end
to recolor
let _yellows (patches with [pcolor = yellow])
let _ny count _yellows
ifelse (n-cells > _ny) [
ask _yellows [set pcolor red]
let _greens sort-on [(- rank)] (patches with [pcolor = green])
let _ng length _greens
let _n min (list (n-cells - _ny) _ng)
ask patch-set sublist _greens 0 _n [set pcolor red]
][
ask n-of n-cells _yellows [
set pcolor red
]
]
end

Error using "n-of" in NetLogo to select specific patches

I am new to NetLogo and I am working on a deforestation model, where farmers are my agents. They have a ID variable (lotid-farmer) that matches a ID in the patches (lotid-patch) that they own. Basically, farmers check how much money and labor they have to deforest some forest patches or abandon some of their agricultural patches (pcolor = red) in their farms. By the end of the latter procedure, farmers have a "n-aband" value calculated, which is the number of patched they will abandon (randomly) within their farms (pcolor = yellow). This is the piece of code that was supposed to do that:
ask farmers [
...
if pcolor = red and lotid-patch = [ lotid-farmer ] of self [ ; Asks the farmer to randomly convert a # of the agricultural patches without maintenance to regrowth...
ask n-of n-aband patches [ set pcolor yellow ] ; ... among all agricultural patches own by the farmer
]
...
However, when I run the code, farmers start "abandoning" patches that they do not own. I think that is because I am not setting up a proper "restriction" when I use "ask n-of n-aband patches" but I thought that that should be implicit in the "if" statement I have in the line above, no? I have also tried:
ask n-of n-aband patches with [ pcolor = red and lotid-patch = [ lotid-farmer ] of self ] [ set pcolor yellow ]
But I run into a error:
A patch can't access a turtle variable without specifying which turtle.
error while patch 390 414 running OF
called by procedure CALCULATE-DEFORESTATION
called by procedure GO
called by Button 'Go'
Any suggestions on how to get this piece working? Thank you in advance.
To do this, you need to consider only patches owned by the farmer.
ask farmers [
let _id lotid-farmer
let _candidates (patches with [lotid-patch = _id and pcolor = red])
let _n-aband min (list n-aband count _candidates)
ask n-of _n-aband _candidates [set pcolor yellow]
]
But ... don't work with ids. Work with agents. Let each patch have an owner,
which is a farmer or nobody. Let each farmer maintain a list (or agentset)
of patches that it owns.

netlogo comparing turtle variables

I'm writing a program which groups turtles into different groups.
I am trying to write a command where if there is a turtle in a different group within a 1 until radius of the turtle the command runs.
This is what I have
to confront
ask turtles
[if [ group ] of turtles in-cone 1 180 != group
[set color brown]]
end
However the command is coming out true even when there is not a turtle in a different group nearby.
may be something like :
to confront
ask turtles
if any? turtles in radius 2 [
if any? turtles in radius 2 with [group != [group] of myself][
set color brown
]
]
end
I don't know if it can work directly (I haven't test this code) but I think it's a way