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 357 times • Downloaded 21 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.)


WHAT IS IT?

This model of contestants within the game of Survivor illustrates the behavior of teams and players when forced to vote out a member. Over time, fluid voting "alliances" emerge, but not without members that betray their alliance, or repeatedly flip back and forth between two large alliances.

HOW IT WORKS

Pre-Merge: At each tick, tribes compete in a challenge, with a winner randomly selected based on a probability weighted on a tribes overall mental and physical ability. The losing tribe is forced to vote to eliminate one member. Each member decides who to vote for based on mental and physical ability (the stronger the better), and their social property (the closer the better). The member with the most votes is eliminated. Contestants who vote together grow slightly closer together socially with each vote.

The "merge", signaling the evolution of Survivor from a tribe vs tribe game to an individual game, happens when half of the initial contestants have been eliminated.

Post-Merge: At each tick, individuals compete in a challenge, with a winner randomly selected based on a probability weighted on a contestant's mental and physical ability. The tribe must vote to eliminate one member (the challenge winner is immune). The member with the most votes is eliminated. Each member decides who to vote for based on mental and physical ability (the weaker the better), and their social property (the closer the better). Contestants who vote together grow slightly closer together socially with each vote.

Initially, contestants are randomly generated with mental, physical, social, and loyalty properties.

  • Mental and physical abilities (0-100) determine contestants' effectiveness at winning "challenges" (challenge winneres are granted immunity from elimination). The social property represents each contestant's "social game", i.e. the relationships and alliances they make.

  • The social property (0-100) represents each contestant's "social game", i.e. the relationships and alliances they develop.

  • The loyalty parameter (0-1.0) represents the significance a player puts into their social relationships and alliances when deciding who to vote for. For example, contestant with low loyalty is more likely to vote out a member they are close to socially that a contestant with high loyalty.

HOW TO USE IT

Click the SETUP button to start a new game. Click GO-ONCE to conduct a challenge, again to eliminate a member, and again to update contestants' alliances and social game.

Click GO to indefinitely conduct challenges, eliminate contestants, and update alliances until a game is finished (only two contestants remaining)

Use the NUM-CONTESTANTS slider to determine how many contestants the game starts with. Use the LOG? switch to output results in the command center.

Use the MINIMUM-LOYALTY slider to determine the minimum loyalty value to use when randomly generating contestant's loyalty properties at the start. I have observed that even the most cutthroat Survivor players give some value to their established alliances and social relationships, making a non-zero minimum-loyalty make sense.

Use the SOCIAL-UPDATE-RATE slider to determine how quickly alliance's social properties converge.

Use the CREATE-A-CONTESTANT switch and CUSTOM sliders to create a contestant with custom attribute values to see how they perform in a random game of Survivor.

THINGS TO NOTICE

The model tries to create an environment where the general voting patterns of past Survivor seasons emerge. Overall, the contestants who are best at challenges (i.e. the strongest and smartest) are not the contestants most likely to make it to the end of the game. Rather, it is the contestants who are best at making and managing their voting alliances that succeed.

THINGS TO TRY

Use the CREATE-A-CONTESTANT switch and CUSTOM sliders to create a contestant with custom attribute values to see how they perform in a random game of Survivor.

Use BehaviorSpace to test how these contestants perform over many runs.

EXTENDING THE MODEL

Implement different strategies (every contestant selects votes using the same randomized, equation-based strategy) and a genetic algorithm to see which strategies dominate.

NETLOGO FEATURES

Uses the cf, csv, rnd, and table extensions.

RELATED MODELS

Team Assembly Model

CREDITS AND REFERENCES

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 about 7 years ago by Isaac Lee.

Attached files

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

This model does not have any ancestors.

This model does not have any descendants.