How to use to in radius command for turtles to seek food and how to regenerate food over time in Netlogo? - netlogo

I am trying to do the following in NetLogo:
Get turtles (Elephants) to seek food
Ask plants to reproduce slowly over time on each side, one side before the other
Keep turtles (Elephants) to stay within world boundary
Keep turtles (Elephants) upright
What I would basically like to do is have our turtles (elephants) eat food on one side and seek food to cross to the other side. They will die if they get hit by a car. We want them to cross back and forth between sides so that they all die over time. We have tried to use the seek food primitive but is does not work for our simulation. We have also had the turtles stay within the world using the bounce primitive but with this current code they tend to move everywhere once again. As for the food regeneration, we have tried to use the hatch function but that also does not work.
Your help is very much appreciated.
Here is our code for the simulation:
breed [ elephants elephant ]
breed [ cars car ]
breed [ plants plant ]
turtles-own [
speed
speed-limit
speed-min
]
to setup
clear-all
setup-patches
setup-elephants
setup-cars
setup-plants
reset-ticks
end
to setup-patches
ask patches [
ifelse (pycor > -2) and (pycor < 2)
[ set pcolor black ]
[ set pcolor green ]
]
end
to setup-elephants
ask n-of number-of-elephants (patches with [ pycor < -4 ])
[ sprout-elephants 1
[ set shape "elephant"
set color 4
set size 4
]
]
end
to setup-cars
ask n-of number-of-cars (patches with [ pcolor = black ])
[ sprout-cars 1
[ set shape "car"
set color 105
set size 2
set heading 90
]
]
end
to setup-plants
ask n-of number-of-plants (patches with [ pcolor = green ])
[ sprout-plants 1
[ set shape "plant"
set color 62
set size 1
]
]
end
to go
ask elephants [
bounce forward 1
]
ask cars [
set xcor random-xcor
set heading 90
forward 1
move-elephants
move-cars
eat-plants
kill-elephants
]
end
to bounce
if abs pxcor = max-pxcor
[ set heading ( - heading ) ]
if abs pycor = max-pycor
[ set heading ( 180 - heading ) ]
end
to move-elephants
ask elephants [
right random 360
forward 1
]
end
to move-cars
set speed 0.1
set speed-limit 0.1
end
to eat-plants
ask elephants
[ let prey one-of plants-here
if prey != nobody [ask prey [die]]
]
end
to kill-elephants
ask cars
[ let prey one-of elephants-here
if prey != nobody [ask prey [die]]
]
end

There are several problems with this code so I am going to try and get rid of the more obvious logical issues and see if that allows you to focus on a specific question. Note that you should really be building your code more gradually - add one behaviour (eg move elephants, move cars, eat food or whatever) and make sure it works before adding the next behaviour.
Your go procedure doesn't have a tick for time passage
Your go procedure has each car randomly move all the elephants, so they are moving multiple times
Your car speeds and speed limits are being set to the same value each tick and never changed
You have nested ask cars [ ask elephants [ <do stuff> ] ] for eating plants and killing elephants, which will make these happen many times each tick
Fixing just those problems, gets this (note that I replaced slider inputs with numbers so you will have to change them back). This should fix the things you mentioned in your comments. You will have to ask a specific question about whatever else it is you are trying to fix.
breed [ elephants elephant ]
breed [ cars car ]
breed [ plants plant ]
turtles-own
[ speed
speed-limit
speed-min
]
to setup
clear-all
setup-patches
setup-elephants
setup-cars
setup-plants
reset-ticks
end
to go
ask elephants
[ bounce
forward 1
]
ask cars [ forward 1 ]
move-elephants
eat-plants
kill-elephants
tick
end
to bounce
if abs pxcor = max-pxcor
[ set heading ( - heading ) ]
if abs pycor = max-pycor
[ set heading ( 180 - heading ) ]
end
to move-elephants
ask elephants
[ right random 360
forward 1
]
end
to eat-plants
ask elephants
[ let prey one-of plants-here
if prey != nobody [ask prey [die]]
]
end
to kill-elephants
ask cars
[ let prey one-of elephants-here
if prey != nobody [ask prey [die]]
]
end
to setup-patches
ask patches [
ifelse (pycor > -2) and (pycor < 2)
[ set pcolor black ]
[ set pcolor green ]
]
end
to setup-elephants
ask n-of 20 (patches with [ pycor < -4 ])
[ sprout-elephants 1
[ set shape "wolf"
set color 4
set size 4
]
]
end
to setup-cars
ask n-of 20 (patches with [ pcolor = black ])
[ sprout-cars 1
[ set shape "car"
set color 105
set size 2
set heading 90
set speed 0.1
set speed-limit 0.1
]
]
end
to setup-plants
ask n-of 50 (patches with [ pcolor = green ])
[ sprout-plants 1
[ set shape "plant"
set color 62
set size 1
]
]
end

Related

How to get turtles to move to the target?

I'm stumped with an issue in my model. I have a model that looks to simulate an office environment, where there are two breeds: employees and citizens. The employees stay in the office, denoted by grey coloured patches, and the citizensstay in the outside world denoted by black colour patches.
In the middle of the world patch 0 0 there is an office, where employees go to pick up money. There are 4 service-desks where both employees and citizens are to meet for a transfer of money to occur. Here is the full code:
globals [ office-space ]
breed [ offices office ]
breed [ service-desks service-desk ]
breed [ employees employee ]
breed [ citizens citizen ]
offices-own [ money ]
employees-own [ money-held ]
citizens-own [ money-received ]
to setup
clear-all
create-offices 1
ask offices [
set shape "building institution"
set size 4
set color yellow
set money num-of-money ]
create-employees num-of-employees
ask employees [
set shape "person"
set size 1.5
set color blue
setxy random-xcor random-ycor ]
create-citizens num-of-citizens
ask citizens [
set shape "person"
set size 1.5
set color white
setxy random-xcor random-ycor ]
;; create four service desks
ask patch 0 8 [
sprout 1 [
set breed service-desks
set shape "building institution"
set color pink
set size 3 ]
]
ask patch 0 -8 [
sprout 1 [
set breed service-desks
set shape "building institution"
set color pink
set size 3 ]
]
ask patch -8 0 [
sprout 1 [
set breed service-desks
set shape "building institution"
set color pink
set size 3 ]
]
ask patch 8 0 [
sprout 1 [
set breed service-desks
set shape "building institution"
set color pink
set size 3 ]
]
;; create office space
set office-space patches with [ pxcor <= 8 and pxcor >= -8 and pycor <= 8 and pycor >= -8 ]
ask office-space [ set pcolor grey]
place-on-color-employees ;; sets all employees randomly within the grey square
place-on-color-citizens ;; sets citizens randomly outside of the grey box
reset-ticks
end
to place-on-color-employees
let _patches (patches with [pcolor = grey])
ask employees [
move-to one-of (_patches with [not any? turtles-here])
]
end
to place-on-color-citizens
let _patches (patches with [pcolor = black])
ask citizens [
move-to one-of (_patches with [not any? turtles-here])
]
end
to go
employee-movement
employee-take-money
citizen-movement
tick
end
to employee-movement
ask employees [
ifelse [pcolor] of patch-ahead 1 = black
[ rt random-float 360]
[ forward 1 ]
let target one-of citizens
if money-held > 0 [
set heading (towards target)
]
]
end
to citizen-movement
;; citizens walk only in the black patches, they do not go into the office area
ask citizens [
ifelse [pcolor] of patch-ahead 1 = grey
[ rt random-float 360]
[ forward 1 ]
;; if they have no money, then the citizens will walk to one of the service-desks
let target one-of service-desks
if money-received = 0 [
set heading (towards target )
]
]
end
to employee-take-money ;; asks employees to go to the main office and get money
ask employees [
if any? turtles-here with [ shape = "building institution" and color = yellow] [
set money-held money-held + 1
set color green ]
]
end
The issue I have is that within the employee-movement function, the employees will not move towards their targets. Whereas, the citizens will move to their targets. The code for both breeds is basically the same. The employees tend to congregate around the central patch, rather than moving to the targets.
Edited after receiving the full code:
The problem lies with how you define target as a local variable (let target one-of service-desks) each time you call the code. However, since there is more than one service-desk, nothing is forcing them to choose the same service-desk each time. This means that the employees, who are standing in the middle of the four service-desks, are basically taking a step in a random direction at each tick. The citizens on the other hand stand outside of the square on which the service-desks are located. Because of that, all of the service-desks are roughly in the same direction for them, so their general movement also goes in that direction.
I see two different options for working around this. The first one is to not use let target one-of service-desks but use let target min-one-of service-desks [distance myself]. This moves them to the closest service-desk rather than to a random service desk.
The other option would be to set target as a turtles-own variable, and not letting them choose a new one all the time.
Finally I streamlined your setup a little bit, reducing the amount of code you needed.
globals [
office-space
num-of-money
num-of-employees
num-of-citizens
]
breed [ offices office ]
breed [ service-desks service-desk ]
breed [ employees employee ]
breed [ citizens citizen ]
offices-own [ money ]
employees-own [ money-held ]
citizens-own [ money-received ]
to setup
clear-all
set num-of-money 100
set num-of-employees 5
set num-of-citizens 5
create-offices 1 [
set shape "building institution"
set size 4
set color yellow
set money num-of-money
]
create-employees num-of-employees [
set shape "person"
set size 1.5
set color blue
setxy random-xcor random-ycor
]
create-citizens num-of-citizens [
set shape "person"
set size 1.5
set color white
setxy random-xcor random-ycor
]
;; create four service desks
let service-desk-patches (patch-set patch 0 8 patch 8 0 patch 0 -8 patch -8 0)
ask service-desk-patches [
sprout-service-desks 1 [
set shape "building institution"
set color pink
set size 3
]
]
;; create office space
set office-space patches with [ pxcor <= 8 and pxcor >= -8 and pycor <= 8 and pycor >= -8 ]
ask office-space [ set pcolor grey]
place-on-color-employees ;; sets all employees randomly within the grey square
place-on-color-citizens ;; sets citizens randomly outside of the grey box
reset-ticks
end
to place-on-color-employees
let _patches (patches with [pcolor = grey])
ask employees [
move-to one-of (_patches with [not any? turtles-here])
]
end
to place-on-color-citizens
let _patches (patches with [pcolor = black])
ask citizens [
move-to one-of (_patches with [not any? turtles-here])
]
end
to go
employee-movement
employee-take-money
citizen-movement
tick
end
to employee-movement
ask employees [
ifelse [pcolor] of patch-ahead 1 = black
[ rt random-float 360]
[ forward 1 ]
let target min-one-of citizens [distance myself]
if money-held > 0 [
set heading (towards target)
]
]
end
to citizen-movement
;; citizens walk only in the black patches, they do not go into the office area
ask citizens [
ifelse [pcolor] of patch-ahead 1 = grey
[ rt random-float 360]
[ forward 1 ]
;; if they have no money, then the citizens will walk to one of the service-desks
let target min-one-of service-desks [distance myself]
if money-received = 0 [
set heading (towards target )
]
]
end
to employee-take-money ;; asks employees to go to the main office and get money
ask employees [
if any? offices-here [
set money-held money-held + 1
set color green ]
]
end

How do you fix a problem with convert probability on a zombie apocalypse simulation on Netlogo [duplicate]

This question already has an answer here:
How do you go about making a convert probability chance for an agent in netlogo?
(1 answer)
Closed 1 year ago.
currently I'm working on a zombie apocalypse simulation on Netlogo, and I'm almost done except that the convertion function is not working. when the zombies collide with humans the humans they either die or convert the human to a zombie according to the global variable convert_probability. For example, if convert probability is set to 80 the human would have an 80% chance of winning the fight and killing the zombie and the zombie would have a 20% chance of converting the human to a zombie.
Also, zombies and humans are not allowed to pass over the brown patches and the function I wrote for that is change_direction, but had to comment those parts because I run to an error.
I have spent hours but couldnt come up with a solution so I would really appreciate any help;
breed [humans human]
humans-own [ humans_speed]
turtles-own [
infected?
]
patches-own [
block
]
breed [zombies zombie]
zombies-own [ zombies_speed]
globals [
student_id
username
nzomb
%infected
]
to setup_world
clear-all
reset-ticks
set student_id 19009670
ask patches [set pcolor green]
set-default-shape zombies "person"
set-default-shape humans "person"
create-zombies 5 [
set color red
set size 4
set zombies_speed 0.5
setxy random-pxcor random-pycor
]
ask zombies[
move-to one-of patches with [pcolor = green]
]
create-humans 15 [
set color blue
set size 4
set humans_speed 1 + random-float 0.1
setxy random-pxcor random-pycor
]
ask humans[
move-to one-of patches with [pcolor = green]
]
set %infected (count turtles with [color = red ] / 20 ) * 100
set nzomb 0
draw_blocks
end
to draw_blocks
ask patches [
set block false
]
ask n-of 100 patches with [pcolor = green][
set pcolor brown
set block true
]
end
to change_direction
if[block] of patch-ahead 2 = true [
right 180
face one-of patches in-radius 2 with [not block]
]
end
to run_model
if ticks >= 10000 [ stop ]
tick
move-turtles
convert
if not any? humans [stop]
end
to move-turtles
ask humans [move-humans]
ask zombies [move-zombies]
end
to move-humans
ask humans [
if any? zombies in-radius (10 + random 20) [rt 180]
set infected? false
set heading (heading + 45 - (random 90))
forward 1 + random-float 1.1
zombiedeath
convert
;;change_direction
]
end
to move-zombies
ask zombies [
chasehuman
convert
zombiedeath
set %infected (count turtles with [color = red ] / 20 ) * 100
set infected? true
set heading (heading + 45 - (random 90))
forward 0.5
; change-direction
]
end
to chasehuman
if any? humans in-radius 10 [
set heading towards one-of humans in-radius 10]
; change_direction
end
to runaway
face min-one-of zombies [distance myself]
rt 180
;change_direction
end
to convert
ask turtles with [ breed = zombies ]
[
ask humans-on patch-here
[
if random 100 < convert_probability [set breed zombies]]
ask humans-on patch-here [if random 100 < convert_probability
[set color red]]
]
end
to zombiedeath
ask zombies-on patch-here [if random 100 > convert_probability
[die]]
end
Okay, the only procedure relevant to this question is this one (same code as above, formatted so you can see the structure logic}:
to convert
ask turtles with [ breed = zombies ]
[ ask humans-on patch-here
[ if random 100 < convert_probability
[ set breed zombies
]
]
ask humans-on patch-here
[ if random 100 < convert_probability
[ set color red
]
]
]
end
You haven't actually told us what the problem is - "convertion function is not working" does not say whether it is generating an error, or what behaviour it is doing compared to what is expected for example. But, look at what this code actually does. First it finds all the zombies then, for each zombie, it:
gets the humans on the same patch to convert to zombies with some probability
gets the humans on the same patch to change colour to red with some probability
Your first problem is that you haven't linked the turning red with becoming a zombie. Is that the problem you were trying to solve? If so, here is some cleaned up code that links zombie and red:
to convert
ask zombies ; note, you can just directly use the breed name
[ ask humans-here ; again, can use the breed name
[ if random 100 < convert_probability
[ set breed zombies
set color red
]
]
]
end

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:

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

Avoid visited patch netlogo

Sir i am working on a project and time to time i use to post questions here related to that problem. I have created a simulation scenario i which turtles (robots) move around in the space and also each robot keep track of its visited patches. On the movement if patch-ahead 1 is visited patch then i need to turn the robot to 45 degree left and check again for patch-ahead until it checks all 8 neighbors if any one of the 8 is UN-visited then it should move to that patch and continue its exploration. But if all 8 are visited then it should move to patch which is in front of current heading after checking the all 8 neighbors no matter it is visited.
Here is the piece of code i am using.
breed [robots robot ]
robots-own[ state memory ]
patches-own [ is-obstacle? ]
to setup
__clear-all-and-reset-ticks
create-robots num [
set memory (list patch-here)
]
draw-obstacles
ask patches [if pxcor = 0 and pycor = 0 [ set pcolor black ]]
end
to draw-obstacles
ask patches with [ pxcor mod 6 = 0 and pycor mod 6 = 0 ] [set pcolor red set is-obstacle? true]
; set pcolor red
ask patches [ ifelse pcolor = red [ set is-obstacle? true ][ set is-obstacle? false ] ]
ask patches with [ count neighbors != 8 ] [ set pcolor red set is-obstacle? true ]
end
to make-obstacle
if mouse-down?
[ ask-concurrent patches
[ if ((abs (pxcor - mouse-xcor)) < 1) and ((abs (pycor - mouse-ycor)) < 1)
[set pcolor red]]
]
end
to remove-obs
if mouse-down?
[ ask-concurrent patches
[ if ((abs (pxcor - mouse-xcor)) < 1) and ((abs (pycor - mouse-ycor)) < 1)
[set pcolor black]]
]
end
to go
ask patches [if ( pcolor = red )[set is-obstacle? true]]
ask patches [if ( pcolor = black )[set is-obstacle? false]]
ask-concurrent robots ; wanderers instructions
[
rt random-float rate-of-random-turn
lt (rate-of-random-turn / 2)
set-state
move-robots
]
tick
end
to move-robots ;;turtle proc
if (not member? state ["disperse" "explore"]) [
error "Unknown state"
]
if (state = "disperse") [
disperse
]
if (state = "explore") [
explore
]
end
to set-state ;;turtle proc
ifelse (any? other turtles in-radius 1) [
set state "disperse"
] [
set state "explore"
]
end
to disperse ;;turtle proc
avoid-obstacle
move1
; move-to one-of patch-set [neighbors] of neighbors
end
to explore
move
;search-open-room
avoid-obstacle
;move-to one-of neighbors
end
to move
fd speed
set memory lput patch-here memory
if ( (member? patch-ahead 1 memory) or ([is-obstacle?] of patch-ahead 1 ) )
[ lt random 45
]
end
to move1
fd speed
end
to avoid-obstacle
set memory lput patch-here memory
if ([is-obstacle?] of patch-ahead 1 )
[
ifelse [is-obstacle?] of patch-at-heading-and-distance (heading - 5) 1
[
ifelse [is-obstacle?] of patch-at-heading-and-distance (heading + 5) 1
[
ifelse random 1 = 0
[ rt 40 ]
[ lt 40 ]
]
[ rt 60 ]
]
[lt 60]
]
end
to search-open-room
ask robots[
ifelse ([is-obstacle?] of patches in-cone 2 150 )
[ rt 45 ] [ move ]
]
end
But in the move procedure i am just able to lt random 45. How to change it according to above mentioned scenario. I tried many with while loop and repeat statement but code does not seems to be working for me.
You could do it using while or repeat, but I think this a case where recursion works well.
The idea is to have a procedure that keeps on calling itself until the desired state is achieved:
to turn-until-free [ n ]
let target ifelse-value (patch-ahead 1 = patch-here)
[ patch-ahead 2 ]
[ patch-ahead 1 ]
let seen? member? target memory
let obstacle? [ is-obstacle? ] of target
if-else n < 8
[ if seen? or obstacle? [ lt 45 turn-until-free n + 1 ] ]
[ if obstacle? [ lt 45 turn-until-free n + 1 ] ]
end
The n parameter represents the number of calls that we've already made to the procedure (or, in other words, the number of neighbors that we've checked so far). When you call the procedure for the first time, you start with n = 0:
to move
turn-until-free 0
fd 1
set memory lput patch-here memory
ask patch-here [ set pcolor black + 2 ] ; just to show what's visited
end
A couple of things that were not part of your original specification:
It can happen that patch-ahead 1 is the same patch that the robot is already on. A patch has sides of length 1, but its diagonal is a bit longer (√2). So if a robot is in the bottom left corner, for example, and facing towards the top right, patch-ahead 1 = patch-here will be true. In these cases, we look a bit further and set the target to patch-ahead 2.
It can happen that, after checking all 8 neighbors, you end up facing an obstacle. If that's the case, you need to keep on turning until you're clear of the obstacle. And as a matter of fact, doing this takes care of obstacle avoidance nicely, and you might be able to get rid of the avoid-obstacle procedure in your code.
Edit:
Here is the code needed (in addition to the two procedures above) for a fully working example:
breed [ robots robot ]
robots-own [ memory ]
patches-own [ is-obstacle? ]
to setup
ca
ask patches [ set is-obstacle? false ]
ask patches with [ pxcor mod 6 = 0 and pycor mod 6 = 0 ] [
set is-obstacle? true
set pcolor red
]
ask n-of 5 patches with [ not is-obstacle? ] [
sprout-robots 1 [ set memory [] ]
]
reset-ticks
end
to go
ask robots [ move ]
tick
end
If you are having trouble with runtime errors or other unwanted behavior, I suggest you start from this and add back whatever else you had in your simulation one piece at a time. Then, you can see exactly where the problem comes from.
I also changed if-else n < 7 for if-else n < 8 in the turn-until-free procedure above. This way, the robot comes back to its original heading if all neighbors are explored instead of turning a bit right. This avoids going in circles once the whole territory is explored.