Survivor Voting Alliances
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
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.
This model does not have any ancestors.
This model does not have any descendants.