NetLogo Battle Simulation: Placing soldiers in between specific coordinates? - netlogo

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
]

Related

How to force turtles to move only in a half of the world?

I created a world divided in two parts with the command ask patches with [ pxcor < 0] [set pcolor blue] ask patches with [pxcor > 0] [set pcolor green] .
In one of this there're 100 turtles, who 5 are infected and the same in the other part.
My problem is to force the turtles to move only in their part of the world. So I want that turtles with pcolor = blue move randomly in the second and third quadrant (pxcor <0) and turtles with pcolor = green in the first and fourth quadrant (pxcor> 0). how do I do?
This is the code:
turtles-own
[
sick?
sick-time]
to setup
ca
ask patches with [ pxcor < 0 ] [set pcolor blue] ; we want divide the world in two parts: the blue one in the north of Italy
ask patches with [pxcor > 0 ] [set pcolor green]; the white one is the south of Italy
ask patches with [pxcor = 0 ] [set pcolor white ] ; represent the border
create-turtles 200 ; we create a population made up for 200 people
[ set size 1
set shape "person"
set sick-time 0
get-healthy]
ask n-of 100 turtles ; 100 of this one live in north of Italy
[setxy 12 random-ycor ]
ask n-of 100 turtles ; another 100 in the south
[setxy -12 random-ycor
]
ask n-of 5 turtles with [pcolor = blue] ; we want infect 5 people for each world
[get-sick ]
ask n-of 5 turtles with [pcolor = green]
[get-sick ]
reset-ticks
end
to get-healthy
set sick? false
set color white
end
to get-sick
set sick? true
set color yellow
set shape "circle"
set sick-time sick-time + 1
end
to go
ask turtles
[
move ]
tick
end
to move
rt random-float 360
fd 1
end
Your movement procedure looks like:
to move
right random-float 360
forward 1
end
If you want them to just stay where they are if moving would take them into the wrong half, then you can use patch-ahead to test the patch they'd be moving to. I think what you want is that they don't go to a different coloured patch. One way is:
to move
right random-float 360
if [pcolor] of patch-ahead 1 = pcolor [forward 1]
end
[pcolor] of patch-ahead 1 returns the colour of the patch that is one distance unit ahead, so where the turtle is trying to move to. pcolor is the colour of the patch that the turtle is currently standing on.

Turtles hatch when crossing a line

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

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 assign group of patches to own variable of a breed

I'm very new to netlogo and am wondering how I can set a group of patches to be an own variable to a certain breed. For example, let's say I have:
breed [ buildings building ]
buildings-own [ my-patches ]
I want to be able to have a set of patches (let's say a rectangle, so constrained by some coordinates) that are assigned to each individual building's my-patches field. How would I do this?
First thing you need to know is that you can't have breeds of patches. While you don't say that's what you want, I just want to make sure you are aware of this.
Have a look at this code. It is a complete program that creates some turtles (called realtors) and assigns them each some patches. It then turns those patches the same colour as the realtor.
breed [realtors realtor]
realtors-own [my-patches]
to setup
clear-all
create-realtors 10
[ setxy random-xcor random-ycor
set size 2
set shape "circle"
set my-patches n-of 5 patches in-radius 3
]
ask realtors [ask my-patches [set pcolor [color] of myself ] ]
reset-ticks
end
You can run it by creating a button for 'setup' or simply typing setup in the command centre.
Welcome to Stack Overflow and Netlogo! Given your breed and buildings-own as above, you can simply use set to assign the patch-set that you want a building's my-patches variable to hold.
to setup
ca
ask patches with [ pxcor mod 10 = 0 and pycor mod 10 = 0 ] [
sprout-buildings 1 [
set shape "square"
set heading 0
set size 1.5
set my-patches patches with [
pxcor > [pxcor] of myself - 3 and
pxcor < [pxcor] of myself + 3 and
pycor > [pycor] of myself - 3 and
pycor < [pycor] of myself + 3
]
ask my-patches [
set pcolor [color] of myself - 2
]
]
]
reset-ticks
end

To create fixed number turtles each with separate headings on fixed ycor and equidistant xcor

I want to create 4 turtles on fixed pycor (like pycor = 10) and even spacing xcor over that pycor; and also I want to make the headings of each turtles separate from other. The display is like
............. O ............. O .............. O ........... O ............
(heading 45) (heading 90) (heading 230) (heading 180)
O is the turtle here. My code is as below.
ask n-of 4 patches with [ pcolor = 18 and pycor = 10 ] [
sprout-turtles 1 [
set shape "default"
set color blue
set size 2
set heading one-of [90 270]
]
]
With this code turtles are created but many time with same heading, sometimes on same patch, sometimes neighboring patch as shown below
..........OOO...................O or .........OO..........O.........O...
but this i don't want. Should i have to use Create turtles four times separately specifying xcor, ycor and heading? Actually i don't want to use it four times. Please any suggestion and help? Thanks a lot.
Since the only thing you are taking from the patch to the turtle, you may as well just use create-turtles instead of sprout-turtles and then put them where you want. Typically, sprout is used when the particular patch meets relevant conditions - such as having lots of resources. Also, since you want specific values, using one-of or n-of will not work because they randomly select.
Instead you want something more like this (not tested):
let gap 15 ; spacing between turtles
let directions [45 90 230 180] ; heading values
let ii 0 ; counter / index
repeat 4
[ create-turtles 1
[ setxy (0 + ii * gap) 10
set shape "default"
set color blue
set size 2
set heading item ii directions
]
set ii ii + 1
]