Survivor Voting Alliances

Survivor Voting Alliances preview image

1 collaborator

Default-person Isaac Lee (Author)

Tags

(This model has yet to be categorized with any tags)
Model group MAM-2018 | Visible to everyone | Changeable by the author
Model was written in NetLogo 6.0.3 • Viewed 211 times • Downloaded 6 times • Run 0 times
Download the 'Survivor Voting Alliances' 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

extensions [
  cf
  csv
  rnd
  table
]

breed [ contestants contestant ]
undirected-link-breed [ alliances alliance ]

contestants-own [
  eliminated?

  tribe

  mental
  physical
  social
  loyalty

  target ; most recent target
  vote  ; most recent vote

  initial-social
  finish ; for resume output
  individual-challenge-wins ; for resume output
  correct-votes
  total-votes-against

  elimination-score ; for voting-history output
  voting-history ; for voting-history output

  archetypes
]

globals [
  merged?
  phase ; 0:challenge -> 1:tribal-council -> 2:update social game -> repeat

  eliminated-contestant ; most recent eliminated contestant
  winning-contestant ; most recent individual challenge winner
  winning-tribe ; most recent tribal challenge winner

  challenge-eliminated-list ; list of challenge winner, eliminated contestant pairs

  my-contestant ; created contestant
  contestant-experiment-finishes ; list of my-contestant's finishes
  repeat-experiment-finishes-table ; table of each contestants finishes
]

to setup
  ca
  set-default-shape contestants "person"

  create-contestants num-contestants / 2 [ ; create first tribe
    set tribe 0
    contestant-constructor
    setxy (- (random max-pxcor / 2)) - max-pxcor / 2  (social / 100) * (max-pycor * 2) - max-pycor
  ]

  create-contestants num-contestants / 2 [ ; create second tribe
    set tribe 1
    contestant-constructor
    setxy (random max-pxcor / 2) + max-pxcor / 2 (social / 100) * (max-pycor * 2) - max-pycor
  ]

  if create-a-contestant? [
    ask contestant 0 [
      set my-contestant self
      set mental custom-mental
      set physical custom-physical
      set social custom-social
      set loyalty custom-loyalty
      setxy (- (random max-pxcor / 2)) - max-pxcor / 2  (social / 100) * (max-pycor * 2) - max-pycor
    ]
    watch my-contestant
  ]


  set phase -1
  set merged? false
  set challenge-eliminated-list (list)
  reset-ticks
end 

to go
  set phase (phase + 1) mod 3

  if count contestants with [eliminated? = false] = 2 [
    log-challenge-eliminated-list-to-file
    log-contestant-resumes-to-file
    log-voting-histories-to-file
    stop
  ]

  if count contestants with [eliminated? = false] = num-contestants / 2 + 2 and phase = 0 [ merge ]
  (cf:ifelse
    phase = 0 [
      challenge
    ]
    phase = 1 [
      tribal-council
    ]
    phase = 2 [
      update-alliances
    ]
    [ print phase ])

  ; log
  tick
end 

; creates a contestant with random attributes

to contestant-constructor  ; turtle procedure
  set eliminated? false

  set mental random 100 + 1
  set physical random 100 + 1
  set social random 100 + 1
  set initial-social social
  set loyalty minimum-loyalty + random-float (1 - minimum-loyalty)

  set individual-challenge-wins 0

  set elimination-score ""
  set voting-history (list)

  set archetypes (list)
  set-archetypes
end 

; adds labels to contestants for later analysis

to set-archetypes  ; turtle procedure
  if loyalty < (minimum-loyalty + 0.1) [
    set archetypes lput "Deceptive" archetypes
  ]

  if loyalty > 0.9 [
    set archetypes lput "Loyal" archetypes
  ]

  if mental > 50 and physical > 50 [
    set archetypes lput "Balanced" archetypes
  ]

  if mental > 90 [
    set archetypes lput "Smart" archetypes
  ]

  if physical > 90 [
    set archetypes lput "Strong" archetypes
  ]

  if social > 40 and social < 60 [
    set archetypes lput "Diplomatic" archetypes
  ]

  if social > 90 or social < 10 [
    set archetypes lput "Eccentric" archetypes
  ]
end 

; merges tribes

to merge
  set merged? true
  ask contestants with [eliminated? = false] [
    set xcor (random max-pxcor) -  max-pxcor / 2
    ifelse tribe = 0 [
      ;set ycor social / 100 * max-pycor
    ]
    [
      ;set ycor social / 100 * max-pycor
    ]
  ]
end 

; sets mental/physical ratio for each challenge, randomly selects winner with probability based on overall mental/physical abilities

to challenge
  let challenge-mental-physical-ratio random-float 1
  ifelse not merged? [

    let tribe-0-mental-physical (challenge-mental-physical-ratio * tribe-0-mental + (1 - challenge-mental-physical-ratio) * tribe-0-physical) ^ 2
    let tribe-1-mental-physical (challenge-mental-physical-ratio * tribe-1-mental + (1 - challenge-mental-physical-ratio) * tribe-1-physical) ^ 2

    let tribes list (list 0 tribe-0-mental-physical) (list 1 tribe-1-mental-physical)

    set winning-tribe first rnd:weighted-one-of-list tribes [ [t] -> last t ]

    ; log
    if log? [ print word "Tribe " word winning-tribe " Won Challenge" ]
  ]
  [
    set winning-contestant rnd:weighted-one-of contestants with [eliminated? = false] [(challenge-mental-physical-ratio * mental + (1 - challenge-mental-physical-ratio) * physical) ^ 2]

    ask winning-contestant [
      set individual-challenge-wins individual-challenge-wins + 1
    ]

    ; log
    if log? [ print word "Contestant " word [who] of winning-contestant " Won Challenge" ]
  ]
end 

; calculates which contestant to eliminate from the game based on votes

to tribal-council
  let c contestants with [eliminated? = false]
  set-vote

  ifelse not merged? [
    ; Pre-Merge: losing tribe votes to eliminate a contestant
    let to-eliminate max-one-of c with [tribe != winning-tribe] [votes-against]

    ; log
    if log? [
      print word "Tribe " word (1 - winning-tribe) " Tribal Council:"
      foreach sort-on [(- [who] of vote)] contestants with [eliminated? = false and vote != nobody][ the-contestant ->
        ask the-contestant [
          let vh last voting-history
          print word who word ": " vh
        ]
      ]
    ]

    ask contestants with [eliminated? = false] [
      if vote = to-eliminate [
        set correct-votes correct-votes + 1
      ]
      set total-votes-against total-votes-against + votes-against
    ]

    ; eliminate contestant
    ask to-eliminate [ eliminate ]
    set challenge-eliminated-list lput (list winning-tribe eliminated-contestant) challenge-eliminated-list
  ]
  [
    ; Post-Merge: entire merged tribe votes to eliminate a contestant
    let to-eliminate max-one-of c [votes-against]

    ; log
    if log? [
      print "Tribal Council:"
      foreach sort-on [(- [who] of vote)] contestants with [eliminated? = false][ the-contestant ->
        ask the-contestant [
          let vh last voting-history
          print word who word ": " vh
        ]
      ]
    ]

    ask contestants with [eliminated? = false] [
      if vote = to-eliminate [
        set correct-votes correct-votes + 1
      ]
      set total-votes-against total-votes-against + votes-against
    ]

    ask to-eliminate [ eliminate ]
    set challenge-eliminated-list lput (list winning-contestant eliminated-contestant) challenge-eliminated-list
  ]
end 

; completes bookwork required to eliminate a contestant

to eliminate  ; turtle procedure
  if log? [ print word "Contestant " word who " Eliminated" ]
  set-elimination-score
  set eliminated? true
  set eliminated-contestant self
  hide-turtle
  ask my-alliances[ die ]
  set finish count contestants - count contestants with [eliminated? = true] + 1
end 

; sets each contestants elimination vote for output (ex. contestant eliminated 5 votes to 3 votes, output: (5-3))

to set-elimination-score ; turtle procedure
  set elimination-score (word "(" first tribal-council-score)
  foreach but-first tribal-council-score [ num ->
    set elimination-score (word elimination-score "-" num)
  ]
  set elimination-score (word elimination-score ")")
end 

; updates contestant's social property and alliance links based on previous vote

to update-alliances

  ; Line In The Sand: if contestant did not vote with their ally, they are no longer allies
  ask contestants with [eliminated? = false] [
    ask my-alliances [
      if [vote] of other-end != [vote] of myself [ die ]
    ]
  ]

  ; contestants who vote together are linked together and have their "social" properties grow closer
  ask contestants with [eliminated? = false and vote != nobody] [
    let mean-alliance-social mean [social] of contestants with [eliminated? = false and vote = [vote] of myself]
    let social-change social-update-rate * (mean-alliance-social - social)
    set social social + social-change
    set ycor (social / 100) * (max-pycor * 2) - max-pycor
    ifelse not merged? [
      create-alliances-with other contestants with [eliminated? = false and tribe = [tribe] of myself and vote = [vote] of myself]
    ]
    [
      create-alliances-with other contestants with [eliminated? = false and vote = [vote] of myself]
    ]
  ]
end 

; sets each contestants vote for an elimination

to set-vote
  ask contestants [
    set target nobody
    set vote nobody
  ]
  ifelse not merged? [
    ; Pre-Merge, every contestant on the losing tribe selects one target at random w/probability = (social-difference myself) / (mental + physical) ^ 2
    ask contestants with [eliminated? = false and tribe != winning-tribe] [
      set target rnd:weighted-one-of other contestants with [ eliminated? = false and tribe = [tribe] of myself ] [(social-difference myself) / (mental + physical) ^ 2]
    ]
    ; next, every contestant chooses between the top two targets based solely on social difference
    let target-table table:counts [[who] of target] of contestants with [eliminated? = false and tribe != winning-tribe]

    let primary-target key-with-max-value target-table
    table:remove target-table primary-target
    let secondary-target key-with-max-value target-table

    ask contestants with [eliminated? = false and tribe != winning-tribe] [
      set vote max-one-of (turtle-set (contestant primary-target) (contestant secondary-target)) [ social-difference myself ]
    ]

    ask contestants with [eliminated? = false] [
      ifelse vote = nobody [
        set voting-history lput "-" voting-history
      ]
      [
        set voting-history lput [who] of vote voting-history
      ]
    ]
  ]
  [
    ; Post-Merge, every contestant selects one target at random w/probability = (social-difference + perceived-threat)
    ask contestants with [eliminated? = false] [
      set target rnd:weighted-one-of other contestants with [ eliminated? = false and self != winning-contestant ] [social-difference myself + perceived-threat]
    ]
    ; next, every contestant chooses between the top two targets based solely on social difference
    let target-table table:counts [[who] of target] of contestants with [eliminated? = false]

    let primary-target key-with-max-value target-table
    table:remove target-table primary-target
    let secondary-target key-with-max-value target-table

    ask contestants with [eliminated? = false] [
      set vote max-one-of other (turtle-set contestant primary-target contestant secondary-target) [social-difference myself]
    ]

    ask contestants with [eliminated? = false] [
      ifelse vote = nobody [ set voting-history lput "-" voting-history ]
      [ set voting-history lput [who] of vote voting-history ]
    ]
  ]
end 

; REPORTERS

to-report absolute-value [number]
  ifelse number >= 0
    [ report number ]
  [ report (- number) ]
end 

to-report key-with-max-value [ t ]
  let l table:to-list t ; convert to list of key/value pairs
  report first reduce [ [a b] -> ifelse-value (last a > last b) [a] [b]] l ; find pair with max value, report key
end 

to-report perceived-threat  ; turtle reporter
  report (
    (mental + physical)
    + individual-challenge-wins * 20
  )
end 

to-report social-difference [ ms ] ; turtle reporter
  if not merged? [
    report (absolute-value (social - [social] of ms)) * [loyalty] of ms
  ]
  report round absolute-value (social - [social] of ms) * [loyalty] of ms
  ;report round absolute-value ((social - [social] of ms) + (0.9) ^ (sum [individual-challenge-wins] of contestants) * 50 * absolute-value (tribe - [tribe] of ms)) * [loyalty] of ms
  ; post-merge social difference: social-difference + 50 * decay (if different tribe)
end 

to-report tribal-council-score
  let l (list)
  ; iterates through contestants who had votes cast against them
  foreach sort-on [(- votes-against)] contestants with [votes-against > 0][ the-contestant ->
    set l lput [votes-against] of the-contestant l  ]
  report l
end 

to-report tribe-0-mental
  if count contestants with [tribe = 0 and eliminated? = false] = 0 [ report 0 ]
  report sum [mental] of contestants with [tribe = 0 and eliminated? = false] / count contestants with [tribe = 0 and eliminated? = false]
end 

to-report tribe-0-physical
  if count contestants with [tribe = 0 and eliminated? = false] = 0 [ report 0 ]
  report sum [physical] of contestants with [tribe = 0 and eliminated? = false] / count contestants with [tribe = 0 and eliminated? = false]
end 

to-report tribe-1-mental
  if count contestants with [tribe = 0 and eliminated? = false] = 0 [ report 0 ]
  report sum [mental] of contestants with [tribe = 1 and eliminated? = false] / count contestants with [tribe = 1 and eliminated? = false]
end 

to-report tribe-1-physical
  if count contestants with [tribe = 0 and eliminated? = false] = 0 [ report 0 ]
  report sum [physical] of contestants with [tribe = 1 and eliminated? = false] / count contestants with [tribe = 1 and eliminated? = false]
end 

to-report votes-against  ; turtle reporter
  ifelse not merged?
  [ report count contestants with [eliminated? = false and tribe = [tribe] of myself and vote = myself] ]
  [ report count contestants with [eliminated? = false and vote = myself] ]
end 

to-report winning-contestant-reporter
  report winning-contestant
end 

to-report winning-tribe-reporter
  report winning-tribe
end 

; CSV PROCEDURES

to log-challenge-eliminated-list-to-file
  csv:to-file "challenge-eliminated-list.csv" fput (list "challenge-winner" "eliminated-contestant") challenge-eliminated-list
end 

to log-contestant-resumes-to-file
  let l (list)
  set l lput (list "contestant" "tribe" "finish" "individual-challenge-wins" "mental" "physical" "social" "loyalty" "correct-votes" "total-votes-against" "archetypes") l
  foreach sort-on [(- finish)] contestants[ the-contestant ->
    ask the-contestant [
      set l lput (list who tribe finish individual-challenge-wins mental physical initial-social precision loyalty 2 correct-votes total-votes-against archetypes) l
    ]
  ]
  csv:to-file "contestant-resumes.csv" l
end 

to log-voting-histories-to-file
  let l (list)

  let r (list "contestant")
  foreach sort-on [(- finish)] contestants [ the-contestant ->
    ask the-contestant [
      set r lput (word who " " elimination-score) r
    ]
  ]

  set l lput r l

  foreach sort-on [finish] contestants[ the-contestant ->
    ask the-contestant [
      set l lput fput who voting-history l
    ]
  ]
  csv:to-file "voting-histories.csv" l
end 

There is only one version of this model, created almost 6 years ago by Isaac Lee.

Attached files

File Type Description Last updated
Survivor Voting Alliances.png preview Preview for 'Survivor Voting Alliances' almost 6 years ago, by Isaac Lee Download

This model does not have any ancestors.

This model does not have any descendants.