Reputation: 67
New NetLogo User and first-time poster here, with some cannibalistic turtles on my hands.
About my model:
My turtles have a bodysize (bsize), and a breed (male, female, juvenile turtles). They move around in a random fashion and encounter each other on patches. When two turtles land on the same patch, my little beasts size each other up, and depending on a probability of cannibalism (PrCan) specific to the larger turtle's breed and the body size ratio (bsize_ratio) between the two, the bigger one eats the smaller one.
I don't think this is relevant, but I have created a table (PrCanTable) of 3 lists with two keys (body size ratio, breed, and probability of cannibalism) using table:make from instructions I found on this stack overflow answer.
To continue, the bigger turtle looks up the probability of cannibalizing (PrCanT) in the table (PrCanTable), then picks a random number (random-float) and compares it to the probability (PrCanT). If the random number is less than or equal to the probability, the little turtle dies. So sad!
Unfortunately, my bloodthirsty turtles are misbehaving. I am running into a problem:
There is no agent for MYSELF to refer to. error while fa 25 running MYSELF called by procedure CANNIBALIZE called by procedure GO called by Button 'go'
NetLogo has helpfully highlighted the last instance of myself in my code...but I don't know why. I think this is a problem with my own understanding of myself vs. self. I have read as much as I can, but honestly am still stumped. Can anyone take a look at this code and let me know?
to-report get-PrCan_T [ bsize_ratio_T breed_T ]
report table:get (table:get PrCanTable bsize_ratio_T) breed_T
end
to cannibalize
if ( any? turtles-here with [bsize > [bsize] of myself])
and ( random-float 1 <= get-PrCan_T ( precision( bsize / bsize of myself ) 1 ) ( [breed] of self ) )
[die]
end
Upvotes: 3
Views: 539
Reputation: 14972
Yeah, self
and myself
are confusing at first, but once you get the hang of it, it's really not that hard. What you need to understand is that every piece of NetLogo code runs into a "context". That context, by default, is the observer, but some primitives can introduce a new context.
ask
is the most obvious way to introduce a new context: the command block that you pass to ask
(delimited by [
and ]
) puts NetLogo in the context of a turtle. Inside that context, self
refers to the current turtle.
But sometimes you introduce a new turtle context inside an existing turtle context! Inside that new context, self
changes meaning: it now refers to the turtle from the inner context. But what if you still want to refer to the turtle from the outer context? That's what myself
is for.
Assuming that cannibalize
is a procedure that is run by a turtle, your use of myself
in turtles-here with [bsize > [bsize] of myself]
is correct: the turtle running the with
block is self
(which you don't need to specify) and turtle running cannibalize
(the "outer" turtle) is myself
. The inner context was introduced by with
.
But in the second part of your if
condition (everything that follow and
) there is no inner context anymore: you're not inside the with
block anymore. So myself
is not defined anymore. There is only self
.
Your code is also made harder to debug by the fact that you're trying to pack everything in the same long if
condition. Try splitting it up by using multiple local variables:
to cannibalize
let bigger-turtles-here turtles-here with [ bsize > [ bsize ] of myself ]
if any? bigger-turtles-here [
let cannibal one-of bigger-turtles-here
let ratio precision ([ bsize ] of cannibal / bsize) 1
let p get-PrCan_T ratio breed
if random-float 1 <= p [ die ]
]
end
One final note: in both your version and mine, the turtle running the cannibalize
procedure is the one that gets eaten! That's confusing. I would either rename the procedure to get-cannibalized
or switch things around so that the turtle running the procedure is the one that does the eating. (Naming is important!)
Upvotes: 2