Creating the game Snake on Netogo - netlogo

I have to create the game snake on Netlogo, with specific instructions on how the snake has to move, as below:
"The snake moves by adding a square to its head and simultaneously deleting a square from the tip of its tail."
I believe that I have successfully managed to fulfill this condition, however, when taking a sharp turn everything falls apart, due to lines 105-110. The issue is that I can't seem to figure out how to specify which body segment has to become the tail in the next step.
ask heads [
if (count heads-here + count mice-here = 2) [
if heading = 0 [
hatch-heads 1 [
setxy xcor (ycor + 1)
;;and so on for all 4 directions
ask heads [
if heading = 0 [
hatch-heads 1 [
setxy xcor (ycor + 1)
;; and so on for all 4 directions
ask bodies [if (
count bodies-on neighbors4) + (
count heads-on neighbors4) + (
count tails-on neighbors4) < 2 [
set breed tails
set shape "square"]]
;; the above segment is where I believe the problem lies
I am hoping for the last "body" segment on the snake to turn into the breed "tail".

Related

Counting turtles after a chunk of code has executed

In my model currently, I have a monitor on the Interface that counts the total number of turtles (deer in my case) every tick. Is it possible to have another monitor that counts the number of deer after a certain line of code is executed? For example, here's a snippet of code:
to catch-fawns-source
let fawn-hunting-rate (fawn-harvest-rate-source)
if any? fawns-on source-patches
[ ask fawns-on source-patches [
if random-float 1.0001 < (fawn-hunting-rate)
[ set harvest (harvest + 1)
set fawn-harvest (fawn-harvest + 1)
set source-harvest (source-harvest + 1)
die ] ]
]
end
In this case, this is where I have fawns being harvested. This code is the same for my male and female adult and juvenile deer. So is there a way I could track my population specifically after that snippet of code (and the other identical ones for the juveniles and adults) is executed?
I'm not sure if I would need any sort of Netlogo extension (if there are any applicable to this) or if I could somehow add in another global variable and lines of code that accomplishes this task.
Thanks for all of your help as always!
I think you can get away with another global variable that you just update however often you want. For a very simple example, consider this setup:
globals [ most-recent-pop-check ]
to setup
ca
crt 10
set most-recent-pop-check count turtles
reset-ticks
end
Here, most-recent-pop-check will only be updated when needed, then you can just set a monitor to display that variable. In this example, the value will only change every 25 ticks- see comments for more detail:
to go
ask turtles [
; Turtles may die
if random-float 1 < 0.25 [
die
]
; Throw in some density-dependence to control population size
if random-float 1 < ( 0.5 * ( 1 - ( count turtles / 500 ) ) ) [
hatch random 2 + 1
]
]
; If the ticks are not 0, and if the remainder after dividing
; the ticks by 0 is 0, update the most-recent-pop-check
; variable to reflect the current turtle population.
if ticks != 0 and ticks mod 25 = 0 [
set most-recent-pop-check count turtles
]
tick
end
Of course, in your case rather than having the update occur based on the number of ticks, just have it occur whenever you run the code chunk you're after.

How do I make turtle face in an organized manner like the "cro" command but in turtle context?

I am trying to make a turret that will fire 8 bullets in 8 directions. In the command I have, they all spawn with heading 0 how do I make them face the right direction. Each turtle should face in a multiple of 45. Just like it would with the cro command in observer context.
to fire-tacks
ask ttacks with [alive?] [
set attackSpeed attackSpeed + .5
if any? turtles with [is-bloon?] in-radius 5 and attackSpeed >= 12
[set attackSpeed 0
hatch-btacks 8 [set alive? false set is-turret? false
set size 1 set damage 1 set color black set is-dart? true set bullet-
speed 4
]]]
end
You could use range and foreach to do this (check the links for more detail on how they work). range can generate a sequence of the headings you would like, and foreach can iterate over that sequence to sprout new turtles with each heading. Have a look at this simplified example:
breed [ turrets turret ]
breed [ btacks btack ]
to setup
ca
create-turrets 1 [
setxy random-xcor random-ycor
]
reset-ticks
end
to go
ask turrets [
foreach ( range 0 360 45 ) [
new_heading ->
hatch-btacks 1 [
set heading new_heading
fd 1
]
]
]
end

Perspective based ranking?

I have a program where each peer has their own ranking system of other peers, what is the best way to implement this is NetLogo?
Normally, I would solve this with a 2D list:
[[turtle 1, score], [turtle 2, score], ...]
But this seems very troubling in NetLogo. This is my code for creating and modifying a 2D list:
to test
clear-all
crt 10
;Create a list of turtles
let agents-list [self] of turtles
;Create empty list, which will be the top level of the TwoD list
let TwoD-list []
;Populate the TwoD-list: [[turtle 0, 0], [turtle 1, 0], ...]
foreach agents-list [
set TwoD-list (lput (list ? 0) TwoD-list)
]
show TwoD-list
repeat 5 [
;Change a value in the TwoD-list
let rand-index random (length TwoD-list) ;select a random index
;The next line is what makes it a huge headache, basically you have to select a list at the top level to replace, and then select the list at the lower level to replace it.
;This entire line of code is just adding one to an element
set TwoD-list (replace-item rand-index TwoD-list (replace-item 1 (item rand-index TwoD-list) (item 1 (item rand-index TwoD-list) + 1)))
show TwoD-list
]
end
What else can I do? Or is there a better way to implement this method?
If you want to model relations between agents, NetLogo has the perfect thing for that: links!
Having each turtle assign a score to all other turtles can be quite naturally expressed as:
directed-link-breed [ rankings ranking ]
rankings-own [ score ]
to setup
clear-all
create-turtles 10
ask turtles [ create-rankings-to other turtles ]
; increment 5 random rankings by one:
ask n-of 5 rankings [ set score score + 1 ]
; display the rankings of each turtle:
ask turtles [ show [ (word end2 " " score) ] of my-out-rankings ]
end
If you don't want the links to show up in the view, you can hide them with:
ask links [ set hidden? true ]

Running a model several times with BehaviorSpace

From BehaviorSpace, I would like to run a model 100 times by varying two variables as follows:
["x-area" 1 ] and ["y-area" [1 1 100]].
A model is built as follows:
create landscape
add-turtles
go-simulation
By using the two variables, I would like that my 100 models run as follows:
;;; Model 1 ;;
"x-area" = 1
"y-area" = 1
clear-all
create landscape
add-turtles
go-simulation
;;; Model 2 ;;
"x-area" = 1
"y-area" = 2
add-turtles
go-simulation
;;; Model 3 ;;
"x-area" = 1
"y-area" = 3
add-turtles
go-simulation
....
;;; Model 100 ;;
"x-area" = 1
"y-area" = 100
add-turtles
go-simulation
To do this, I built 100 experiments and this method worked. Is there a faster way to run automatically 100 models without doing 100 experiments ? I tried to build 1 experiment like this
But I have this error message:
OF expected input to be a turtle agentset or patch agentset or turtle or patch but got NOBODY instead.
org.nlogo.nvm.ArgumentTypeException: OF expected input to be a turtle agentset or patch agentset or turtle or patch but got NOBODY instead.
at org.nlogo.prim._asm_proceduremovewithinpolygon_ifelse_86.perform(:4)
at org.nlogo.nvm.Context.runExclusive(Context.java:119)
at org.nlogo.nvm.ExclusiveJob.run(ExclusiveJob.java:57)
at org.nlogo.nvm.Context.runExclusiveJob(Context.java:162)
at org.nlogo.prim._asm_procedurestartsimulation_ask_69.perform(:1)
at org.nlogo.nvm.Context.stepConcurrent(Context.java:91)
at org.nlogo.nvm.ConcurrentJob.step(ConcurrentJob.java:82)
at org.nlogo.job.JobThread.org$nlogo$job$JobThread$$runPrimaryJobs(JobThread.scala:143)
at org.nlogo.job.JobThread$$anonfun$run$1.apply$mcV$sp(JobThread.scala:78)
at org.nlogo.job.JobThread$$anonfun$run$1.apply(JobThread.scala:76)
at org.nlogo.job.JobThread$$anonfun$run$1.apply(JobThread.scala:76)
at scala.util.control.Exception$Catch.apply(Exception.scala:88)
at org.nlogo.util.Exceptions$.handling(Exceptions.scala:41)
at org.nlogo.job.JobThread.run(JobThread.scala:75)
The problem is that my models continue to run with this error. So it is difficult to see where is the problem. Given the following message:
"at org.nlogo.prim._asm_proceduremovewithinpolygon_ifelse_86.perform(:4)" in the error message,
maybe that the problem is in the procedure "move-within-polygon".
Here is my procedure "move-within-polygon" for a given color of polygons:
if [pcolor] of patch-here = green [
set list-angles-in-green item 0 table-angles
loop [
let angle-in-green one-of list-angles-in-green
ifelse [pxcor] of (patch-right-and-ahead angle-in-green 1) = max-pxcor or [pycor] of (patch-right-and-ahead angle-in-green 1) = max-pycor [
print "die"
die
stop ]
[ ifelse (patch-right-and-ahead angle-in-green 1) != nobody and [pcolor] of (patch-right-and-ahead angle-in-green 1) = green [
print "move"
move-to patch-right-and-ahead angle-in-green 1
[ if not any? neighbors with [pcolor = green] [
print "no neighbors"
move-to patch-here
stop ] ] ] ] ]
Thanks for your help.
If a turtle ends up on the edge of the world, then patch-right-and-ahead angle-in-green 1 might point outside the world (depending on what angle-in-green is), so [pxcor] of in [pxcor] of (patch-right-and-ahead angle-in-green 1) = max-pxcor would ask for the coordinate of nobody. The same thing could happen for pycor later in the same line.
Question: Can a turtle ever get to the edge of the world in your model? It looks to me like the code that you displayed could lead to that result.
If so, then one way to prevent the error would be to replace
[pxcor] of (patch-right-and-ahead angle-in-green 1) = max-pxcor
with
xcor = max-pxcor
That's true when a turtle reaches the last column of patches. If you also want turtles to die when they're close to the edge, you could use both of these expressions in the if-else:
(xcor = max-pxcor) or ([pxcor] of (patch-right-and-ahead angle-in-green 1) = max-pxcor)
(I added parentheses simply for clarity.)
However, I wonder whether this would serve the same purpose:
xcor = max-pxcor or xcor = max-pxcor - 1
If any of these methods are right for your application, then you can obviously do the same thing for the y coordinates.
Your experiment setup appears correct to me, except that you should remove the "Stop condition" of TRUE, because if the stop condition is always true, your runs will never run the go commands even once.
The error you're getting is coming from code that you haven't shown us, so I can't help you there. You'll need to show us the code in which the error is occurring.
Also, at the time the error occurs, what are the values of x-area and y-area? And does the same error occur if you set x-area and y-area to the same values outside BehaviorSpace? If so, then the error doesn't really have anything to do with BehaviorSpace.
Finally, a note on terminology: there is only one model here, not 100, and only one experiment here, not 100. You're attempting to run one experiment on your model, and that experiment consists of 100 model runs. Using the standard terminology will help you communicate your issue clearly.

Controlling lives of turtles in NetLogo

For a project, I'm developping a simulation in NetLogo dealing with rabies diseases in dogs and humans. I have some turtles-humans with dogs that can be vaccinated or not. At the beginning I create a dog with rabie and, in according to the fase (1 or 2) of the disease, it can spread the disease to other dogs with a probability. At the end the dog can die either for paralysis (if a probability is higher than 75%) or for other complications. Here's the code:
http://pastebin.com/esR75G3T
In the end you can see that a dog not dying for paralysis will die after some days (between 4 or 6). In other words when the days_infected are equal to end-life.
To check if everything is ok at the beginning I tried to set that NONE of the dog is vaccinated so everyone is supposed to get the disease. In fact when the dog is in phase 2 it will bite anyone. The problem is that if I delete the last line of the code, everything works and some dogs die of paralysis and the other remain alive. If I enable also the last line to let the other dogs die too, nothing works...no dog is infected. why?
This is not a problem with your code: this is a problem with the dynamics of your model. What's happening is that your initial sick dog dies before actually infecting another dog. This is why removing the if (days_infected = end-life) [die] "fixes" the problem.
When I tried your model with a huge population (e.g., 5000 people) so that encounters are more frequent, the infection does spread. You could also increase the probability of infection, or increase the duration of the "furious" phase, I guess.
Another unrelated suggestion, if I may: you should have distinct persons and dogs breeds. Trying to cram everything inside regular turtles makes your code much more complicated than it should be. The way I would approach this would be to create a link from the person to her dog, and then use tie so that the dog is automatically moved when you move the person.
Edit:
OK, here is a version of your code slightly modified to use breeds:
globals [
total_dogs_infected
total_dogs
dead_humans
dead_dogs
]
breed [ persons person ]
persons-own [
sick?
]
breed [ dogs dog ]
dogs-own [
sick?
vaccinated?
rabies_phase
days_infected
end-incubator
end-furious
end-life
]
to setup
clear-all
initialize-globals
setup-turtles
reset-ticks
end
to initialize-globals
set dead_humans 0
set dead_dogs 0
set total_dogs_infected 0
end
to setup-turtles
set-default-shape persons "person"
set-default-shape dogs "wolf"
create-persons people [
setxy random-xcor random-ycor
set size 1.5
set sick? false
ifelse random 100 < 43 [
set color green
hatch-dogs 1 [
set color brown
set heading 115 fd 1
create-link-from myself [ tie ]
set days_infected 0
set vaccinated? (random 100 > %_not_vaccinated)
if not vaccinated? [ set color orange ]
]
]
[
set color blue ;umano sano senza cane
]
]
set total_dogs count dogs
ask one-of dogs [ get_sick ]
end
to get_sick
set sick? true
set color white
set rabies_phase 1
set end-incubator 14 + random 57
set end-furious (end-incubator + random 5)
set end-life (end-furious + 4 + random 2)
set total_dogs_infected total_dogs_infected + 1
end
to go
move
infect
get-older-sick-dog
tick
end
to move
ask persons [
rt random 180
lt random 180
fd 1
]
end
to infect
ask dogs with [ sick? ] [
if (rabies_phase = 1 and (random 100) <= 2) or rabies_phase = 2 [
ask other dogs-here with [ not sick? and not vaccinated? ] [ get_sick ]
]
]
end
to get-older-sick-dog
ask dogs with [ sick? ] [
set days_infected days_infected + 1
;the incubator phase ends after at least 14 days + random(57) and then we have phase 2 (furious)
if (days_infected = end-incubator) [ set rabies_phase 2 ]
;when the main furious phase finishes we have 75% of probability that a secondary furious phase continues for other 4 - 6 days until death ;or we have a probability of 25% that the disease end in paralysis with a fast death
if (days_infected = end-furious and (random 100 > 75)) [
set dead_dogs dead_dogs + 1
die
]
if (days_infected = end-life) [
die
]
]
end
; These last reporters are not used,
; they just illustrate how to get the
; dog from the owner or vice-versa:
to-report my-dog ; person reporter
report one-of out-link-neighbors
end
to-report has-dog? ; person reporter
report any? out-link-neighbors
end
to-report my-owner ; dog reporter
report one-of in-link-neighbors
end
Not only does it simplify some expressions (e.g., ask dogs with [ sick? ] instead of ask turtles with [ has_dog? and sick_dog? ]), it opens up all sorts of possibilities: a dog could run away from its owner, the owner could die without the dog dying, an owner could have two dogs, etc.