1

Here is what I want to do:

  1. I want a team consists of 3 turtles in a group.

  2. All turtles need to store their own ID and teammatesID inside the variable called teammatesID. (Imagine you want to create a group, you will put your name and your friends' name in a list, that's why this variable need to store ownID, I am bad in explaning things..)

  3. Instead of just showing (agentset,3 turtles), I need them to be able to show all teammates ID.

  4. After they have gathered all 3 members, they will get teamID.

The problem here is I don't know how to make these turtles store their own ID and teammatesID in variable called teammatesID. In a group, they supposed to have 3 different members. These teammates are not supposed to be from the same group. And how to give them teamID after they get all members.

Here is my coding:

global
[ teamID]

turtles-own
[
  myID
  teammatesID
]

to setup
  clear-all
  set-default-shape turtles "arrow"
  create-turtles 10

  ask turtles [ set myID who]
  reset-ticks
  setup-group
end

to setup-group

   set teamID []
   let agent one-of other turtles
   let  nearestNeighbor one-of other turtles in-radius 1 
   set teamID = 0
   ask agent with [ teammatesID < 3]
   [ ask nearestNeighbor with [teammatesID < 3]
     [ ;set teammatesID = myID ; here is the problem, I need to make sure they did not save the same turtle in one group.
       show teammatesID]]

       ask agent with [teammatesID > 3]
       set teamID fput teamID teamID
        end

I appreciate your extra time here. Thank you.

linda
  • 117
  • 9
  • Can you clarify what you mean by "These teammates are not supposed to be from the same group? Are group and team different things here? – Luke C Sep 28 '18 at 21:17
  • From my coding, the condition stated is "turtles that have less than 3 members need to find other members". For example, turtle 1 and turtle 2 create a team, so in turtle 1's teammatesID should have his ID and turtle 2's ID, so does turtle 2, it has it's own ID and turtle 1 ID. BUT, both of them still need to find one more member, and both of them satisfy the condition I stated before, which is they both have less than 3 member, I don't want them end up finding the same turtle in their team, which will end up => turtle 1 has its own ID, and DOUBLE turtle 2 ID. I'm sorry for my bad explanation – linda Sep 29 '18 at 23:28

2 Answers2

4

If teams are random, I don't think you need a loop for this as ask will call the turtles in a random order anyway.

I think you should still make use of agentsets here as it makes certain things easier. For example, once turtles know their (agentset,3 turtles), you can easily query that agentset for the myIDs or whatever variable you're after.

I'm not entirely clear on the purpose of teamID so I may be off base here, but I don't think you want it as a global variable if the teamIDs are to be unique to each group of three turtles. You'll probably want it to be a turtles-own variable as well.

Here is an example that incorporates the above ideas. With this setup:

turtles-own [ myteamset teamID myID teammatesID ]

to setup 
  ca
  crt 10 [
    set myID who
    set myteamset nobody 
    set teammatesID [ ]
  ]
  setup-groups
  print remove-duplicates [teammatesID] of turtles
  print sort [teamID] of turtles
  reset-ticks
end

And the setup-groups procedure (more detail in comments):

to setup-groups
  ask turtles [
    ; If you don't have a team yet
    if myteamset = nobody [
      ; Make a temporary agent-set out of all other turtles that
      ; are also not yet part of a team
      let possible-teammates other turtles with [ myteamset = nobody ]

      ; If there are at least two more turtles, make a new team:
      ifelse count possible-teammates > 1 [
        ; Make a team out of myself and two possible teammates
        set myteamset ( turtle-set self n-of 2 possible-teammates )

        ; Make a temporary variable to pass on to my entire team
        ; (yourself included) for the team ids and the team members.
        ; Also, assign a random teamID to the whole team
        let ids sort [myID] of myteamset
        let teammmembers myteamset
        let tempteam random 1000
        ask myteamset [
          set teammatesID ids
          set myteamset teammmembers
          set teamID tempteam
        ]
      ] [
        ; If there aren't enough turtles to form a new team, 
        ; print a warning to the console.
        show "Not enough turtles to make a new team!"
      ]
    ]
  ]
end

Let me know if that's kind of what you're after, hope it helps.

Edit- As per your comments:

To get sequential team numbers, you can make use of a simple counter that gets assigned to a team and then incremented for the next one- modified setup-groups would look like:

to setup-groups
  ; Create a temporary variable to use as a counter
  let teamCounter 1
  ask turtles [
    if myteamset = nobody [
      let possible-teammates other turtles with [ myteamset = nobody ]
      ifelse count possible-teammates > 1 [
        set myteamset ( turtle-set self n-of 2 possible-teammates )
        let ids sort [myID] of myteamset
        let teammmembers myteamset

        ; Assign the current teamCounter as team number, then 
        ; increment it by one for the next team
        let tempteam teamCounter
        set teamCounter teamCounter + 1
        ask myteamset [
          set teammatesID ids
          set myteamset teammmembers
          set teamID tempteam
        ]
      ] [
        show "Not enough turtles to make a new team!"
      ]
    ]
  ]
end

The second question may be worth a new question on its own, depending on how in depth you're hoping to get, but here is one very simplistic approach where you just get all unique team IDs and have one turtle with that ID have their team move together:

to move-in-groups
  ; Get the unique team IDs
  let teamNumbers remove-duplicates [teamID] of turtles 

  ; Get one member of each team to ask all members
  ; of its team (itself included) to move 
  foreach teamNumbers [
    tn ->
    ask one-of turtles with [ teamID = tn ] [
      let newHeading heading + random 60 - 30
      if myteamset != nobody [
        ask myteamset [
          set heading newHeading
          fd 1
        ]
      ]
    ]
  ]
end

Edit 2: NetLogo 5-friendly version

to move-in-groups
  ; Get the unique team IDs
  let teamNumbers remove-duplicates [teamID] of turtles

  ; Get one member of each team to ask all members
  ; of its team (itself included) to move
  foreach teamNumbers [
    ask one-of turtles with [ teamID = ? ] [
      let newHeading heading + random 60 - 30
      if myteamset != nobody [
        ask myteamset [
          set heading newHeading
          fd 1
        ]
      ]
    ]
  ]
end
Luke C
  • 10,081
  • 1
  • 14
  • 21
  • Yes, yes, yes~! Oh my goodness, this is the one I plan to do, Thank youuu so muchh~! ヽ(^o^)ノThis seriously helped me so much. I have been racking my brain for a week to solve this. Btw, if I want to make the teamID as in 1,2,3..., how can I do it? And I want them to move in a group, how can I 'ask' them? – linda Oct 04 '18 at 09:04
  • @linda - Happy to help! I've made a few edits to potentially address your comments, but you may end up wanting to ask a new question if your movement needs are more in depth. – Luke C Oct 04 '18 at 18:03
  • Sorry for the late reply, in the `to move-in-groups` function, what is `tn` for? How can I set this variable? I have change `tn` into teamnumbers but I had problem in `to go` code.·´¯`(>▂<)´¯`·.·. Thank you for your time :D – linda Oct 08 '18 at 14:24
  • @linda - the `tn` variable is a temporary variable that only exists within the `foreach` block. You can't set it, it takes the place of the current **t**eam**N**umber that is being used as the `foreach` procedure iterates over each item in the `teamNumbers` list. Have a look at the `foreach` dictionary entry for more information on how anonymous procedures work. `move-in-groups` as-is works for me to move the turtle groups as a unit- try just calling it directly in `go` without any `ask turtles` or other commands. – Luke C Oct 08 '18 at 18:07
  • I don't know why but `tn` in my coding return error saying that `Nothing named TN has been defined` (•ิ_•ิ)? – linda Oct 09 '18 at 06:15
  • @linda - did you copy the entire `move-in-groups` procedure in directly? What version of NetLogo are you using? – Luke C Oct 09 '18 at 06:32
  • yes, I did copy the entire `move-in-groups` procedure.. my NetLogo version is version 5.2 – linda Oct 09 '18 at 07:44
  • @linda - Ah, I see- NetLogo versions 6 and greater have a slightly different syntax for `foreach` procedures. I recommend updating to the latest version if you can, there are some very nice quality-of-life improvements, of which the change to `foreach` is a great example. If you can't update, please see my edit for a NetLogo 5 version of the `move-in-groups` procedure. – Luke C Oct 09 '18 at 17:46
  • 1
    Thank you for the edited version 5, and thank you for the move-in-group, this one is quite similar to what I want, but I need agents to move in group using flocking rules. I will ask in a new question later on. Thank you so much for your help before :D – linda Oct 14 '18 at 12:37
  • is this code `set myteam1 myteamset with [self != myself]` is the right, if I want to remove myself from the agentset? thank you for your time.. – linda Oct 18 '18 at 08:48
  • @linda - `myteamset with [ self != myself` will indeed return an agentset of any turtles in the `myteamset` for the asking turtle, *excluding* the asking turtle. However, I think it's easier to use other- eg, `ask turtles [ show other myteamset ]` – Luke C Oct 18 '18 at 17:40
0

I agree with Luke that the most appropriate way to deal with teams is as agentsets, not the complicated allocating of identifiers. This is what the code looks like to do that. Note that I haven't addressed the movement part of your question.

globals [max-teamsize]

turtles-own
[ teamID
  teammates
]

to testme
  clear-all
  create-turtles 100
  [ setxy random-xcor random-ycor
    set teamID 0
    set teammates nobody
  ]
  set max-teamsize 3
  setup-groups
  reset-ticks
end

to setup-groups
  ; assign turtles to team by allocating a team number
  let counter 1
  ask turtles
  [ if teamID = 0
    [ set teamID counter
      let potential-teammates turtles with [teamID = 0]
      ask n-of min (list (max-teamsize - 1) (count potential-teammates)) potential-teammates
      [ set teamID counter
      ]
      set counter counter + 1
    ]
  ]
  ; store teammates as agentset of other turtles in team
  ask turtles
  [ set teammates other turtles with [teamID = [teamID] of myself]
  ]
end
JenB
  • 17,620
  • 2
  • 17
  • 45
  • First of all, thank you for your time explaning this, I have some question regarding code, if it doesn't burden you, can you explain this part to me `ask n-of min (list (max-teamsize - 1) (count potential-teammates)) potential-teammates` . how this one works? Due to I need to show the teammates list to prove that my code is right, I have make mistake in insisting on showing teammatesID etc. thus making `turtles-own` has a lot of identifiers. Thank you so much for your time. – linda Nov 07 '18 at 18:21
  • `ask n-of N agentset` means randomly select N agents from the named agentset. In this code, I have `min (list (max-teamsize - 1) (count potential-teammates)` as N, so it calculates the smaller of the teammates needed and the number of turtles still to be assigned. The agentset that they are being selected from is the one named potential-teammates, which is all the turtles with 0 as the teamID (so haven't been assigned yet). – JenB Nov 07 '18 at 20:25
  • meaning that, it could have a group with less than 3 members inside it? – linda Nov 08 '18 at 15:24
  • yes. if you have 20 turtles and you have set the team size to 3, the there are 6 teams of 3 gets you to 18 turtles but there's only 2 left, so team 7 has 2 members only – JenB Nov 08 '18 at 15:34
  • how can I make an agentset include myself from here `set teammates other turtles with [teamID = [teamID] of myself]`, i tried `set myteam turtle-set self other turtles with [teamID = [teamID] of myself]` and it was wrong. And another question, what other option beside face, if I want a turtle to stay at certain patch if I use `ask teammates`, eg: `set food food-quality set location patch-here] face location ` , to think that I'm still stuck coding this program after one year :'( – linda Dec 24 '19 at 13:16
  • For your first question, just remove `other`. I think your second question is a new question since it is not obviously related – JenB Dec 24 '19 at 13:27