Problems with NetLogo agents movimentation - simulation

I'm actually developing a simulation to study social phenomena.
My idea is a population of agents choosing the closer factory of them, walking forwards it and (when they reach it) go back to their initial position.
However, I'm having some trouble to program it. Some of the agents just pass by their initial position and reach the borders of my simulation, stopping there.
Here is my code:
breed [population person] ;create the population
breed [all-fac factory] ;create the factories
população-own [
myneighbor ;defines which factory is closer
myNND ;calculate the distance between the person and the closer factory
home-x ;initial x position
home-y ;initial y position
]
to setup
clear-all
reset-ticks
create-population 83 ; creates the population with 83 people in it
[
setxy random-xcor random-ycor ; set people initial position randomly
set shape "person"
set home-x xcor
set home-y ycor
]
create-all-fac 9
[
ask all-fac [ set color white]
ask facture 83 [ setxy 0 0 ] ; defines the initial position of every factory
ask facture 84 [ setxy 70 0]
ask facture 85 [ setxy -70 0 ]
ask facture 86 [ setxy 70 70 ]
ask facture 87 [ setxy 0 70 ]
ask facture 88 [ setxy -70 70 ]
ask facture 89 [ setxy 70 -70 ]
ask facture 90 [ setxy 0 -70 ]
ask facture 91 [ setxy -70 -70 ]
set shape "house"
]
end
to go
move
tick
choose-facture
end
to choose-facture
ask population [
set myneighbor min-one-of other fábricas [distance myself] ; choose my nearest neighbor based on distance
set myNND distance myneighbor
]
end
to move
ask population [
if xcor = home-x and ycor = home-y [
face myneighbor
fd 1
]
if any? all-fac in-radius 5 [
facexy home-x home-y
fd 1 ]
fd 1
]
end
If someone could help me with that I would be really thankful :) .

Arthur!
Your code was almost right!
I changed the names for consistency, to fix some typos.
I rearranged the commands in the go step so that they checked their positions before moving, not after. Usually we put "tick" as the last statement in the go procedure.
I manually reset the view to have max-xcor and max-ycor 100, and shut off wrapping, so the factories were within the view, and made the patch size 3 instead of 13, so the view fit on my laptop small screen.
Finally, I changed the test of whether someone was home to whether they were within a distance of 5 of home, not whether they were exactly at home -- just the same as the test you use for being at a factory.
With those changes, the code seems to do what you want it to -- the people walk to the factory and then back home, over and over. No one gets stuck on the border of the view.
;; NOTE -- the view has been changed to shut off horizontal and vertical wrapping
;; and max-pxcor = max-pycor = 100
;; and patch-size = 3 pixels, not 13
;; so population and factory size have been increased.
breed [population person] ;create the population
breed [all-fac factory] ;create the factories
;;população-own [
population-own [
myneighbor ;defines which factory is closer
myNND ;calculate the distance between the person and the closer factory
home-x ;initial x position
home-y ;initial y position
]
to setup
clear-all
reset-ticks
create-population 83 ; creates the population with 83 people in it
[
setxy random-xcor random-ycor ; set people initial position randomly
set shape "person"
set home-x xcor
set home-y ycor
set size 5
]
create-all-fac 9
[
ask all-fac [ set color white]
ask factory 83 [ setxy 0 0 ] ; defines the initial position of every factory
ask factory 84 [ setxy 70 0]
ask factory 85 [ setxy -70 0 ]
ask factory 86 [ setxy 70 70 ]
ask factory 87 [ setxy 0 70 ]
ask factory 88 [ setxy -70 70 ]
ask factory 89 [ setxy 70 -70 ]
ask factory 90 [ setxy 0 -70 ]
ask factory 91 [ setxy -70 -70 ]
set shape "house"
set size 5
]
end
to go
choose-factory ;; moved this command up from below tick
move
tick
;; choose-factory
end
to choose-factory
ask population [
set myneighbor min-one-of all-fac [distance myself] ; choose my nearest neighbor based on distance
set myNND distance myneighbor
]
end
to move
ask population [
;; if xcor = home-x and ycor = home-y [ ;;<<<<<<<<<<<<<<<<<<<< replaced this test
if (distancexy home-x home-y) <= 5 [
face myneighbor
fd 1
]
if any? all-fac in-radius 5 [
facexy home-x home-y
fd 1 ]
fd 1
]
end
One last suggestion. The code you wrote is quite "brittle", because if you change the number of people to some smaller number like 5, for testing, there will be no factory #83 to set anywhere and the code will crash.
You may want to have some slider to set the number of people and want your code to keep working for any number of people.
Also, it take a lot of lines to position all the factories. What is a good way to do it that is short, but will not break if you change the number of people?
Here's some code that does that. It makes a list of the factories when it creates them, so it then has a list of the who numbers of the 9 factories it just created.
Then, it finds those on the list and uses the numbers to position the factories.
It works. Here is the modified section of code:
let factory-list [] ;; make an empty list
create-all-fac 9
[
set shape "house"
set color white
set size 5
set factory-list fput who factory-list ; add this factory to the growing list
]
;; OK, now we have a list of all 9 factories.
;; Confirm that by printing it
print "here is the list of who-numbers of the new factories:"
show factory-list
;; now we need to insert those numbers into the following commands:
ask factory item 0 factory-list [ setxy 0 0 ] ; defines the initial position of every factory
ask factory item 1 factory-list [ setxy 70 0]
ask factory item 2 factory-list [ setxy -70 0 ]
ask factory item 3 factory-list [ setxy 70 70 ]
ask factory item 4 factory-list [ setxy 0 70 ]
ask factory item 5 factory-list [ setxy -70 70 ]
ask factory item 6 factory-list [ setxy 70 -70 ]
ask factory item 7 factory-list [ setxy 0 -70 ]
ask factory item 8 factory-list [ setxy -70 -70 ]

Related

Netlogo: Patches Disappear instantly instead of continualy

I'm trying to show deforestation versus reforestation. To do this I created a slider to show how much reforestarion and deforestation is being done. However every time at 11 ticks the whole scene gets deforestated and I don't know why.
patches-own
[reforestar
deforestar]
breed [ potreros potrero ] ; sheep is its own plural, so we use "a-sheep" as the singular
breed [ bordes borde ]
breed [ bosques bosque ]
to setup
clear-all
set-default-shape turtles "frog top"
ask patches
[ifelse pcolor = 44
[ set reforestar tiempo-sin-reforestar ]
[ set reforestar tiempo-sin-reforestar * 0.5];
]
reset-ticks
end
to go
ask patches [ reforestacion ]
ask patches [ deforestacion ]
tick
end
to reforestacion ; patch procedure
; countdown on brown patches: if you reach 0, grow some grass
if pcolor = 35 [
ifelse reforestar <= 0
[ set pcolor 44
set reforestar tiempo-sin-reforestar ]
[ set reforestar reforestar - 1 ]
]
end
to deforestacion
if pcolor = 44 [
ifelse deforestar >= 10
[ set pcolor 35
set deforestar tasa-deforestacion ]
[ set deforestar deforestar + 1 ]
]
end
The idea is that some patches of random brown (deforestacion) turn into yellow (reforestacion) but for some reason it just changes everything at once.
You're not asking a random number of patches to do something, you're asking all patches with pcolor 44 to count up to 10 with every tick and when they reach 10, they get "deforested".
If you want to ask a random number of patches to get deforested, try something like
ask n-of (random ([count patches with pcolor = 44] * deforestationRate)) patches with pcolor = 44 [set pcolor 35 set deforestar tasa-deforestacion]
Where deforestationRate would be a value from a slider from 0 to 1. What this would do is count the nuber of patches that can be deforested and then select a random number of those patches to deforest. If you only use the count itself, then every tick between 0 and 100% of the forest will get deforested, but if you add the deforestationRate slider value, it may be whatever maximum percentage you'd like. (So if you set it to 0.1 for example, then only up to 10% of the forest can get deforested each tick) You can do the same thing with reforestation too and use a different slider / value for the rate.
(Note: I haven't used NetLogo in a while so the code and parentheses may not be 100% on point, but you get the idea)

Is there a way to create impassable barriers in NetLogo?

I am attempting to code a path-finding behavior wherein agents will locate an optimal patch in the environment and navigate their way around fences to reach said patch. I've created a patch variable 'f', which is set to 1 to indicate fences and 0 for any other patch.
I want to make these fences impassable (i.e. I want them to be patches the agents will not use for movement), but agents still seem to be able to travel on them to some extent and in some cases are even able to fully cross them.
Here is a picture of an agent crossing a barrier I don't want it to cross
Relevant decision-making code for the agents is as follows:
{let moveset patches in-radius 30 with [f = 0 and n > 0]
let target max-one-of moveset [n]
ifelse patch-here != target
[
set heading towards target
]
[]
let chance random-float 10
if chance >= 5 [let pick -145]
if chance < 5 [let pick 145]
ask patches in-radius 1
[if f = 1
[ask myself
[set heading towards min-one-of patches [distance myself] + 180 - random 10 + random 10 ]
]
]
fd 1}
For clarity, 'n' is simply a variable to denote the patch I want my agent to locate and venture to.
Is anyone aware of a simple way in NetLogo to exclude certain patches as viable zones for movement in the decision making process (i.e. hard barriers)?
If you haven't yet, have a look at the "Look Ahead" example in the Models Library- it's a simple demonstration of using patch color to control turtle movement. Some code based on that model is below. With this setup:
breed [ seekers seeker ]
breed [ goals goal ]
patches-own [ steps-from-goal ]
to setup
ca
ask patches [
set steps-from-goal 999
]
ask patches with [ pxcor mod 10 = 0 ] [
set pcolor red
]
ask patches with [ pycor mod 10 = 0 ] [
set pcolor black
]
ask one-of patches with [ pcolor = black ] [
sprout-seekers 1 [
set color blue
pd
]
]
ask one-of patches with [ pcolor = black ] [
sprout-goals 1 [
set color white
set shape "circle"
]
]
reset-ticks
end
You can have the seekers breed wander around the black squares until they share a patch with a goal turtle:
to random-wander
ask seekers [
if any? goals-here [
stop
]
rt random 61 - 30
ifelse can-move? 1 and [pcolor] of patch-ahead 1 = black [
fd 1
] [
rt one-of [ 90 -90 ]
]
]
tick
end
However, note that turtles can still 'jump' corners of patches using this method, because they are able to assess the patch-ahead 1 at any angle- so, a patch one space ahead of a turtle may be assessed across the corner of another patch. The turtle should never actually land on the forbidden patch, but you may notice that their path can cross those blocked patches.
Edit:
See simplified code that "traps" a turtle in a square cage:
to setup
ca
crt 1 [
setxy 5 5
set heading 180
repeat 4 [
repeat 10 [
ask patch-here [ set pcolor red ]
fd 1
]
rt 90
]
die
]
crt 1 [ pd ]
reset-ticks
end
to go
ask turtles [
rt random 61 - 30
ifelse can-move? 1 and [pcolor] of patch-ahead 1 = black [
fd 1
] [
rt one-of [ 90 -90 ]
]
]
tick
end
After 1100 ticks:
After 13300 ticks:

Create a gradient for a turtle swarm

I created a rectangular turtle grid using a total of 1000 turtles.
let in-shape patches with [ pxcor >= -50 and pxcor <= 50 and pycor >= -5 and pycor <= 5 ]
ask in-shape [ sprout 1 ]
Now I need to create a sort of gradient, that will give a sense of distance to my turtle swarm. Given a "seed" with value 0, it emits a message with its value 0 in a certain talk_radius.
The turtles inside this talk_radius compute their distance to the seed. If the distance is less than a fixed value (called gradient_distance) the turtle will assume 1 as gradient_value, emitting a message with its value.
The other turtles do the same. So everyone will take the value x + 1, where x is the lowest value of the turtle within the gradient_distance, as shown in the picture
This is the relative algorithm in pseudo code:
loop
if gradient seed = TRUE then // check if robot is designated as gradient source
gradient value(self) = 0
else
gradient value(self) = GRADIENT MAX
for all neighbors n do
if measured distance(n) < G then // G represents the gradient-distance and GRADIENT MAX is infinity
if gradient value(n) < gradient value(self) then
gradient value(self) = gradient value(n)
gradient value(self) = gradient value(self) + 1
transmit gradient value(self)
And that's my implementation in netlogo:
globals [talk_radius gradient_max gradient_distance]
turtles-own [gradient_seed gradient_value]
to setup
ca
resize-world -60 60 -20 20
crt 1000
let in-shape patches with [ pxcor >= -50 and pxcor <= 50 and pycor >= -5 and pycor <= 5 ]
ask in-shape [ sprout 1 ]
set talk_radius 4
set gradient_max 100000
set gradient_distance 1
ask turtles
[set shape "circle"]
ask turtles-on patch -50 5
[set gradient_seed true]
end
to gradient-formation
while [true]
[
ask turtles
[
ifelse (gradient_seed = true)
[
set gradient_value 0
]
[
set gradient_value gradient_max
set color scale-color green gradient_value 0 120
ask (other turtles) in-radius talk_radius with [distance myself <= gradient_distance] ;; i consider all the turtle in talk_radius having the right gradient_distance
[
let a ([gradient_value] of self) ;; "of self" is not necessary but helped me for a better comprehension
if (a < ([gradient_value] of myself))
[
ask myself [set gradient_value a]
]
]
set gradient_value (gradient_value + 1)
]
set color scale-color green gradient_value 0 120
]
]
end
I used a scale-color in order to have a feedback of what i have done, as you can see in the image.
And now the problem: instead of let a ([gradient_value] of self), i tried set a ([gradient_value] of self) adding a to the turtle variable (I added a in the turtle-own list on top).
I thought the result would have been the same, but instead i got a constantly increasing gradient_value for every turtle as you can see in the image(the color white denotes a very high gradient_value).
Why this difference? Thank you in advance and sorry for the long question.
EDITED EXTENSIVELY in response to discussion that refined the problem
First, I would like to start with a simpler version of the code. I believe this is exactly the same as yours without the while[true]. I removed the extra 1000 turtles you are creating, and separated the ifelse on whether a seed into two separate ask statements, for clarity. I also moved the colouring until after the value calculation is complete.
globals [talk_radius gradient_max gradient_distance]
turtles-own [gradient_seed? gradient_value]
to setup
clear-all
resize-world -60 60 -20 20
let in-shape patches with [ pxcor >= -50 and pxcor <= 50 and pycor >= -5 and pycor <= 5 ]
ask in-shape
[ sprout 1
[ set shape "circle"
set gradient_seed? false
]
]
set talk_radius 4
set gradient_max 100000
set gradient_distance 1
repeat 10 [ gradient-formation ]
end
to gradient-formation
ask turtles-on patch -50 5
[ set gradient_seed? true
set gradient_value 0
]
ask turtles with [not gradient_seed?]
[ set gradient_value gradient_max
ask (other turtles) in-radius talk_radius with [distance myself <= gradient_distance]
[ let my-gradval ([gradient_value] of self)
if my-gradval < [gradient_value] of myself
[ ask myself [set gradient_value my-gradval]
]
]
set gradient_value (gradient_value + 1)
]
ask turtles [set color scale-color green gradient_value 0 120 ]
end
There is a conceptual issue here. Until a turtle has its gradient_value calculated, it is 0. This means a large number of turtles will have a 0 turtle nearby and then have their own gradient_value as 1. It does not produce a colour gradient. To get around this, you need to run the gradient-formation several times. The approach in your code of while [true] introduces an infinite loop. Instead, you can repeat an arbitrary number of times (10 in the code above).
The problem with let versus set + turtles-won is that the set with turtles-own creates 1000 copies of gradient_value - one for each turtle. The let version creates a (temporary) global variable that all turtles access. So when you use set, you are setting it for that turtle, not as a general access number. I think what is happening is that the line set gradient_value my-gradval is accessing the wrong turtle's copy of my-gradval.
But, from the discussion, the purpose of the code that is causing the problem is to find a local minimum. There is a much more direct way of doing that.
to gradient-formation
ask turtles-on patch -50 5
[ set gradient_seed? true
set gradient_value 0
]
ask turtles with [not gradient_seed?]
[ set gradient_value 1 + min [gradient_value] of
other turtles in-radius min (list talk_radius gradient_distance)
]
ask turtles [set color scale-color green gradient_value 0 120 ]
end
ADDED a minimum working example to show the differences.
This is the let (global variable) version
turtles-own [testval]
to testme
clear-all
create-turtles 500
[ setxy random-xcor random-ycor
set color blue
set testval 1 + random 10
]
ask one-of turtles
[ set color red
inspect self
type "testval of asking turtle is " print testval
ask turtles-on neighbors
[ set color yellow
let my-testval [testval] of self ;; creates a temp global variable
type "my-testval is " print my-testval
if my-testval < [testval] of myself
[ ask myself
[ set testval my-testval ;; copies the global variable value
]
]
]
]
end
This is the set (turtle attribute) version
turtles-own [testval my-testval]
to testme
clear-all
create-turtles 500
[ setxy random-xcor random-ycor
set color blue
set testval 1 + random 10
]
ask one-of turtles
[ set color red
inspect self
type "testval of asking turtle is " print testval
ask turtles-on neighbors
[ set color yellow
set my-testval [testval] of self
type "my-testval is " print my-testval
if my-testval < [testval] of myself
[ ask myself
[ set testval my-testval ;; copies value from one attribute to other
]
]
]
]
end

NetLogo: How to make a turtle recognise any shade of one color?

I'm using NetLogo for the first time and need to lay out a simple programme where i have one light source that diffuses light out beyond its source patch and one turtle that will avoid the light.
I can achieve this by using basic 'set pcolor yellow' and then use 'if patch-ahead [pcolor] = yellow [right 45][fd speed]' type command. However this doesn't give me diffused light.
By adapting the HeatBugs code, i can diffuse the color out past the source patch, however the roaming turtle no longer recognises the color as yellow, i think, as it is a scale-color. I tried setting the code to != black but this also doesn't work. I'm assuming it's because the patches are being recolored after each tick.
Is there a way to make the turtle recognise the patches of diffused color so as to avoid them? Or a simpler way to diffuse the light out. (i want a variable intensity so using neighbors and yellow -1 won't do it.)
Here's the code i have so far: (this is a condensed version as i have other things happening in the main body, so i apologise if it isn't clear)
globals [ color-by-unhappiness? ]
turtles-own[
speed
speed-limit
speed-min
ideal-temp ;; The temperature I want to be at
output-heat ;; How much heat I emit per time step
unhappiness ;; The magnitude of the difference between my ideal
;; temperature and the actual current temperature here
]
patches-own[
temp
]
to setup
clear-all
setup-turtles
;;creating diffused light
set color-by-unhappiness? false ;; button
ask n-of number-of-lights patches [
sprout 1 [
set color white
set shape "circle"
set ideal-temp min-ideal-temp + random (max-ideal-temp - min- ideal-temp) ;;these are all sliders
set output-heat min-output-heat + random (max-output-heat - min- output-heat) ;;these are all sliders
set unhappiness abs (ideal-temp - temp) ;;ideal-temp is a button
color-by-ideal-temp
set size 2
]
]
reset-ticks
end
to setup-turtles
create-fears number-of-fears [
set color violet
set shape "circle"
setxy random-xcor random-ycor
set speed 0.1 + random-float 0.9
set speed-limit 1
set speed-min 0.00
]
end
to go
ask turtles [
if speed > speed-limit [set speed speed-limit]
fd speed
ask fears[
if patch-ahead 1 = nobody [rt 135]
if patch-right-and-ahead 45 1 != nobody and [pcolor] of patch-right-and-ahead 45 1 != black[left 45]
if patch-left-and-ahead 45 1 != nobody and [pcolor] of patch-left-and-ahead 45 1 != black[right 45]
ifelse [pcolor] of patch-here = yellow [set speed speed-min][fd speed]
]
if not any? turtles [ stop ]
;; diffuse heat through world
diffuse temp diffusion-rate
ask patches [ set temp temp * (1 - evaporation-rate) ]
ask turtles [ set temp temp + output-heat ask bugs [bug-move patch-here]]
recolor-turtles
recolor-patches
tick
end
to recolor-patches
ask patches [ set pcolor scale-color yellow temp 0 150 ]
]
end
I can't use your code as-is; check out the MCVE guidelines for some tips on reducing your code to just the necessary parts.
Color in Netlogo can given as a string, but it's also just a range of numbers. If you look at Tools > Color Swatches, you will see that the range of "Yellow" colors corresponds roughly to 40 ~ 50. So if you want to, you can just have them evaluate patch color using a numerical range rather than the color name. So, using this unnecessarily complicated example setup:
patches-own [ light? temp]
to setup
ca
ask patches [
set light? false
]
ask n-of 5 patches [
set light? true
set temp 150
]
recolor-patches
crt 10 [
move-to one-of patches with [ not ( pcolor > 40 and pcolor < 49 ) ]
]
reset-ticks
end
to recolor-patches
ask n-of 3 patches with [ light? ] [
if temp < 20 [
set temp temp + random 20
]
]
repeat 5 [
diffuse temp 0.1
]
ask patches [
ifelse temp > 0.25 [
set temp temp - 0.005
] [
set temp 0
]
set pcolor scale-color yellow temp 0 15
]
end
You can ask your turtles to move and just avoid patches that fall in that numerical range:
to go
recolor-patches
ask turtles [
ifelse [pcolor] of patch-ahead 1 > 40 and [pcolor] of patch-ahead 1 < 49 [
let target min-one-of neighbors [pcolor]
if target != nobody [
face target
fd 1
]
] [
rt random 60 - 30
fd 1
]
]
tick
end
EDIT
As Seth Tisue pointed out, the shade-of? primitive can accomplish what the greater than / less than logical statement does:
to go
recolor-patches
ask turtles [
ifelse shade-of? ( [pcolor] of patch-ahead 1 ) yellow [
let target min-one-of neighbors [pcolor]
if target != nobody [
face target
fd 1
]
] [
rt random 60 - 30
fd 1
]
]
tick
end
However, this does require a slight modification to the recolor-patches procedure, as scale-color sets the base color to 40 (in the case of 'yellow'); just ask patches with that pcolor to set their color to black (0) so that movement works as expected here:
to recolor-patches
ask n-of 3 patches with [ light? ] [
if temp < 20 [
set temp temp + random 20
]
]
repeat 5 [
diffuse temp 0.1
]
ask patches [
ifelse temp > 0.25 [
set temp temp - 0.005
] [
set temp 0
]
set pcolor scale-color yellow temp 0 15
if pcolor = 40 [
set pcolor black
]
]
end

Development of turtles from one breed to another

I dont know much about netlogo so this may be a really simple solution but I have multiple breeds of turtles where each breed is a different age range (eggs, hatchlings, juveniles, hawksbills (adults)) and i need them to be able to go from one breed to the next after a certain amount of ticks (in my model one tick = one day). Is this possible to code for?
Here's my code so far
globals [island]
Breed [eggs egg]
Breed [hatchlings hatchling]
Breed [juveniles juvenile]
Breed [hawksbills hawksbill]
turtles-own [
age
z
]
to setup
clear-all
set-default-shape eggs "circle"
create-eggs 80
[ set color 49.5
set size 0.5
setxy random-xcor random-ycor ]
set-default-shape hatchlings "turtle"
create-hatchlings 70
[ set color 57
set size 1.5
setxy random-xcor random-ycor ]
set-default-shape juveniles "turtle"
create-juveniles 10
[ set color 55
set size 2
setxy random-xcor random-ycor ]
set-default-shape hawksbills "turtle"
create-hawksbills 9
[ set color 53
set size 3
setxy random-xcor random-ycor ]
clear-output
setup-environment
setup-birthdays
reset-ticks
end
to setup-environment
ask patches [set pcolor cyan]
ask patches with [abs(pxcor) < 5 and abs(pycor) < 5] [set pcolor yellow]
ask patches with [abs(pxcor) < 2 and abs(pycor) < 2] [set pcolor brown]
end
to setup-birthdays
end
to go
ask eggs
[ kill-eggs ]
ask hatchlings
[ move-hatchlings
kill-hatchlings]
ask juveniles
[ move-juveniles
kill-juveniles]
ask hawksbills
[ move-hawksbills
kill-hawksbills
reproduce-hawksbills ]
tick
if not any? turtles [stop]
end
to kill-eggs
set z random 100
if z > 50
[die]
end
to kill-hatchlings
set z random 100
if z > 10
[die]
end
to kill-juveniles
set z random 20
if z > 18
[die]
end
to kill-hawksbills
set z random 5
if z > 4
[die]
end
to move-hatchlings
rt random 360
fd 1
end
to move-juveniles
rt random 360
fd 1
end
to move-hawksbills
rt random 360
fd 1
end
to reproduce-hawksbills
if pcolor = yellow
[set z random 100
if z > 75
[hatch-eggs 5[
set color 49.5
set size 0.5]
]]
end
To turn a turtle into a hatchling, just do set breed hatchlings! So, your code will probably look something like:
if age > 10 [
set breed hatchlings
]