How to 'track' a turtle? - netlogo

I would like to track a turtle created as follows:
time 0: turtle 1 creates a new turtle - object - using hatch-
time > 0: the object created is added to the list of a new turtle, turtle 2;
time > 0: turtle 2 wants to share this object with a new turtle, turtle 3. The object is then added to turtle 3's list ...
The turtle to track is the object. I thought about visit a path/link or changing color to the turtle created (for example, ask this-object [ set color red ]), but I am hiding the turtle, so it does not make sense.
Do you have any idea on how I can track the path of this turtle within the network? (you can think of a car that has an accident, but the driver does not stop, continuing driving and it has a new accident ...
What I would like to track are not only the accidents, but also the cars that have caused them, if it possible.
I hope you can help me.
Thanks

You have now asked essentially the same question at least 10 times in slightly different ways. It's clear that none of the answers have answered your question, but it's also clear that you aren't understanding any of the answers. While I would normally ask you to post what you have tried so far, it's probably best to start from the beginning.
Here is a complete model that does what you want. I have put print statements at key points so that you can see that it does what you want.
breed [people person]
people-own
[ my-objects
]
breed [objects object]
objects-own
[ my-people
]
to setup
clear-all
create-people 5
[ setxy random-xcor random-ycor
set color red
set my-objects []
]
ask one-of people
[ hatch-objects 1
[ set color blue
set my-people (list myself)
let child self
ask myself [ set my-objects (list child) ]
]
]
reset-ticks
end
to go
ask one-of objects [move-object]
tick
end
to move-object
let target one-of people
while [target = first my-people] [set target one-of people]
let this-object self
ask target
[ type self type " Objects old: " print my-objects
set my-objects fput this-object my-objects
type self type " Objects new: " print my-objects
]
type self type " Owners old: " print my-people
set my-people fput target my-people
move-to target
type self type " Owners new: " print my-people
end
If you want to make any progress on your code, you need to completely understand this model first. Don't just copy the relevant bits into your code and try to amend. Instead, make a new NetLogo model for this code and understand every line - what it does, how it works. Once you understand it, you can then use the concepts and approach in your own model.

Related

How to create turtles that create (or are owner of) objects with specific attributes?

The code below should select a random turtle (selected) and let it create an object with attributes (size, shape). selected is a local variable, objects is a breed; new_object and size are objects-own.
The reason why I am considering a breed for the objects is that I want to monitor these objects within the network through time. In my code, size and shape of the object should have the same value of selected's size and shape. Probably there will be another way to do what I am trying to do, more efficient and correct than mine.
let selected nobody
set selected one-of turtles with [breed = engineersA or breed = engineersB]
if empty? [my-list] of selected [
ask selected [
set size random-float 1
]
create-objects random 10[
hide-turtle
set new_object self
set size [size] of selected
set shape [shape] of selected
]
set my-list fput new_object my-list
]
new_object in my-list should still keep information about size and shape.
The schema that I should follow is:
select a random turtle
for this turtle, create a new object with specific attributes (size and shape)
put this object, keeping its attributes, into the turtle's list
Since I have had some issues in plotting the objects (when I want to distinguish between objects created by engineersA and objects created by engineersB), I wanted to ask your help to better understand how to create turtles that are owner of objects/items.
Any suggestions and/or comments would be greatly appreciated.
Thanks
You didn't say what your problem is. But there are three ways to create turtle agents. Look at create-, sprout- and hatch-. In this case, you want hatch because that is the way a parent turtle creates a child turtle with the same attribute values. Do hatch-objects instead of create-objects. That also specifies the breed of the child turtles.
Does this do what you want? It inherits size and shape from the parent and uses myself to refer to the parent turtle.
ask one-of turtles with [breed = engineersA or breed = engineersB]
[ if empty? my-list
[ set size random-float 1
]
hatch-objects random 10
[ hide-turtle
let this-object self
ask myself
[ set my-list fput this-object my-list
]
]
]

How to give a score when an element is pulled out from a list?

I would like to implement a part of code where agents can get a score when they pick an element from a list generated from a specific turtle.
I set
breed [playersA playerA]
breed [playersB playerB]
breed [balls ball]
playersA-own[
my-list
new_ball
score
]
playersB-own[
my-list
new_ball
score
]
to setup
clear-all
create-playersA 10
ask playerA 0 [ create-links-with other playersA ]
ask playerA 2 [ create-link-with playerA 1 ]
create-playersB 10
ask playerB 0 [ create-links-with other playersB ]
ask playerB 2 [ create-link-with playerA 1 ]
ask playersA[
set my-list []
set score 0
]
ask playersB[
set my-list []
set score 0
]
end
to go
let selected nobody
let team-player nobody
set selected one-of turtles with [breed=playersA or breed=playersB]
ifelse [breed = playersA] of selected[
ask selected [
set size [count link-neighbors] of self
show size
]
create-balls 1[
hide-turtle
]
]
[ ask selected [
set size [count link-neighbors] of self
show size
]
create-balls 1[
hide-turtle
]
]
set team-player link-neighbors with [breed = playersA]
ask team_player [
set my-list lput my-ball my-list
]
end
The above code should select on random turtle and add a new ball to its neighbours list. What I would need is probably a counter that can compute how many balls were shared between players.
Could you please help me to figure out with it?
Thanks
The code you posted has many problems that prevent it from passing error-checking in the editor. Some of these produce surprising error messages that don't even make sense, and they happen because the logic mixes contexts -- that is, some commands make sense for the "observer" level, some require being in a "turtle" context, etc.
I think you are trying to do too much at once, and trying to add a counter to code that already does not work. First you have to fix the code you have and then you can see where to add a counter.
You absolutely must understand how the unique agent id number "who" works. Each turtle has a unique who number assigned, starting with zero. It doesn't matter whether the breed of turtle is playerA or playerB or a ball, it will have a unique number. Once you create your first 10 turtles, of the PlayerA breed, they will have who numbers 0 through 9. Then, when you create the next 10 turtles, of PlayerB breed, they will get assigned who numbers of 10 through 19. If you then create a ball, say, it will have a who number of 20.
So there will never be a PlayerB with a who number of 0 or 1 or 2. Those numbers will already be used by PlayerA. Your setup will crash with the error:
playera 0 is not a PLAYERB error while observer running PLAYERB
called by Command Center
Even with just PlayerA, it is not clear what kind of network you want to build in the setup code. Why would everyone link to player 0, but then also add a single link between player 1 and player 2? Since players only "see" their linked team-mates, only player zero will see everyone else. Other players will have only one or two link-neighbors, so they will never update everyone else's my-lists.
create-playersA 10
ask playerA 0 [ create-links-with other playersA ]
ask playerA 2 [ create-link-with playerA 1 ]
Anyway, I would suggest that you get this much working correctly before trying to add counting.
I don't think you can do that by just looking at the code. You need to get rid of as much complexity as you can, and then use shapes, colors, and numerous print statements to see whether each command is doing what you think it should do. Complex working code almost always evolves from simple working code.
So get rid of PlayersB entirely ( comment out the code ), only create 5 players A, and change the colors and shapes as you process each step to confirm that it is working. The editor lets you use ctrl-; to comment out entire blocks of code, or un-comment them at once, so comment out everything you possibly can while you are getting one step to work, then uncomment the next section, get that to work, etc.
When you finally get everything working, you can comment out all your print statements that you used in development.
Anyway, I refactored your code, added many comment, and added many print statements, and finally got it to run. If you run just setup and look at the view, you will see what I mean about the network. ( I shut off wrapping in the view so the network looks right.)
Here's my revision of your code. It prints out what is in each player's my-list after each step, so you can see at a glance if it is doing what you want, or not. ( It's not.)
I added the who numbers as a label to each player in the view so you can see what I mean.
It produces helpful output like:
let's confirm that the lists have been updated. Here's the my-lists
for playersA [[5 5 5 5 10] [0 0 0 0 0] [0 8 8] [0 0] [0 9]]
Get the setup step to work correctly and generate the network you want before you even try to fix the go section.
breed [playersA playerA]
breed [playersB playerB]
breed [balls ball]
playersA-own[
my-list
new_ball
score
]
playersB-own[
my-list
new_ball
score
]
to setup
clear-all
;; for debugging, only create 3 players and inspect the results to confirm it's working as you intended
;; use labels to see player numbers in the view
create-playersA 5 [ set size 1 set color blue set shape "square" setxy random-xcor random-ycor set label who]
ask playerA 0 [ create-links-with other playersA [set color blue]]
ask playerA 2 [ create-link-with playerA 1 [set color red]]
create-playersB 5 [ set size 2 set color yellow set shape "person" setxy random-xcor random-ycor set label who]
; comment out this code until create-playersA is working properly
; ask playerB 0 [ create-links-with other playersB ]
; ask playerB 2 [ create-link-with playerA 1 ] ;; copy-and-paste error? link with playerB intended?
ask playersA[
set my-list []
set score 0
]
ask playersB[
set my-list []
set score 0
]
reset-ticks
end
to go
let selected nobody
let team-players nobody
let hot-ball nobody
set selected one-of turtles with [
breed = playersA
;; or breed = playersB ;; always select one of playersA for debugging this code
]
print ( word "At point 1, we selected turtle " [who] of selected " with breed " [breed] of selected)
;; we're still in the observer context here
ifelse [breed = playersA] of selected [ ;; by mentioning breed, we shift into a turtle context silently
print ( word " entering the TRUE part of the if-else statement " )
ask selected [
set size [count link-neighbors] of self
print ( word "at point 2 we set selected player's size to " size )
]
create-balls 1 [
set shape "circle" set size 3 set color blue set label who
set hot-ball who
; hide-turtle ;; for debugging show it so you can click on it and inspect it
print ( word "at point 3 we set created a blue hot-ball with who= " hot-ball )
]
;; it seems you want to update the selected turtle's my-ball variable here with a reference to the ball just created??
print " at point 4 we should set selected agent's my-ball to the ball we just made..."
ask selected [
set new_ball hot-ball
]
print (word " Confirming that selected player got the hot-ball " [new_ball] of selected )
;; ask ball hot-ball [ set hidden? true ]
;; this set of code seems to apply only when selected turtle is one of playersA, so it was moved INSIDE that ask-selected code
;; and put inside another ask selected [ ] context
ask selected [
set team-players link-neighbors with [breed = playersA]
print (word "At point 5, For selected player " who ", here is the team-players agent set :" )
print (sort team-players) ;; using "sort" here just to convert an agent set to a list for display
]
print " ------------- about to ask team-players to update their my-lists and change to triangles ---"
ask team-players [
set shape "triangle" set size 3 ;; to see at a glance that everyone was processed
set my-list lput new_ball my-list
print "... updated one my-list"
]
print " let's confirm that the lists have been updated. Here's the my-lists for playersA "
print map [ i -> [my-list] of i ] sort playersA ;; using "sort" to convert agent-set to a list
print (word "At the end of the go step, we have this many balls: " count balls)
]
;; else we should have breed != playersA
[
error " we should only be looking at one of playersA here for testing" ;; for debugging
]
;; tick
end

Create a new item and add it to my neighbours's lists

I would like to ask how I can add an element created by one turtle to its own list and its neighbour's lists.
I created a local variable, neighbours, defined as turtle-set in-link-neighbors with [breed=breed1]. Then I asked neighbours to add the element created (new_elem), following an answer provided me by an user in this forum.
The code is:
to create_elements
create-elements 1[
set person one-of turtles with [breed = breed1 or breed = breed2]
ifelse [breed = breed1] of person
[
set attribute1 random-float 1
set attribute2 random-float 1
set function1 (1 + attribute1)
]
[
set attribute1 random-float 1
set attribute2 random-float 1
set function2 (1 - attribute1)
]
let neighbours (turtle-set self in-link-neighbors with [breed = breed1] of person)
ask neighbours
[set my-list fput new_elem my-list]
]
]
end
I know that there is an error in let neighbours (turtle-set self in-link-neighbors with [breed = breed1] of person)..., but also in putting an element in the list, as I think the new element is defined in the breed elements. In fact, the error message says that
elements breed does not own variable my-list
Would it be possible to specify the breed of the turtle-set? What I would need is consider only breed1 and breed2, not elements breed.
For example, since I am considering person as creator of the element, is it right to write
let neighbours (turtle-set person in-link-neighbors with [breed = breed1] of person)
ask neighbours
[set my-list fput new_elem my-list]
And if it would be correct, how can I add a new element as "New element" to the list, taking into account its attribute for further consideration.
For example: set my-list fput (list attribute1 attribute2) of elements my-list) returns me list of values like (0.134531 0.14141) (0.91844 0.42176) ... Any suggestions to have something nicer to see but with the same information? I will need to keep track of this values in the next steps.
I hope you can shed some light on what I am doing incorrectly.
Thanks
Val, here's some working code that creates a new element and updates everyone's my-list.
It's probably not exactly what you wanted but I hope it provides some help anyway.
You didn't include all the info on breeds and who owns what so I punted.
I broke up more complex commands into multiple shorter ones in order to debug what was going on and where it was breaking down. I added some print statements.
If you load this up, run setup, and hit "go" once, you can see agents in a network linked up with their "who" numbers besides them so you can easily inspect the ones you
want. Values of my-list are also printed out in the command section.
Two more iterations of the "go" step should verify that they are outputting what you wanted.
I didn't know whether you wanted new_elem to be just local to the create_elements section, of if you wanted it globally available, so I put comments in both places.
I hope this helps! There are more comments in the code itself. Note especially that you must initialize my-list as an empty list, or it will default to the number zero, and your fput statement will fail with a comment about expecting a list and finding zero.
globals [
;;new_elem ;; might be needed as a global ??
]
;; ///////////////////// note that there is no breed required called "people"
breed [ elements element]
breed [ breed1 lion ]
breed [ breed2 tiger ]
;; ///////////////////// i punted on which entity owned "function1 and function2
breed1-own [ attribute function1 function2 my-list]
breed2-own [ attribute function1 function2 my-list]
to setup
clear-all
;; make some turtles with breed = breed1 (say, red lions)
create-breed1 2 [ set size 2 set shape "circle" set color red
setxy random-xcor random-ycor
]
;; make some turtles with breed = breed2 (say, green tigers)
create-breed2 2 [ set size 2 set shape "circle" set color green
setxy random-xcor random-ycor
]
;; //////////////////////////////////////////////////////////////////////////
;; NOTE!!! If you don't initialize my-list to an empty LIST type,
;; fput will generate an error when you try to fput a new element onto it
;; this is ugly but fast:
ask breed1 [create-links-with other breed1
set my-list [] ]
ask breed1 [create-links-with breed2
set my-list [] ]
ask breed2 [create-links-with other breed2
set my-list [] ]
ask breed2 [create-links-with breed1
set my-list [] ]
ask turtles [set label who] ;; ///////////////////////// for debugging
;; set new_elem nobody ;; this could be a global so it can persist
;; outside create_element, in which case
;; initilize it here
reset-ticks
end
to go
create_elements
tick
end
to create_elements
;; declare the local variables, all agent-sets of some type
let new_elem nobody ;; declare this locally if we don't need to persist it
;; outside the create_elements context
;; and remove the declaration in [ globals ]
;; and initializtion in setup
let personx nobody
let xx-neighbors nobody
;; do just this creation here in order to see what's going on more easily
;; than combining multiple operations into a long complex command
create-elements 1 [ set new_elem self ]
type "new element is this agentset " show new_elem
set personx one-of turtles with [breed = breed1 or breed = breed2]
ifelse [breed = breed1] of personx
[ ;; if it is breed1
ask personx [
set attribute random-float 1
set function1 (1 + attribute)
]
]
[ ;; else, it must be breed2
ask personx [
set attribute random-float 1
set function2 (1 - attribute)
]
]
;;//////////////////////////////////////// for debugging
type "the personx we defined above is " print personx
ask personx [set xx-neighbors (turtle-set self in-link-neighbors )]
if-else xx-neighbors != nobody ;; If it has any members, which should
;; always be true since we added self to the set
[
ask xx-neighbors
[
set my-list fput new_elem my-list
;; ////////////////////////////////////for debugging
type "here's the resulting my-list: " show my-list
]
]
[ print "ERROR didn't find any neighbors or self" ]
end

Selecting an item from a list in Netlogo

I'd need to pick an object in a bag containing 20 elements with attributes c (color) and s (size). Both color and size are numbers (e.g. c= {red = 256, black = 0, ... } = {256, 0, ...}).
As in Python I'd use random.choice in numpy library, I found on the web that the corresponding function in Netlogo is the extension rnd.
Struggling along a possible solution, I did
Edited:
breed[people person]
people-own
[
ball
size
color
bag
]
to setup
create-people 5
[ set color gray
setxy random-xcor random-ycor
]
ask people[
set bag [ ] ; 0 items
]
end
To create the balls:
to create-balls
set color random 300 ; color
set size random-float 5 ; size
let this-ball self
ask one-of people [ ; ask one of people to put the ball created into the bag
set bag fput this-ball bag ; add ball to the bag
]
end
The code below should include the part of drawing:
to draw
ask one-of people [
rnd:weighted-one-of bag [ ] ; I do not know what I'd write in the brackets
]
end
As you can easily see, I've many doubts about how to implement the code.
How can I select one item from the bag depending on its size (or color)?
Can you please help me out with it?
Here is a complete model that creates people and balls as turtle agents and has 30 of the balls get chosen weighted by their size. It then opens an inspect window for the person who has chosen the most balls.
extensions [rnd]
breed [people person]
people-own [ my-balls ]
breed [balls ball]
balls-own [ chosen? ]
to setup
clear-all
create-people 20
[ setxy random-xcor random-ycor
set my-balls (turtle-set nobody)
]
create-balls 50
[ hide-turtle
set size one-of [1 2 3 4 5]
set color one-of [red white blue yellow]
set chosen? false
]
repeat 30 [draw-ball]
inspect max-one-of people [count my-balls]
end
to draw-ball
ask one-of people
[ let bag-of-balls balls with [not chosen?]
let choice rnd:weighted-one-of bag-of-balls [size]
ask choice [set chosen? true]
set my-balls (turtle-set my-balls choice)
]
end
Some things to notice:
There are NO lists in this code. There are situations where you should use lists. Common uses include memory where the order is important (eg you only want to keep track of the last 5 other people seen) or where the same agent can appear multiple times. And the list commands are very powerful. However, unless you need a list then you should use agentsets.
Each person has their own bag called 'my-balls' that contains the balls they select. That is initialised as a turtle-list as part of the setup.
I used a variable called 'chosen?' that is owned by each ball to track whether it is still in the bag for the next person to choose. Then the bag-of-balls is created only as all the balls not yet chosen.
The code for weighted random choice (when choosing from agentsets) simply has the name of the variable holding the weight as the reporter, but you could use some function such as rnd:weighted-one-of bag-of-balls [size ^ 2] if you wanted a more complicated weighting scheme.

Netlogo one-to-one relation

I have a netlogo problem for which I can't seem to find a solution, but yet it feels very basic.
I have two types of breeds:
breed [individuals individual]
breed [cars car]
I want to create a link from one individual to one car. So, its a one-one relation. I use this code to do that:
to setup-individuals
create-individuals individuals-number [
set ID 2
set shape "person"
set color yellow
setxy random-xcor random-ycor
set activity ""
set activity_time 0
let rand random 2
ifelse rand = 0
[
set owns-car false
]
[
set owns-car true
create-link-to one-of cars ;; here is the issue
]
]
end
The problem is that if i use "create-link-to one-of cars" there are more than one individuals linked to one car, but I want each individual to have a distinct car. When trying the following command: "create-link-to one-of cars with [my-in-links = 0]" its giving me the following ERROR: "CREATE-LINK-TO expected input to be a turtle but got NOBODY instead." I tried many variations of this command, but its not working.
Your attempted solution of create-link-to one-of cars with [my-in-links = 0] is on the correct path. However, if you look at the NetLogo dictionary, you will see that my-in-links returns an agentset, not an integer giving the number of members of that agentset. So you need to compare to empty rather than compare to the number 0.
This is the code that is syntactically closest to what you have: create-link-to one-of cars with [count my-in-links = 0].
What you really want though is something more like create-link-to one-of cars with [not any? my-in-links]