I'm new to NetLogo and I'm trying to create 2 sub-breeds (denoted by different shapes) within each breed for 2 breeds total (i.e. sharks and fishes). The chunks of code work as expected when ran individually, however, when running both chunks the first sub-breed of the fishes does not seem to initialise in the interface tab. For some reason the initialisation of the shark breed seems to interfere with the initiation of the fishes breed.
Any idea what i'm doing wrong? Code below.
; Create the agents
breed [sharks shark]
breed [fishes fish]
; Create the agents' variables
fishes-own
[
x0
y0
]
globals
[
species
species-f
]
to setup
; Always start with this
clear-all
reset-ticks
; Create sharks and species
create-sharks N-sharks ; N-sharks is a slider
[
set color blue
setxy random-xcor random-ycor
set species N-sharks
ask sharks
[
set shape "default"
set size 2.5
]
ask sharks with [who >= (species * (1 / 2))]
[
set shape "square"
set size 2
]
ask sharks with [who < (species * (1 / 6))]
[
set shape "star"
set size 3
]
] ; End create sharks and species
; Create fishes
create-fishes N-fishes
[
setxy random-xcor random-ycor
set x0 xcor
set y0 ycor
set species-f (N-fishes * species-ratio)
ifelse who <= species-f
[
set shape "sheep"
set size 5
]
[
set shape "cow"
set size 3
]
set color white
] ; End create fishes
end
There seem to be a number of misunderstandings about what code is run when by NetLogo, and what some pieces of code do: when you use create-turtles *number* [*commands*]
(or with breeds, as in your case), commands is run once by every turtle being created (first the new turtles are created, then they run the commands in turn).
That means that every time you use ask sharks
within the create-sharks
' command block, every new shark will ask all other sharks to set shape and size. For example, if you create 100 sharks, instead of setting the shape and size only once you are doing it 10,000 times (100 * 100).
So you need to put all those commands out of their respective create-<breed>
's command blocks; for example:
create-sharks N-sharks [
set color blue
setxy random-xcor random-ycor
]
ask sharks [
set size 2.5
]
ask sharks with [who >= (species * (1 / 2))] [
set shape "square"
set size 2
]
ask sharks with [who < (species * (1 / 6))] [
set shape "star"
set size 3
]
This is still improvable code, but it shows how to achieve exactly the same thing by doing it once and not doing it N-sharks ^ 2
times.
A better way to do it is to bring those commands back inside the create-<breed>
's command block, but letting each agent carry out the task for itself only. That is, without using ask sharks
but using ifelse
, so that each shark will check its own condition:
create-sharks N-sharks [
set color blue
setxy random-xcor random-ycor
(ifelse
who >= (species * (1 / 2)) ; the first condition
[set shape "square" set size 2]
who < (species * (1 / 6)) ; the second condition
[set shape "star" set size 3]
; else
[set size 2.5])
]
All of this applies to the other breed too.
It is generally said that using who
is a sign that the code should be improved, but let's not focus on this now.
You will have noticed that I omitted the part where you set species N-sharks
. This is because I think there is another misunderstanding here and it is not clear to me what you wanted to do: species
(such as species-f
for the other breed) is a global variable. You are basically asking each of the 100 sharks (again, 100 for example) to do the same thing: set the value of a global variable to equal the value of another global variable. In this case, you are asking each shark to set species 100
. This seems very unnecessary, especially considering that N-sharks
is a slider used for setup and thus probably won't be changed during the simulation (which means that there is probably no need to store the current value of N-sharks
as a separate global variable).
Why are you basing the repartition of your sub-breeds on the value of species
? What do you want species
to represent? Is it correct for it to be a separate variable from N-sharks
? If yes, then it is not clear what is its point; if no, then it can be eliminated.
You need to make sure that whatever you wanted to do with N-sharks
& species
, and with N-fishes
and species-f
, is better reflected in your code.
Also because I think this is the reason why your first fish sub-breed isn't showing. First of all, what is species-ratio
? It is not present in your example, but it seems to be relevant for your question. In any case, if your first fish sub-breed isn't showing, it means that there is no fish
who satisfies the condition who <= species-f
.
This doesn't surprise me. who
numbers are progressive for turtles: if you create 15 sharks and later you create 10 fish...
who = 0
who = 14
who = 15
who = 24
As you can see in this example, there is no fish for which who <= N-fishes
(where N-fishes = 10
). Let alone that in your case you set species-f (N-fishes * species-ratio)
and, although you didn't tell what species-ratio
is, I imagine it is a value between 0 and 1 - thus making the value of species-f
even smaller.