Child of Helping_vs_Harming

No preview image

1 collaborator

Default-person Joe Blass (Author)

Tags

(This model has yet to be categorized with any tags)
Child of model Helping_vs_Harming preview imageHelping_vs_Harming Parent of 1 model: Child of Child of Helping_vs_Harming
Visible to everyone | Changeable by everyone
Model was written in NetLogo 5.2.0 • Viewed 93 times • Downloaded 6 times • Run 0 times
Download the 'Child of Helping_vs_Harming' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

;;; originally all the globals were able to be set by the user; too many damn parameters! 
;;; Now they are set in setup; the indicated settings provide some nice behavior
globals [
  number-of-turtles
  social-radius
  exile-distance
  social-gain  
  life-expectancy
]

turtles-own [
  ;;; internal setting variables
  social-currency
  p-theft
  p-protect
  age
  my-life-expectancy
  
  ;;; color variables
  r
  g
  b
  
  ;;; turn variables
  take-action
  my-neighbors
  got-away?
  
  ;; reproduction variables
  can-breed?
  my-mateworthy-neighbors
  my-mate
    
  ;;; helper variables
  random-choice-num ;;; every turn a turtle uses random to pick what to do; this is so we can pick one random number per turn in the ifelse block
  my-count ;; this is just a placeholder variable; not at all necessary for logic but is handy to avoid retyping code bloacks
  ]

to setup
  ca
  
  if (verbose? and protect-threshold <= theft-threshold) [ ;;; verbose is just there to be able to turn this message off for behavior-space experiments
    user-message "Oops: the protection threshold must be larger than the theft threshold"
    stop
  ]
  
  ;;; set globals to some nice defaults
  set number-of-turtles 150 ;;; This mostly affects how fast things change; doesnt majorly affect the outcome of the model
  set social-radius 8 ;;; if this is smaller turtles tend to die out quickly
  set exile-distance 8
  set life-expectancy 50 ;;; much less than 50 and turtles die out before reproducing; much more and everything just slows down. Might as well specify.
  set social-gain 10 ;;; NOTE: in a different model, social-gain would be a crucial parameter to vary! 
  ;;; However, in this model it doesn't make things that interesting, just move faster.
  ;;; I think this is because this model is set up such that it's a constant increment, that is, turtles only ever gain or lose
  ;;; a maximum of social-gain divided amongst neighbors, rather than from each neighbor. Also, social-currency is not a zero sum game 
  ;;; (since turtles are born with social-currency). I thought it made sense to hide it from the user for simplicity
   
  ask patches [ set pcolor grey ] ;;; turtles are initialized black and can end up white, so grey background is best
  
  crt number-of-turtles [
    ;;; initialize color and location. we are going to do some color math so we have to do this a little hamfistedly
    set r 0
    set g 0
    set b 0
    set color rgb r g b ;; everyone starts off green, randomly placed in the world, with equal social currency
    set size 2
    setxy random-xcor random-ycor
    
    ;; internal variables
    set can-breed? (social-currency > mate-threshold)
    set social-currency initial-social-currency
    set p-theft (theft-threshold - 5 + random 11) ;; everyone has their own theft threshold within 5 of the set threshold
    set p-protect (protect-threshold - 5 + random 11) ;; ditto protection threshold
    if p-theft >= p-protect [set p-theft (p-protect - 1)] ;; make sure p-theft < p-protect; this gives preference to protection rather than theft. call me old-fashioned.
    set age 0
    set my-life-expectancy (life-expectancy - 5 + random 11)
    set got-away? false
      
    
  ]
  
  reset-ticks
end 

to go
  if (count turtles = 0) [stop]
  if stop-at-5000-turtles-or-1000-ticks? ;; do we want the model to eventually halt?
  [ if (count turtles > 5000 or ticks > 1000) [stop]] 
  ;;; these population/tick limits were decided upon basically by seeing where the model starts to slow down enormously and by which point clear trends have emerged.
  
  ;;; first code block resets internals, moves the turtles, and picks what to do
  ask turtles [
    
    turn-reset
    ;;; move
    ifelse any? my-neighbors
    [ face max-one-of my-neighbors [social-currency]] ;; face your most popular neighbor
    [ rt random 360 ] ;; or wiggle if you have no neighbors
    fd 1 ;; take a step towards them
    
    ;;; pick an action. Actions will actually happen during the resolution phase
    ;;; this does NOT have to happen after all the turtles have moved because they are just picking what
    ;;; they WILL do, they are not actually doing it yet
    set random-choice-num random 100
    ifelse (random-choice-num < p-theft) 
    [ set take-action "steal" 
      ifelse (random 100 < probability-of-getting-away) ;; if you steal, figure out whether you get away with it (independent of who's watching)
      [ set got-away? true]
      [ set got-away? false]]
    [ ifelse (random-choice-num < p-protect) ;; if we got here that means p-theft < choice-num < p-protect
      [ set take-action "do-nothing" ] ;; and we do nothing
      [ set take-action "protect" ]]
  ]  ;; otherwise we protect
  
  ;;; resolve performs the actions and resolves the consequences
  ;;; has to happen after all turtles have moved and chosen their actions
  ask turtles [resolve] ;; within resolve, functions to actually perform actions are called
  
  ask turtles [
    if (social-currency > 100) [ set social-currency 100 ]
    if (social-currency <= 0) [ die ] ;; turtles at zero die
    if (age > my-life-expectancy) [ die ]
    set age (age + 1)
  ]
  
  ask turtles [ if can-breed? [ reproduce-if-possible ]] ;;; after all actions are resolved, turtles reproduce if they can
  
  tick
end 

to turn-reset
    ;;; reset some information at each tick
    set my-mate false ;; reset mate info
    set got-away? false 
    set color rgb r g b ;;; reset color
    set can-breed? (social-currency > mate-threshold) ;;; reset breeding status
    set my-neighbors other turtles in-radius social-radius ;; figure out who your neighbors are
    if (social-currency <= 0) [ die ] ;; turtles at zero die
    if (age > my-life-expectancy) [ die ]
end 

to resolve
  ;;; this is only its own function out of convenience; could be in-line with go
  ifelse (take-action = "steal")
  [ steal ]
  [ ifelse (take-action = "protect") 
    [ protect ]
    [ do-nothing ]
  ]
end 

to steal
  ;;; note that steal actually handles MOST of what happens to turtles, i.e., both thieves and protectors  
 
  ;;; in this implementation, a successful thief takes TOTAL social-gain divided amongst the victims. another possibility would be to have it take a social-gain from EACH victim
  ifelse (got-away? or not any? my-neighbors with [take-action = "protect"]) ;; if no one is watching out for thieves or you get away with it
  [ set my-count (count my-neighbors)
    if (my-count > 0) ;; provided you have neighbors
    [ set social-currency (social-currency + social-gain) ;; get social-gain from chumpy neighbors
      ask my-neighbors [set social-currency (social-currency - (social-gain / [my-count] of myself))] ];; each neighbor loses social-gain/count neighbors
                                                                                                       ;;; if you have no neighbors, don't sweat it, you do nothing.
  ] 
  
  ;;; otherwise, someone is watching out for thieves AND you got caught
  [ set my-count (count my-neighbors with [take-action = "protect"])
    set social-currency (social-currency - social-gain) ;; lose social-gain
    ask my-neighbors with [take-action = "protect"]
      [ set social-currency (social-currency + (social-gain / [my-count] of myself))]  ;;; protectors don't each get social-gain, since the more protectors you have, the less each protection matters
    
    ;;; and deal with the consequences of getting caught
    rt random 360
    fd exile-distance ;;; if you get caught stealing, turn and walk away
  ]
  
  ifelse (r < 230) ;;; thieves turn redder
    [ set r (r + 25) ]
    [ set r 255 ]
end 

to protect
  set my-count (count my-neighbors with [take-action = "steal" and not got-away?])
  if (my-count = 0) ;; if none of your neighbors tried to steal and did not get away with it, then you are being a busybody
    [ set social-currency (social-currency - social-gain) ;; lose social-gain 
      ask my-neighbors [set social-currency (social-currency + (social-gain / [count my-neighbors] of myself))]] ;;; all your neighbors are smugly satisfied with themselves and each other
  
  ;;; otherwise, someone has tried to steal
  ;;; but we don't have to do anything because it is handled by the steal function
  
  ;;; protectors turn bluer
  ifelse (b < 230) ;;; turtles who are protectors turn bluer
  [ set b (b + 25) ]
  [ set b 255 ]
end 

to do-nothing
  ;;; the only thing we need to do within this function is change the color a bit
  ifelse (g < 230) ;;; show the turtle's guilt by turning it redder
  [ set g (g + 25) ]
  [ set g 255 ]
end 

to reproduce-if-possible
  ;; only called with turtles who can reproduce
  set my-mateworthy-neighbors my-neighbors with [can-breed? and (my-mate = false)] ;; my-mate is set to false at the beginning of each tick
  if any? my-mateworthy-neighbors
  [ set my-mate max-one-of my-mateworthy-neighbors [social-currency]
    ask my-mate [ set my-mate true ] ;;; I know it's a bit odd to have the my-mate variable be a combination of booleans and agents, but this should still work; the point is to have my-mate bound or not
    ;; we do it this way so that turtles don't mate twice per turn
    hatch 1 [
      set social-currency initial-social-currency
      set p-protect ((([p-protect] of myself + [p-protect] of [my-mate] of myself) / 2) - 5 + random 11) ;; average p-protect of parents, plus some randomness
      set p-theft ((([p-theft] of myself + [p-theft] of [my-mate] of myself) / 2) - 5 + random 11) ;; average p-theft of parents, plus some randomness
      if p-theft >= p-protect [set p-theft (p-protect - 1)] ;; make sure p-theft < p-protect; this gives preference to protection rather than theft. call me old-fashioned.
      set age 0
      set my-life-expectancy ((([my-life-expectancy] of myself + [my-life-expectancy] of [my-mate] of myself) / 2) - 5 + random 11)
      set got-away? false
      
      ;;; placement and color
      set r 0
      set g 0
      set b 0
      set color rgb r g b ;; no matter who your parents are, you start off innocent
      rt random 360
      fd (exile-distance / 2)
    ]
  ]
end 

;;; reporters for charts

to-report num-turtles-that-can-breed
  ifelse (count turtles = 0)
  [report 0]
  [ report count turtles with [can-breed?]]
end 

to-report proportion-of-thieving-turtles
  ifelse (count turtles = 0)
  [report 0]
  [ report count turtles with [r > 250] / count turtles]
end 

to-report proportion-of-protector-turtles
  ifelse (count turtles = 0)
  [report 0]
  [ report count turtles with [b > 250] / count turtles]
end 

to-report proportion-of-placid-turtles
  ifelse (count turtles = 0)
  [report 0]
  [ report count turtles with [g > 250] / count turtles]
end 

to-report proportion-of-mixed-turtles
  ifelse (count turtles = 0)
  [report 0]
  [ report count turtles with [(r > 250) and (b > 250)] / count turtles]
end 

to-report proportion-turtles-who-just-stole
  ifelse (count turtles = 0)
  [report 0]
  [ report turtles-who-just-stole / count turtles]
end 

to-report proportion-turtles-who-just-protected
  ifelse (count turtles = 0)
  [report 0]
  [ report turtles-who-just-protected / count turtles]
end 

to-report proportion-turtles-who-just-did-nothing
  ifelse (count turtles = 0)
  [report 0]
  [ report turtles-who-just-did-nothing / count turtles]
end 

to-report turtles-who-just-stole
  report count turtles with [take-action = "steal"]
end 

to-report turtles-who-just-protected
  report count turtles with [take-action = "protect"]
end 

to-report turtles-who-just-did-nothing
  report count turtles with [take-action = "do-nothing"]
end 

to-report proportion-breeding-turtles
  ifelse (count turtles with [can-breed?] = 0)
  [report 0]
  [report ((count turtles with [can-breed?]) / count turtles)]
end 

to-report proportion-thieving-breeders
  ifelse (count turtles with [can-breed?] = 0)
    [report 0]
    [report ((count turtles with [can-breed? and (take-action = "steal")]) / (count turtles with [can-breed?]))]
end 

to-report proportion-protecting-breeders
  ifelse (count turtles with [can-breed?] = 0)
    [report 0]
    [report ((count turtles with [can-breed? and (take-action = "protect")]) / (count turtles with [can-breed?]))]
end 

to-report proportion-complacent-breeders
  ifelse (count turtles with [can-breed?] = 0)
    [report 0]
    [report ((count turtles with [can-breed? and (take-action = "do-nothing")]) / (count turtles with [can-breed?]))]
end 

There is only one version of this model, created over 4 years ago by Joe Blass.

Attached files

No files