Move turtles to vacant patch ahead in NetLogo - netlogo

I'm struggling to work out how to tell my turtles to move forward 1 onto a vacant patch, once they have already been turned around in a procedure called "turn-turtle".
let ahead patch-ahead 1
let vacant-ahead ahead with [not any? turtles-here ] ;;this line needs fixing
if any? turtles
[turn-turtle if vacant-ahead [fd 1]]
It produces this error, which I understand, but can't work out how to fix.
WITH expected input to be an agentset but got the patch (patch 1 -2) instead.
error while solute 2 running WITH
called by procedure MOVE-TURTLE
called by procedure GO
called by Button 'go'
Just replying to some comments in a more readable fashion:
Sorry I don't think I explained it very well, as I've just taken a tiny bit of my code out. Maybe this makes more sense.
to go
ask turtles
[move-turtle]
end
to move-turtle
turn-turtle
if (not any? turtles-on patch-ahead 1)
[fd 1]
end
So I just want this code to move the turtles that have been turned with "turn-turtle" to an empty patch ahead 1, preferably taking up the entire patch, like if they were "sprouted". Thanks!

Sounds like you want to do something a bit different, if you really want ahead to be a single patch. So perhaps
to move
ifelse (any? turtles-on patch-ahead 1) [
turn-turtle
][
fd 1
]
end

Related

NetLogo : getting turtles to direct-link if a condition is true

I'm trying to implement YOYO leader election algorithm in netlogo
first step in this algorithm is to orient links ( direct link )from the minimum to the maximumbut between neighbors only !
I tried the command
[`ask turtles with [ [ who ] of self < [who] of one-of link-neighbors ]
create-direct-to turtle [who] of one-of link-neighbors ]`
this creates direct link from min to max ( neighbors ) but also creates a direct link from max to min ( neighbors )
and I don't know what's wrong :(
here's a screenshot , if you notice theres' a direct link from 0 to 2 and also from 2 to 0 and my goal is to have only from 0 to 2
Your problem is that every time you do one-of, it randomly selects. So you test against a random link-neighbor in the first line, find it's true and then randomly select a link-neighbor to connect to.
[ ask turtles with [ [ who ] of self < [who] of one-of link-neighbors ]
create-direct-to turtle [who] of one-of link-neighbors
]
More generally, this seems an odd way to achieve your goal. To start with, link-neighbors are the turtles that the turtle is already linked to. link is the generic name for all link breeds (I think you have created a breed called direct-link).
I am not entirely clear what you mean by minimum and maximum since your code is just from smaller to larger who value, regardless of what other who values are available. If you want to create a link from every turtle to every turtle with a higher who value, here is some code:
ask turtles
[ let targets turtles with [who > [who] of myself]
create-links-to targets
]
In general, it is bad practice to use who in NetLogo code. who is a completely arbitrary identifier that simply tracks the order that turtles are created. If you have turtles that die, then your code may crash because it is referring to a turtle that no longer exists. Or perhaps at some point you will have two breeds of turtles - who doesn't care if your turtle is a person or a dog or a factory or...
This may be one of the very few exceptions, but you might want to think about what you are intending who to mean. For example, as this is a leadership model, perhaps you could have a variable called 'charisma' and all the links are from turtles with lower values of charisma to higher values of charisma.

How to specifically change a variable of an agent in the agentset?

I am trying to change a variable (score) of a particular agent in the agent set if it meets the specific condition of a patch. This is called by an another agent. To be more clear. My idea is for instance if there is a breed (horse) and it sees the patch (grass) and it is standing on another breed (vertices - since horse move along a path connected by nodes represented by vertices) - a score variable to added to vertices-own where if the grass quality <=3, it would add a score to the vertex on which it stands.
ask horses[
ask patches in-cone 50 60 [
if grass-quality <= 3 ask vertices with [min-one-of vertices in-radius 0 [distance myself] [set vertex-score vertex-score + 1 ]]]]
I know something is wrong with this code logic. I am trying to convert my mentioned thought into codes. Kindly suggest me.
Thank you all.
Regards,
Heng wah
NetLogo agent (turtle) positions are continuous numbers so it is generally wrong to try and say something like 'if another turtle is where I am'. While you may have got there using move-to, it's probably safer to have the horse identify a vertex that is very close to it rather than in the exact position. You have used radius 0 but I'm going to change that to 0.001 to allow for potential errors in position.
ask horses
[ if any? patches in-cone 50 60 with [ grass-quality <= 3 ]
[ let my-vertex min-one-of vertices in-radius 0.001 [distance myself]
ask my-vertex
[ set vertex-score vertex-score + 1 ]
]
]
]
This is not tested, but I have simply reorganised your code. You had some bracketing issues and you were also asking vertices to find the closest vertex (which would have been itself), rather than having the horse find the closest vertex.
It's also not necessary to separate the let and the ask but I thought that would be easier for you to see how it works.

NetLogo: ask turtle to set destination and keep walking towards it until reached

Goal: I am attempting to make a turtle pick a destination, then continue walking towards it until the destination is reached. At that point, the turtle returns to its original patch and picks another destination, walks towards it, repeat.
Issue: The selected destination sometimes changes while the turtle is walking towards it. I need some means of telling the turtle to hold the original destination until it reaches it.
Details: Here is my relevant code. Turtles are building territories. They have a territory center-point ("start-patch") from which they choose a destination to walk to and claim. Destination is based on the patch with "highest-value" where value should be the patch's benefit ("benefit-to-me") divided by the distance away from the start-patch ("cost-to-me"). I think turtles are constantly reassessing cost-to-me while walking, however. They shouldn't do this--highest-value must be assessed while standing on the start-patch.
How can I fix this so a turtle assesses highest-value while standing on the start-patch, sets a destination, and moves towards it until reached?
patches-own
[
owner ;; once part of a territory, owner becomes the turtle.
benefit ;; i.e., food available in a patch; used to assess "highest-value" to the turtle.
]
turtles-own
[
start-patch ;; the territory center; turtle returns here after reaching destination.
destination ;; the patch turtle wants to claim for its territory.
territory ;; the patches the turtle owns.
]
to go
tick
ask turtles
[
pick-patch
]
end
to pick-patch
set destination highest-value ;; calculated in reporters, below.
ifelse destination != nobody [
ask destination [set pcolor red] ;; reveals that destination changes occasionally before original destination is reached.
travel]
[give-up] ;; (will reposition start-patch to a new site if no destinations available.)
end
to travel
face destination forward 1 ;; **should** keep original destination, but it doesn't.
if patch-here = destination
[update-territory
move-to start-patch ] ;; return to the start-patch, and should only NOW assess new destination.
end
to update-territory
set owner self ;; and so on....
end
;;;---Reporters for highest-value:---
to-report highest-value ;; this appears to be changing while turtle moves...how fix this?
let available-destinations edge-patches
report max-one-of available-destinations [benefit-to-me / cost-to-me]
end
to-report benefit-to-me
report mean [benefit] of patches in-radius 1 ;; i.e., moving window to find high-benefit cluster
end
to-report cost-to-me
report distance myself
end
to-report edge-patches
report (patch-set [neighbors4] of territory) with [owner = nobody]
end
(Note: instead of "forward 1," I realize I could just use "move-to." I will eventually build in obstacles, however, and turtles will need to walk towards the destination to check for obstacles.)
Update: I think the issue could be addressed within the "cost-to-me" reporter? I tried making this change:
to-report cost-to-me
report distance [start-patch] of myself
end
Should this accomplish what I'm after? It would take away the "distance myself" part so that this cost remains constant. The other idea I've had is that "pick-patch" or "travel" may need something along the lines of "ifelse patch-here != destination [forward 1...]" but that doesn't seem to work either.
I tried the "while" loop idea recommended below (thanks!) and that seems to introduce a new host of odd behavior. I'm not sure how to code that out if I go that route. Something like this doesn't work (they just stop moving):
to travel
while [distance destination > 1]
[face destination forward 1]
if patch-here = destination
[update-territory
move-to start-patch ]
end
I'm new to this; thanks in advance for any help!
Second update: I think that the change I made in the previous update (report distance [start-patch] of myself) fixed part of my problem (assuming that line makes sense?), but left one issue. If there is a tie among patches with highest-value, the turtle still switches destination midway to its selected patch. So it still goes back to the original problem of having the turtle set and keep a destination until it is reached. Any ideas on how to fix this?
The difficulty with using while is that it will move the whole way during the tick. Since the turtle returns to the start patch, why don't you simply add a condition that it only picks out a destination when it is at the start patch? So the code would look like this:
to go
tick
ask turtles
[ if patch-here = start-patch [pick-patch]
]
end
You're right- every time a turtle runs pick-patch, it goes through the step of setting destination to highest-value. Then, it'll move forward one and check if it has arrived. At that point, whether or not it has reached its destination, the other turtles (if there are any) will have a chance to run pick-patch. Once all other turtles have done so, your original turtle will again set its destination to a freshly assessed highest value. So, since highest-value is dependent on distance, and the turtle's spatial coordinates change as it moves, some other patch might have the highest-value from the turtle's new position.
One way you could accomplish what you are after is to use while so that your turtle stays within the procedure until whatever criteria you designate are reached. For a very simple example:
to move-until
ask turtles [
let start-patch patch-here
let destination patch-ahead 10
while [ distance destination > 1 ] [
fd 1
]
]
end
Obviously you will have to modify that to suit your needs, but it should get you started.

Game of Life , NetLogo i Extend my neighbors to 24 cells using in-radius

Here is the code :
to new_neighbor
set my-neighbors (other patches) in-radius 2
end
to go
ask patches
[ set live-neighbors count my-neighbors with [living?] ]
;; Starting a new "ask patches" here ensures that all the patches
;; finish executing the first ask before any of them start executing
;; the second ask. This keeps all the patches in synch with each other,
;; so the births and deaths at each generation all happen in lockstep.
ask patches
[ ifelse live-neighbors = 3
[ cell-birth ]
[ if live-neighbors != 2
[ cell-death ] ] ]
tick
end
Here is the error:
COUNT expected input to be an agentset but got the number 0 instead.
Error while patch 30 -31 running COUNT
called by procedure GO
called by Button 'go-once'
I just want to extend my neighbors to 24 cell. Nothing else. I want program to check not first 8 cells ring but 24.
Thank you.
Look in the Models Library (File menu). In the Code Examples section, there is one called 'Moore & von Neumann Example'. That does exactly what you want.
For your error, there were no patches in my-neighbors. Your code doesn't include any section that actually sets the my-neighbors variable, so it's unclear why it was empty. That is, what bit of code actually calls the procedure new_neighbor?

Why is NetLogo's in-radius so slow, is there a faster way around it?

I was finding my model was running very slow and I narrowed it down to an in-radius command that the turtles are running. The bottom line is that out of the two procedures below, test1 checks [var] of every patch but runs faster than test2 which should only check a small subset of 8 patches.
set patches-of-interest (patch-set patches with [var > 1])
to test1
ask min-one-of other patches-of-interest with-max [var][distance myself][set pcolor red]
end
to test2
ask min-one-of other patches-of-interest in-radius 1.5 with-max [var][distance myself][set pcolor yellow]
end
You can check their speeds using the Profiler extension and the following code:
profiler:start
repeat 100 [
ask one-of turtles [test1 test2]
]
profiler:stop
print profiler:report
profiler:reset
Firstly, why is test2 running slower? And secondly, is there an alternative to test2 which does approximately the same thing but more efficiently?
I found a couple discussions on the Netlogo list about this but they're a bit old so may be out of date:
https://github.com/NetLogo/NetLogo/issues/402
http://netlogo-users.18673.x6.nabble.com/Re-in-radius-efficiency-question-td5003840.html
EDIT: I left out that in my model I'm actually using a patch-set not the full "patches". I've updated the code example above, but Bryan already partially explained the reason for the slowdown in the comments. Bryan is right that if using all patches, test2 is much faster, but I haven't been able to subset the patches in advance or within the two tests without slowing down test2.
#bryan-head gave the reason for why the code is slow (in-radius checks on patch-sets cannot be optimized). I assume this is something internal to Netlogo's code.
However, I did finally find a work around that speeds things up and has the same effect so I thought I'd post it. First add the patch variable binaryvar then,
ask patches [ifelse var > 1 [ set binaryvar 1][set binaryvar 0]
to test3
ask min-one-of other patches-of-interest in-radius 1.5 with-max [var * binaryvar][distance myself][set pcolor yellow]
end
Of course this still fails if all the cells in-radius also have var = 0...