Search code examples
if-statementnetlogoagent-based-modeling

NetLogo IF statement color change


Hi im building my first NetLogo model and this is a statement I want to have inside my code

ask turtles
[ ifelse calm <= agigated 20% 
  [set opposite turtle color]
]

If a calm agent meets an agitated agent with a different vote there is a 20% chance that the calm agent will change opinion.

The set up is as follows. There are 2 breeds called group1 and group2 with their own color which is red and blue. The color represents their vote. Each agent is either calm or agitated.

globals [ color-changed calm agitated ]

breed [groups1 group1]
breed [groups2 group2]

turtles-own [ mental-state ]

to setup
  clear-all
  ask patches [ set pcolor black ]
  set-default-shape turtles "person"
  create-groups1 50
  [ setxy random-xcor random-ycor
    set color red
  ]
  create-groups2 50
  [ setxy random-xcor random-ycor
    set color blue
  ]
  ask turtles
  [ ifelse who <= share-of-calm-people
    [ set mental-state "calm" ]
    [ set mental-state "agitated" ]
  ]
end

Solution

  • I am assuming that the red and blue colours represent the opinion. You don't have anything in your code about turtles actually meeting. However, this should get you close:

    ask turtles with [mental-state = "calm"]
    [ let meeter min-one-of other turtles [distance myself]
      if ([mental-state] of meeter = "agitated") and ([color] of meeter != color) and random-float 1 < 0.2
      [ set color [color] of meeter
      ]
    ]
    

    Note that this is not tested. The code if random-float 1 < 0.2 [] is the answer to your specific question about making something happen with a given probability. It draws a random number uniformly from the interval 0 to 1 and then compares that to the value of the probability you want. So 20% of the time, such a random number will be <0.2 for example.

    The rest of the code runs through all the calm turtles, find the closest other turtle (min-one-of other turtles [distance myself]) and then checks whether it is both agitated and has a different colour. If so, with 20% probability, the asking turtle changes colour to the colour of the other turtle.

    I have several general comments about your code:

    1/ If the only difference between group1 and group2 turtles are their colour, which is also their opinion, then you don't need to use breeds. In fact, the code I wrote changes the turtle's colour but does not change its group. There's not a rigid rule, but it is easiest for beginners to use breeds to indicate things that are completely different (eg cars and people) - if your breeds all have the same set of variables, then you probably don't need breeds.

    You can continue to use colour to indicate opinion. But it's good practice to separate the variable from the visualisation. As your model gets more complicated, you may find that you have several different things that you want to visualise and having one attached to colour makes things harder. It also makes your code harder to read (and debug) because you don't have a good variable name.

    2/ It is almost always a bad idea to use who in your code. In your case you have already introduced a bias because you have linked red colour to calm mental state. This is because the who number is assigned in order as the turtles are created. So who 0 to 49 are red and who 50 to 99 are blue. If you have 50% of your turtles calm, then all turtles are either calm and red or agitated and blue.

    If you want to do that, you should do it explicitly. If you don't, you have introduced a bug.

    To avoid duplicating the code to set the colour (and allow you to easily change your visualisation in the future), you can have a separate procedure to match opinions and colours.

    Here is one version of your code that doesn't use breeds or who and randomly allocates opinions and mental states.

    turtles-own
    [ mental-state
      opinion
    ]
    
    to setup
      clear-all
      ask patches [ set pcolor black ]
      set-default-shape turtles "person"
      create turtles 100
      [ setxy random-xcor random-ycor
        ; set and visualise opinion
        set opinion one-of ["yes" "no"]
        colour-opinion
        ; set mental state with given proportion as calm
        ifelse random-float 1 < share-of-calm-people      ; assumes slider is 0 to 1
        [ set mental-state "calm" ]
        [ set mental-state "agitated" ]
      ]
    end
    
    to colour-opinion         ; turtle procedure
      ifelse opinion = "yes"
      [ set color red ]
      [ set color blue ]
    end
    

    Then the code you asked about is rewritten to:

    ask turtles with [mental-state = "calm"]
    [ let meeter min-one-of other turtles [distance myself]
      if ([mental-state] of meeter = "agitated") and ([opinon] of meeter != opinion) and random-float 1 < 0.2
      [ set opinion [opinion] of meeter
        colour-opinion
      ]
    ]