Turtles hatch when crossing a line - netlogo

I want my turtles to hatch (= make one more turtle) when they cross a specific line. I have tried the command ifelse?, and I can get it to work on a simple model, when my turtles randomly wanders: If they move to a patch on the left side (xcor < 0) they die, if they make a move to a patch with xcor > 0 they hatch 1.
But I want the proces to be linked to witch patch they come from. If they stand on a patch with xcor < 0 and moves to another patch with xcor < 0 they shall die - but if they change xcor from negative to positive - they should multiply (= hatch 1).
My problem is: Is it possible to write a code-string that "remembers" the turtles position one tick before and use it to either let the turtle die og multiply?
{
to setup
clear-all
create-turtles 20
ask turtles [set size 2
set heading random 45 ;; turtle is now facing northeast
setxy random-xcor random-ycor
set color white
set shape "person"]
end
to go
ask turtles
[ rt random 360 ; turns in a random direction
fd 4 ;; all turtles move forward one step
rt random 180 ;; ...and turn a random amount
fd 4
lt random 180
]
ask turtles
[ifelse pxcor > 0
[hatch random 2]
[die]]
end }

You can use a turtle variable to give each turtle a memory.
turtles-own
[
old-xcor
]
Just before the turtle moves, assign ‘xcor‘ to that variable.
To move-turtle
Set old-xcor xcor
< Your movement code >
if old-xcor < 0
[ Ifelse xcor < 0
[ Die ]
[ Hatch 1 ]
]
End

Related

How can I properly implement a function at the end of a counter in Netlogo?

I am writing an assembly line model, and I would like to implement a counter to hold a turtle at a specific patch (in this case, patch 3 0) for 10 ticks. Once 10 ticks have passed, I would like the turtle to keep on moving at the rate of one patch per tick and for the next turtle in line to begin its own 10 tick timer once it arrives at the specified patch.
So far, I can stop the turtles at the specified patch and run a 10 tick counter; however, I cannot seem to get the turtles to keep moving continuously after the timer is completed.
Here are the relevant parts of my code so far.
to go
move-tubs
move-drums
machine-marriage
move-machines
stay
keep-going
tick
end
to move-machines
ask wmachines [
if not any? turtles-on patch-ahead 1 and xcor < 3
[ forward 1]
]
end
to stay
ask wmachines-on patch 3 0[
ifelse counter = 0 [
set counter 10
]
[set counter counter - 1
set label counter
if counter = 0
[forward 1]
]
]
end
to keep-going
ask wmachines-on patch 4 0[
if not any? turtles-on patch-ahead 1 and xcor < 12
[ forward 1]
]
end
If your problem is that turtles leave patch 3 0 but then they do not move forward continuously beyond patch 4 0, it is simply because your keep-going procedure is only addressing turtles that are exactly on patch 4 0 (and for this reason the xcor < 12 part is completely unused).
In general, it looks very complicated and unnecessary that you are using three different procedures (i.e. one before patch 3 0, one for patch 3 0, and one for patch 4 0 but which should really be beyond patch 3 0) each of which is hard-coding some location in your model.
The whole point of having a counter is that you can generalise a waiting condition across the whole model, so your go procedure can be simplified a lot by simply asking agents that have concluded their countdown to do one thing, and those who have not concluded their countdown to do another thing.
Look at this minimal reproducible example where I have an unpredictable arrangement of stopping-patches but implement the waiting condition in a very general and simple way:
turtles-own [
counter
]
to setup
clear-all
reset-ticks
resize-world 0 30 0 4
set-patch-size 25
ask patches with [pxcor = min-pxcor] [
sprout 1 [
set heading 90
set color lime
]
]
ask n-of 15 patches with [pxcor > min-pxcor] [
set pcolor brown
]
end
to go
ask turtles [
ifelse (counter = 0)
;; If the counter equals 0:
[forward 1
if (pcolor != black) [
set counter 10
]
]
;; If the counter does not equal 0:
[set counter counter - 1]
ifelse (pcolor = black)
;; If the turtle is on a black patch:
[set label ""]
;; If the turtle is not on a black patch:
[set label counter]
]
tick
end

NetLogo Battle Simulation: Placing soldiers in between specific coordinates?

I'm new to NetLogo and I'm unsure of how to place 300 spartans in a narrow row. Let's say an area of 2x5 patches, turtles overlapping one another. I have tried using sprout, this achieved the specific coordinate requirements but the turtles are only one per patch.. Here is some code I have.
ask patches with [pxcor > 0 and pycor > -2 and pycor < 2]
[ sprout 1 [ set color red ] ]
or
to setup-spartans
create-spartans 300
set-default-shape turtles "person"
ask spartans
[ setxy random-xcor -3 ;; makes only a single row and goes across entire screen
;; (I need it to be in a specific area)
set heading 180
set color red ]
end
How about something like this?
create-spartans 300 [
set xcor -2 + random-float 5
set ycor -1 + random-float 2
]

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

You can't use Migrate in a turtle context, because migrate is observer-only

I managed to build my small model, but i do get an error, but don't know why?
Ps: i'm a bloody beginner
The Error code is:
You can't use migrate in a turtle context, because migarte ia observer-only.
So what can I do?
Thank you for your answers.
breed [fish a-fish]
breed [boats boat]
boats-own [profit]
to setup
clear-all
ask patches [set pcolor blue]
set-default-shape fish "fish"
create-fish initial-number-fish
[
set color grey
set size 1.0
setxy random-xcor random-ycor
]
set-default-shape boats "boat"
create-boats initial-number-boats
[
set color black
set size 1.5
set profit random (1 * profit-per-fish)
setxy random-xcor random-ycor
]
reset-ticks
end
to go
if not any? turtles [stop]
ask fish
[
move
fish-reproduce
]
ask boats
[
move-boats
catch-fish
death
reproduce-boats
migrate
]
tick
end
to move
rt random 50
lt random 50
fd 1
end
to fish-reproduce
if random-float 100 < fish-growth
[hatch 1 [rt random-float 360 fd 1]]
end
to move-boats
rt random 50
lt random 50
fd 1
set profit profit - 0.1
end
to catch-fish
let prey one-of fish-here
if prey != nobody
[ask prey [die]
set profit profit + profit-per-fish]
end
to death
if profit < 0 [die]
end
to reproduce-boats
if profit > 1
[
set profit (profit / 2)
hatch 1 [rt random-float 360 fd 1]]
end
to migrate
if random-float 100 < random-spawn-rate
[create-turtles 2 [rt random-float 360 fd 1]]
end
There are 3 different primitives for creating new turtles in NetLogo:
create (observer), hatch (turtle) and sprout (patch).
Each one works only in a specific context.
This means you have to be aware of the context in which you are calling your procedure.
In your example, you are calling the create-turtles primitive inside of an ask turtles (specifically ask boats) context. Which means you are in a turtle context and not in an observer context and therefore create-turtles is not allowed to use.
To solve your problem, you just have to replace create-turtles by hatch (or hatch-<breed>, like hatch-fish if you want to spawn new agents in a specific breed).

NetLogo: creation of lattice/grid resources world without using turtles?

I would like to create a "gridded" world of resources, in specific distance from the central patch and keep distances equal between these patches. Due to calculation demand, I prefer not to use turtles to create this patchy world. I expect to create something like this:
Equally, I would like to define distance between patches as a slider tool. I was wandering to use turtle lattice walk and then turn patches to different color, but is there any way how to do that without turtles ? Thanks for any suggestions !
My not totally working exemple:
to setup
clear-all
ask patches [set pcolor green]
foreach [5 10 15] [
repeat 9 [
make-red-patch ?
]
]
reset-ticks
end
to make-red-patch [dist]
crt 1 [
fd dist
rt 90
while [pcolor = red] [
bk dist
rt 90
fd 2 * dist
]
set pcolor red
die
]
end
I am not exactly sure what you need, first you mentioned you don't want to use turtles and in your own answer you have problem with the patch without a turtle.
There might be another way to approach this question:
to setup
clear-all
ask patches with [pxcor mod Grid = 0 and pycor mod Grid = 0] [set pcolor red]
end
And these are examples with different Grid size:
After more detailed search I found my answer here: http://netlogo-users.18673.x6.nabble.com/Setting-up-agents-in-a-grid-formation-td4864083.html
They consider to distribute turtles, not patches and then attribute patches turtles' qualities.
Here is the code:
to setup
clear-all
create-turtles 1
[ let $n 0 ; actual number of turtles on this patch
let $s 0 ; current number of turtles on a side of square pattern - 1
set heading 0
ask patch-here [set pcolor red]
repeat 16 ; number of needed turtles
[ hatch 1 jump Grid ; make one turtle and move
set $n $n + 1 ; increment count of curent side
ask patch-here [set pcolor red]
if $n > $s ; if side finished...
[
right 90 set $n 0 ; turn and reset count
ask patch-here [set pcolor red]
; if headed up or down, increment side count
if heading mod 180 = 0 [ set $s $s + 1
]
]
]
die
]
end
which produce:
I still don't know how to deal with 1 patch without turtle (bottom right corner), but this exemple helped me a lot ! :)