Netlogo, Finding the parent of the hatched breed - netlogo

I am trying to find out when you use the hatch- function how to form link between the parent and the breed it creates. Or is there already a link that I am not aware of.
For example, there are two breeds lets say yellow bees and red bees. The yellow bees travel a certain distance and when they come to a certain point (hive), they hatch x no of red-bees. I want to transfer the distance traveled by the yellow bees to the red bees it creates (from parent to its children). But there is no way of doing this since there is no link between yellow bees and red bees it creates.
i.e (yellow-bee 22 hatches red-bee 15 and red-bee 72) while yellow-bee 77 hatches red-bee 26). If yellow bee traveled 17m, I want red bee 22 & 15 to inherit that info. And red bee 26 to inherit the distance yellow-bee 77 has traveled (i.e 19m)
Note: ideally I am thinking its better not to use in-radius command to find the red-bees around the yellow-bees. Because if two yellow bees arrive at the hive at the same time and creates two sets of red bees. If they use in-radius to find the red bees around them, they might mix up
breed [yellow-bees yellow-bee]
breed [red-bees red-bee]
yellow-bees-own [distance-traveled no-of-red-bees]
red-bees-own [transfered-distance]
to go
....
ask yellow-bees[
if current-node node-at-hive[
hatch red-bees no-of-red-bees [set color red]
]
set transfered-distance [distance-traveled] of ....(;this is where the
agent-set (red-bees) should be added
]

The documentation of hatch says that:
Each new turtle inherits of all its variables, including its location, from its parent.
In other words, hatch already does what you want. You just have to make sure that the variable you want the child to inherit (in this case, distance-travelled) has the same name as in the parent's breed.
Here is an example:
breed [ yellow-bees yellow-bee ]
yellow-bees-own [ distance-travelled ]
breed [ red-bees red-bee ]
red-bees-own [ distance-travelled ]
to setup
clear-all
create-yellow-bees 1 [ set distance-travelled 10 ]
create-yellow-bees 1 [ set distance-travelled 20 ]
ask yellow-bees [ hatch-red-bees 1 ]
ask turtles [ show distance-travelled ]
end
The output of which will be something like:
observer> setup
(red-bee 3): 20
(red-bee 2): 10
(yellow-bee 0): 10
(yellow-bee 1): 20
As you can see, the two red bees inherit their distance-travelled value from their parents.

Related

Netlogo set specific xycor

This is my first Netlogo script and I am a complete beginner and need help in setting the xy coordinates for my turtles which are boats. I wish the boats to be positioned across the top of the world (in a 30 x 30 world, with origin in the bottom left-hand corner). The number of boats is selected by a slider, ranging from 1 to 4. After looking at other questions & answers, I have tried the following code, but cannot get it to work, either "expected closing bracket" or "FOREACH expected at least 2 inputs, a list and an anonymous command" errors.
create-boats N-boats ;; create the boats
[set color red ;; give them a color, a size and shape
set size 1
set shape "arrow"
(foreach [ 0 1 2 3 ] [6 12 18 24] [28 28 28 28] [ xy -> boats [ setxy item 0 xy item 1 xy ] ] )
set heading 180]]]
I also tried "set xcor one-of [6 12]", but sometimes get the boats lined up on top of each other, so I wish to specify the exact coordinates. Many thanks.
Do they have to be equally spaced? Or just anywhere along the top? If anywhere along the top, you are better off choosing 4 random patches in that row and getting each of them to sprout a boat. Something like (not tested):
ask n-of N-boats patches with [pycor = max-pycor]
[ sprout 1
[ set color red
set heading 180
set shape "arrow"
]
]
Just as a general newbie tip with NetLogo, if you are using foreach then you should immediately think about whether what you really want is some sort of agentset. It's particularly common for people coming from some other coding background to try and do things in for loops that are better handled as agentsets in NetLogo.
First, to answer your syntax issues:
Remember that the code in brackets after CREATE-TURTLES is run by a single turtle. After all the turtles are created, each turtle runs the code, one-at-a-time. It looks like you're trying to position all the turtles. That's probably not what you meant.
Second: look at the FOREACH.
( foreach [ 0 1 2 3 ] [6 12 18 24] [28 28 28 28] [ xy -> boats [ setxy item 0 xy item 1 xy ] ] )
You've got the foreach in ( and ) -- that's good.
You've got THREE separate lists as input -- that's fine, too, but looks like maybe you meant that to be one list? Not sure.
Your anonymous procedure has only ONE input: xy. That's a problem, since you have THREE lists as input.
You are referring to ITEM 0 and ITEM 1... which doesn't make a lot of sense at that point, unless you passed a list of lists, but no... still not.
Finally, it looks like you meant to ask boats but if you did, since this is inside the create-turtles code block, this is already being excuted by a boat. So, this boat will ask all boats to do something. If this was otherwise correct, you'd just do the boat commands--you are essentially already inside an "ask".
So, this is not ideal, in any case. Let's start at the top.
Three Ways to Set Turtle Location
If you want to put turtles at specific x and y coordinates, you have a few choices. Here's three:
Use Math based on the value of WHO to calculate the coordinates.
(Or a counter, if you want to keep your model "who-agnostic")
Use a set of patches (probably created using Math, too.) The patches SPROUT the turtles.
Use a List of coordinates. Each turtle pulls its location from the list.
A Note on the Examples.
All the below examples focus on setting the position. After the boats
are created, the boats are asked to run a procedure called
apply-boat-properties, which is where things like color, heading,
size, and other properties would be set. This is to remove clutter
from the examples. It also makes it quite easy to find where the
properties are being set.
to apply-boat-properties
;; run by a boat
set heading 180
set shape "arrow"
set color gray
end
Math (aka "calculated position")
You can do this is the locations are in a pattern that can be calculated. This can be easy to do, but can also be hard and require a lot of tweaking and experimentation to get just right. The weird NetLogo world geometry can sometimes be confusing.
Simple Example of Calculated Positioning
to make-fleet [ #fleet-count ]
create-boats #fleet-count
[ setxy (min-pxcor + 6 + who * 6) max-pycor
apply-boat-properties
]
Elaborate Example of Calculated Positioning
Varies the gap between boats automatically.
The boats are located without regard to patch centers,
unless "$center-on-patches?" is set to true
WHO is not used in the calculations. This ensures the math comes out right, even if other turtles already exist in the model.
to make-fleet [ $fleet-count $center-on-patches? ]
;; requires breed [ boats boat ]
set-default-shape boats "arrow"
let $boat-size 1
;; this is the real "0" in terms of even positioning
let $far-left-edge-xcor min-pxcor - 0.5
let $total-width-of-all-boats ($boat-size * $fleet-count)
let $gap-between-boat-edges (world-width - $total-width-of-all-boats) / ($fleet-count + 1)
let $gap-between-boat-centers $gap-between-boat-edges + $boat-size
let $gap-between-left-edge-and-first-boat-center $gap-between-boat-edges + ($boat-size / 2)
;; I use boat-number, rather than who,
;;so this procedure will work even if there are other turtles
let $boat-number 0 ;; 0 to (#fleet-count - 1)
create-boats $fleet-count
[ let $x 0
if-else ( $center-on-patches? )
[ set $x min-pxcor
+ floor ( $gap-between-left-edge-and-first-boat-center )
+ ceiling ( $boat-number * $gap-between-boat-centers )
]
[ ;; position without regard to patch alignment
set $x $far-left-edge-xcor
+ $gap-between-left-edge-and-first-boat-center
+ $boat-number * $gap-between-boat-centers
]
let $y max-pycor
setxy $x $y
set $boat-number $boat-number + 1
]
ask boats [ apply-boat-properties ]
end
Using a Set of Patches
This is a lot like the previous method, but we create a set of patches, then ask the patches to make the turtles. This is useful for creating a set of turtles on a specific area of the world, like on an edge, or in a specific pattern of patches, or filling an area with a randomly scattered set of turtles.
to make-fleet [ $boat-gap ]
let $locations patches with
[
;; rules to find the patches
pycor = max-pycor ;; top row
and
(pxcor - min-pxcor) mod $boat-gap = 0
]
ask $locations [ sprout 1 [ set breed boats ] ]
ask boats [ apply-boat-properties ]
end
Using A List of Coordinates
If the required coordinates are few, or are can't be calculated, you can put the coordinates in a list. The created turtles can pull the coordinates from the list.
to make-fleet [ $fleet-count ]
;; A list of x y coordinate pairs.
;; The coordinate pairs are also in a list
let $coordinates
[
; x y ;
[ 6 0 ]
[ 12 0 ]
[ 18 0 ]
[ 24 0 ]
]
;; initialize the counter uses as the list index
let $boat-number 0
;; make boats
create-boats $fleet-count
[ ;; get the coordinate pair
let $xy item $boat-number $coordinates
;; get the x and y from the pair
let $x first $xy ;; aka item 0 $xy
let $y last $xy ;; aka item 1 $xy
;; apply the coordinate
setxy $x $y
;; increment the index number
set $boat-number $boat-number + 1
]
ask boats [ apply-boat-properties ]
Note that the above will make errors if $fleet-count is more than 4, because the coordinate list has only 4 items.
You could use FOREACH on the list, and create 1 turtle for each coordinate. This is handy when a large list of coordinates have been read from a file.
to make-fleet [ $coordinates ]
;; assume $coordinates is a list of pairs of coordinates.
;; like [ [ 1 2 ] [ 3 4 ] [ 5 6 ] ]
;; we are going to ask the patch at each of the coordinates
;; to create a turtle. Then we will set up the turtle.
( foreach $coordinates
[ [ $xy ] ->
ask patch first $xy last $xy
[ sprout 1 [ set breed boats ] ]
]
)
ask boats [ apply-boat-properties ]
end
Finally
There are other ways, too, and many other formulas for calculated positions.

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

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.

n-of or one-of turtles is not working as expected when working with turtles individually

I have 200 turtles which represent producers. Each turtle, has 2 variables (sales of 2 prodcuts) and they are compared to let the prodcuer know which product was the most popular, so the turtle's color changes to the color representing that product.
I defined this loop :
while [counter < 201][
ask n-of 1 producers [
if (product1sales > product2sales)
[
set color green
]
if (product2sales > product1sales)
[
set color red
]
;
set counter counter + 1]
]
I assumed each time n-of is called, one turtle is chosen, but this specific turtle will not be chosen again. I also assumed that by running the code, all the turtles must be either green or red, but some are neither green nor red since n-of is not working as I assumed. one-of is not doing what I want either. Any ideas?
Thanks
If you just ask producers it will ask all of the producers in a random order, but without repeating- if you just want all of them to make a choice between the two choices you wouldn't even need the counter.
If either product1sales or product2salesis always higher, you could also trim a little by using ifelse. See if the example below would give you what you need:
breed [ producers producer ]
producers-own [ product1sales product2sales ]
to setup
ca
reset-ticks
create-producers 200 [
setxy random 30 - 15 random 30 - 15
set product1sales random-float 11
set product2sales random-float 11
set color white
]
end
to choose
ask producers [
ifelse product1sales > product2sales [
set color green
]
[
set color red
]
]
end

Netlogo: ask turtle to reproduce after it completes a procedure, and ask new turtle to repeat that procedure for itself

I'm new to NetLogo and am attempting to model home range selection of subsequent colonizers. The model should follow simple steps:
Individual 1 picks a home range (a subset of patches).
When individual 1 is done picking its home range, it hatches new
individual 2.
Individual 2 picks a home range, then hatches individual 3.
Individual 3 picks a home range, and so on.
I'm having trouble figuring out how to get this to work. I can get the first turtle to pick a home range. But the offspring do not. Writing the code numerous ways has only accomplished two unintended outcomes. Either endless new individuals are hatched simultaneously, before the first turtle has a home range, and the new turtles fail to pick a home range. Or, the first turtle picks its home range and hatches a new turtle, but that new turtle doesn't pick a home range. Neither outcome is what I want.
How do I set this up to run as intended, so that hatchlings pick home ranges too? Here is one simplified version of my code:
to setup-turtles
crt 1
[setxy random-xcor random-ycor]
end
to go
ask turtles [pick-homerange]
tick
end
to pick-homerange
while [food-mine < food-required] ;; if not enough food, keep picking patches for home range
[;; code to pick home range until it has enough food; this is working okay
]
[;; when enough food, stop picking home range
hatch 1 fd 20 ;; now hatch 1, move new turtle slightly away
]
end
So it is at this last part, once the home range is built, that I want a new turtle to hatch from its parent. I then want that turtle to repeat the pick-homerange procedure. How could that be coded to happen? I've tried writing this every way I can think of; nothing is working. Thanks in advance for any assistance!
One way to do this is to have each patch equal one "food value", and have turtles grow their home range until their home range supplies them with enough food. I would set this up so that patches "know" to which turtle they belong, and so that turtles know how much food they need, which patches are part of their home range, and the food supplied by their homerange. Example patch and turtle variables would then be:
patches-own [
owned_by
]
turtles-own [
food_required
my_homerange
homerange_food
]
Then, your turtles can add patches into their home range until they hit their "food_required", whatever you set that as. For simplicity, in this example I assume that turtles are territorial and so won't "share" home ranges. Further explanation of steps is commented in the code below. This is intended just to get you started- for example, it will hang if you run pick-homerange too many times.
to setup-turtles
crt 1 [
set size 1.5
setxy random-xcor random-ycor
set food_required 5 + random 5
set homerange_food 0
set my_homerange []
]
end
to pick-homerange
ask turtles [
;; Check if the current patch is owned by anyone other than myself
if ( [owned_by] of patch-here != self ) and ( [owned_by] of patch-here != nobody ) [
;; if it is owned by someone else, move to a new patch that is not owned
let target one-of patches in-radius 10 with [ owned_by = nobody ]
if target != nobody [
move-to target
]
]
;; Now add the current patch into my homerange
ask patch-here [
set owned_by myself
]
set my_homerange patches with [ owned_by = myself ]
;; calculate the number of patches currently in my homerange
set homerange_food count patches with [owned_by = myself]
;; Now grow the homerange until there are enough patches in the homerange
;; to fulfill the "food_required" variable
while [ homerange_food < food_required ] [
let expander one-of my_homerange with [ any? neighbors with [ owned_by = nobody ] ]
if expander != nobody [
ask expander [
let expand_to one-of neighbors4 with [ owned_by = nobody ]
if expand_to != nobody[
ask expand_to [
set owned_by [owned_by] of myself
]
]
]
]
;; Reassess homerange food worth
set my_homerange patches with [ owned_by = myself ]
set homerange_food count patches with [owned_by = myself]
]
ask my_homerange [
set pcolor [color] of myself - 2
]
;; Now that my homerange has been defined, I will hatch a new turtle
hatch 1 [
set color ([color] of myself + random 4 - 2)
]
]
end