TOURNAMENT, EVOLUTION
This commit is contained in:
parent
e70f42c383
commit
8ff91b8135
19 changed files with 945 additions and 185 deletions
|
@ -4,38 +4,3 @@ therefore, understand the conditions of trust, its mechanisms
|
|||
|
||||
---
|
||||
|
||||
And your total score is...
|
||||
BIG NUMBER which is, wow, actually _impressively_ bad. // 8
|
||||
which, uh, could be worse! // 9 to 21
|
||||
which ain't bad! // 22 to 34
|
||||
which is pretty good! // 34 to 48
|
||||
which is actually _perfect_ // 49
|
||||
which i have no idea how you accomplished
|
||||
(the lowest & highest possible scores
|
||||
are 8 and 49, respectively.)
|
||||
|
||||
So who were these strange characters you just played against?
|
||||
|
||||
COPYCAT:
|
||||
|
||||
Hello! I start with Cooperate, and afterwards, I just copy whatever you did in the last round. Meow
|
||||
|
||||
ALWAYS CHEAT:
|
||||
|
||||
_the strong shall eat the weak_
|
||||
|
||||
ALWAYS COOPERATE:
|
||||
|
||||
Let's be best friends! <3
|
||||
|
||||
GRUDGER:
|
||||
|
||||
Listen, stranger. I'll start cooperatin', and keep cooperation', but if y'all ever cheat me, I'LL CHEAT YOU BACK TIL THE END OF DAYS.
|
||||
|
||||
DETECTIVE:
|
||||
|
||||
First: I analyze you. I start: Cooperate, Cheat, Cooperate, Cooperate. If you cheat back, I'll act like Copycat. If you never cheat back, I'll act like Always Cheat, to exploit you. Elementary.
|
||||
|
||||
Now what if these characters were to play...
|
||||
|
||||
...against each other?
|
||||
|
|
BIN
assets/evolution/evolution_intro.png
Normal file
BIN
assets/evolution/evolution_intro.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 93 KiB |
Binary file not shown.
Before Width: | Height: | Size: 96 B |
43
assets/tournament/connection_flower.json
Normal file
43
assets/tournament/connection_flower.json
Normal file
|
@ -0,0 +1,43 @@
|
|||
{"frames": {
|
||||
|
||||
"connection_flower0000":
|
||||
{
|
||||
"frame": {"x":10,"y":10,"w":401,"h":720},
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": {"x":0,"y":0,"w":401,"h":720},
|
||||
"sourceSize": {"w":401,"h":720}
|
||||
},
|
||||
"connection_flower0001":
|
||||
{
|
||||
"frame": {"x":421,"y":10,"w":401,"h":720},
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": {"x":0,"y":0,"w":401,"h":720},
|
||||
"sourceSize": {"w":401,"h":720}
|
||||
},
|
||||
"connection_flower0002":
|
||||
{
|
||||
"frame": {"x":10,"y":740,"w":401,"h":720},
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": {"x":0,"y":0,"w":401,"h":720},
|
||||
"sourceSize": {"w":401,"h":720}
|
||||
},
|
||||
"connection_flower0003":
|
||||
{
|
||||
"frame": {"x":421,"y":740,"w":401,"h":720},
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": {"x":0,"y":0,"w":401,"h":720},
|
||||
"sourceSize": {"w":401,"h":720}
|
||||
}},
|
||||
"meta": {
|
||||
"app": "Adobe Animate",
|
||||
"version": "15.2.0.66",
|
||||
"image": "connection_flower.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {"w":1024,"h":2048},
|
||||
"scale": "1"
|
||||
}
|
||||
}
|
BIN
assets/tournament/connection_flower.png
Normal file
BIN
assets/tournament/connection_flower.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
Binary file not shown.
Before Width: | Height: | Size: 96 B |
BIN
assets/tournament/score_small.png
Normal file
BIN
assets/tournament/score_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8 KiB |
|
@ -48,7 +48,6 @@ body{
|
|||
}
|
||||
#slideshow{
|
||||
|
||||
/*background: #bada55;*/
|
||||
/*border: 1px solid rgba(0,0,0,0.2);*/
|
||||
width:960px;
|
||||
height:540px;
|
||||
|
@ -134,7 +133,7 @@ body{
|
|||
background-position: 0px -125px !important;
|
||||
}
|
||||
.button[deactivated=yes] #background{
|
||||
background-position: 0px -250px;
|
||||
background-position: 0px -250px !important;
|
||||
}
|
||||
.button[deactivated=yes] #text{
|
||||
color: #CCCCCC;
|
||||
|
@ -349,12 +348,50 @@ body{
|
|||
.tft{ color:#4089DD; }
|
||||
.all_d{ color:#52537F; }
|
||||
.all_c{ color:#FF75FF; }
|
||||
.grudge{ color:#C4A401; }
|
||||
.prober{ color:#CC984C; }
|
||||
.grudge{ color:#efc701; }
|
||||
.prober{ color:#f6b24c; }
|
||||
.tf2t{ color:#88A8CE; }
|
||||
.pavlov{ color:#86C448; }
|
||||
.random{ color:#FF5E5E; }
|
||||
|
||||
.icon{
|
||||
width:25px; height:25px;
|
||||
background: url(../assets/ui/sandbox_hats.png);
|
||||
background-size: auto 100%;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.icon_label{
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
position: relative;
|
||||
top: -3px;
|
||||
}
|
||||
.tft .icon{ background-position: 0 0; }
|
||||
.all_d .icon{ background-position: -25px 0; }
|
||||
.all_c .icon{ background-position: -50px 0; }
|
||||
.grudge .icon{ background-position: -75px 0; }
|
||||
.prober .icon{ background-position: -100px 0; }
|
||||
.tf2t .icon{ background-position: -125px 0; }
|
||||
.pavlov .icon{ background-position: -150px 0; }
|
||||
.random .icon{ background-position: -175px 0; }
|
||||
|
||||
/*************************/
|
||||
/******* MISC STUFF *******/
|
||||
/*************************/
|
||||
|
||||
.score_small{
|
||||
width:40px; height:40px;
|
||||
background: url(../assets/tournament/score_small.png);
|
||||
background-size: auto 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.score_small[payoff=R]{ background-position: 0 0; }
|
||||
.score_small[payoff=T]{ background-position: -40px 0; }
|
||||
.score_small[payoff=S]{ background-position: -80px 0; }
|
||||
.score_small[payoff=P]{ background-position: -120px 0; }
|
||||
|
||||
/*************************/
|
||||
/***** SLIDE SELECT ******/
|
||||
/*************************/
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
<script src="js/core/Slider.js"></script>
|
||||
<script src="js/core/Scratcher.js"></script>
|
||||
<script src="js/core/Background.js"></script>
|
||||
<script src="js/core/ImageBox.js"></script>
|
||||
|
||||
<!-- Simulations -->
|
||||
<script src="js/sims/Splash.js"></script>
|
||||
|
@ -85,7 +86,7 @@ window.onload = function(){
|
|||
|
||||
// First slide!
|
||||
//slideshow.nextSlide();
|
||||
slideshow.gotoSlide("iterated");
|
||||
slideshow.gotoSlide("evolution");
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -25,10 +25,6 @@ function Button(config){
|
|||
// Customize DOM
|
||||
button.style.left = config.x+"px";
|
||||
button.style.top = config.y+"px";
|
||||
if(config.fontSize){
|
||||
text.style.fontSize = config.fontSize;
|
||||
text.style.top = 14+(20-config.fontSize);
|
||||
}
|
||||
self.setText = function(text_id){
|
||||
var words = Words.get(text_id);
|
||||
if(config.uppercase) words = words.toUpperCase();
|
||||
|
|
18
js/core/ImageBox.js
Normal file
18
js/core/ImageBox.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
function ImageBox(config){
|
||||
|
||||
var self = this;
|
||||
self.id = config.id;
|
||||
|
||||
// Create DOM
|
||||
self.dom = new Image();
|
||||
self.dom.className = "object";
|
||||
self.dom.src = config.src;
|
||||
|
||||
// Customize
|
||||
_configText(config, self.dom);
|
||||
|
||||
// Add & Remove
|
||||
self.add = function(){ _add(self); };
|
||||
self.remove = function(){ _remove(self); };
|
||||
|
||||
}
|
|
@ -1,6 +1,3 @@
|
|||
/*
|
||||
|
||||
*/
|
||||
function TextBox(config){
|
||||
|
||||
var self = this;
|
||||
|
|
|
@ -2,8 +2,8 @@ var PEEP_METADATA = {
|
|||
tft: {frame:0, color:"#4089DD"},
|
||||
all_d: {frame:1, color:"#52537F"},
|
||||
all_c: {frame:2, color:"#FF75FF"},
|
||||
grudge: {frame:3, color:"#C4A401"},
|
||||
prober: {frame:4, color:"#CC984C"},
|
||||
grudge: {frame:3, color:"#efc701"},
|
||||
prober: {frame:4, color:"#f6b24c"},
|
||||
tf2t: {frame:5, color:"#88A8CE"},
|
||||
pavlov: {frame:6, color:"#86C448"},
|
||||
random: {frame:7, color:"#FF5E5E"}
|
||||
|
@ -74,6 +74,9 @@ PD.playOneGame = function(playerA, playerB){
|
|||
playerA.addPayoff(payoffs[0]);
|
||||
playerB.addPayoff(payoffs[1]);
|
||||
|
||||
// Return the payoffs...
|
||||
return payoffs;
|
||||
|
||||
};
|
||||
|
||||
PD.playRepeatedGame = function(playerA, playerB, turns){
|
||||
|
@ -83,10 +86,21 @@ PD.playRepeatedGame = function(playerA, playerB, turns){
|
|||
playerB.resetLogic();
|
||||
|
||||
// Play N turns
|
||||
var scores = {
|
||||
totalA:0,
|
||||
totalB:0,
|
||||
payoffs:[]
|
||||
};
|
||||
for(var i=0; i<turns; i++){
|
||||
PD.playOneGame(playerA, playerB);
|
||||
var p = PD.playOneGame(playerA, playerB);
|
||||
scores.payoffs.push(p);
|
||||
scores.totalA += p[0];
|
||||
scores.totalB += p[1];
|
||||
}
|
||||
|
||||
// Return the scores...
|
||||
return scores;
|
||||
|
||||
};
|
||||
|
||||
PD.playOneTournament = function(agents, turns){
|
||||
|
|
|
@ -14,6 +14,8 @@ Tournament.resetGlobalVariables = function(){
|
|||
{strategy:"random", count:5}
|
||||
];
|
||||
|
||||
Tournament.FLOWER_CONNECTIONS = false;
|
||||
|
||||
publish("pd/defaultPayoffs");
|
||||
|
||||
PD.NOISE = 0;
|
||||
|
@ -38,7 +40,8 @@ subscribe("rules/turns",function(value){
|
|||
|
||||
// REGULAR LOAD
|
||||
Loader.addToManifest(Loader.manifest,{
|
||||
tournament_peep: "assets/tournament/tournament_peep.json"
|
||||
tournament_peep: "assets/tournament/tournament_peep.json",
|
||||
connection_flower: "assets/tournament/connection_flower.json"
|
||||
});
|
||||
|
||||
function Tournament(config){
|
||||
|
@ -122,15 +125,18 @@ function Tournament(config){
|
|||
// Connect all of 'em
|
||||
for(var i=0; i<self.agents.length; i++){
|
||||
var playerA = self.agents[i];
|
||||
var flip = false;
|
||||
for(var j=i+1; j<self.agents.length; j++){
|
||||
var playerB = self.agents[j];
|
||||
var connection = new TournamentConnection({
|
||||
tournament: self,
|
||||
from: playerA,
|
||||
to: playerB
|
||||
to: playerB,
|
||||
flower_flip: flip
|
||||
});
|
||||
self.networkContainer.addChild(connection.graphics);
|
||||
self.connections.push(connection);
|
||||
flip = !flip;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,6 +174,48 @@ function Tournament(config){
|
|||
|
||||
self.reset();
|
||||
|
||||
////////////////////////////////////
|
||||
// SHOW MATCHES ////////////////////
|
||||
////////////////////////////////////
|
||||
|
||||
self.playMatch = function(number){
|
||||
|
||||
// GET OUR MATCH
|
||||
var matches = [];
|
||||
for(var a=0; a<self.agents.length; a++){
|
||||
for(var b=a+1; b<self.agents.length; b++){
|
||||
matches.push([self.agents[a], self.agents[b]]);
|
||||
}
|
||||
}
|
||||
var match = matches[number];
|
||||
|
||||
// Highlight match
|
||||
self.dehighlightAllConnections();
|
||||
var connections = match[0].connections;
|
||||
var connection = connections.filter(function(c){
|
||||
if(c.from==match[0] && c.to==match[1]) return true;
|
||||
if(c.from==match[1] && c.to==match[0]) return true;
|
||||
return false;
|
||||
})[0];
|
||||
connection.highlight();
|
||||
|
||||
// Actually PLAY the game -- HACK: HARD-CODE 10 ROUNDS
|
||||
var scores = PD.playRepeatedGame(match[0], match[1], 10);
|
||||
|
||||
// Return ALL this data...
|
||||
return {
|
||||
charA: match[0].strategyName,
|
||||
charB: match[1].strategyName,
|
||||
scoreA: scores.totalA,
|
||||
scoreB: scores.totalB,
|
||||
payoffs: scores.payoffs
|
||||
}
|
||||
|
||||
};
|
||||
self.dehighlightAllConnections = function(){
|
||||
for(var i=0; i<self.connections.length; i++) self.connections[i].dehighlight();
|
||||
};
|
||||
|
||||
////////////////////////////////////
|
||||
// EVOLUTION ///////////////////////
|
||||
////////////////////////////////////
|
||||
|
@ -303,7 +351,7 @@ function Tournament(config){
|
|||
_playIndex = 0;
|
||||
_tweenTimer = 0;
|
||||
self.STAGE = STAGE_REST;
|
||||
// slideshow.objects._b2.activate(); // activate NEXT button!
|
||||
publish("tournament/step/completed", ["play"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,8 +362,8 @@ function Tournament(config){
|
|||
if(_tweenTimer==_s(0.3)){
|
||||
_tweenTimer = 0;
|
||||
self.STAGE = STAGE_REST;
|
||||
publish("tournament/step/completed", ["eliminate"]);
|
||||
}
|
||||
// slideshow.objects._b3.activate(); // activate NEXT button!
|
||||
}
|
||||
|
||||
// REPRODUCE!
|
||||
|
@ -340,7 +388,7 @@ function Tournament(config){
|
|||
if(_tweenTimer>=1){
|
||||
_tweenTimer = 0;
|
||||
self.STAGE = STAGE_REST;
|
||||
// slideshow.objects._b1.activate(); // activate NEXT button!
|
||||
publish("tournament/step/completed", ["reproduce"]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -348,24 +396,16 @@ function Tournament(config){
|
|||
});
|
||||
|
||||
// PLAY A TOURNAMENT
|
||||
self.deactivateAllButtons = function(){
|
||||
// slideshow.objects._b1.deactivate();
|
||||
// slideshow.objects._b2.deactivate();
|
||||
// slideshow.objects._b3.deactivate();
|
||||
};
|
||||
self._startPlay = function(){
|
||||
self.STAGE=STAGE_PLAY;
|
||||
// self.deactivateAllButtons();
|
||||
};
|
||||
listen(self, "tournament/play", self._startPlay);
|
||||
self._startEliminate = function(){
|
||||
self.STAGE=STAGE_ELIMINATE;
|
||||
// self.deactivateAllButtons();
|
||||
};
|
||||
listen(self, "tournament/eliminate", self._startEliminate);
|
||||
self._startReproduce = function(){
|
||||
self.STAGE=STAGE_REPRODUCE;
|
||||
// self.deactivateAllButtons();
|
||||
};
|
||||
listen(self, "tournament/reproduce", self._startReproduce);
|
||||
|
||||
|
@ -402,24 +442,46 @@ function TournamentConnection(config){
|
|||
self.to.connections.push(self);
|
||||
|
||||
// Graphics!
|
||||
var g = new PIXI.Container();
|
||||
var gray = PIXI.Sprite.fromImage("assets/tournament/connection.png"); // TODO: PRELOAD
|
||||
var gold = PIXI.Sprite.fromImage("assets/tournament/connection_gold.png"); // TODO: PRELOAD
|
||||
gray.height = 1;
|
||||
gold.height = 2;
|
||||
gray.anchor.y = gold.anchor.y = 0.5;
|
||||
g.addChild(gray);
|
||||
g.addChild(gold);
|
||||
var g;
|
||||
if(Tournament.FLOWER_CONNECTIONS){
|
||||
g = _makeMovieClip("connection_flower");
|
||||
g.anchor.x = 0;
|
||||
g.anchor.y = 0;
|
||||
g.scale.set(0.5);
|
||||
}else{
|
||||
g = _makeMovieClip("connection");
|
||||
g.anchor.x = 0;
|
||||
g.anchor.y = 0.5;
|
||||
g.height = 1;
|
||||
}
|
||||
self.graphics = g;
|
||||
var _flowerLong = false;
|
||||
var _updateFlower = function(highlight){
|
||||
var frame = 0;
|
||||
if(highlight) frame+=2;
|
||||
if(_flowerLong) frame+=1;
|
||||
g.gotoAndStop(frame);
|
||||
};
|
||||
if(config.flower_flip){
|
||||
g.scale.y *= -1;
|
||||
}
|
||||
|
||||
// Highlight or no?
|
||||
self.highlight = function(){
|
||||
gray.visible = false;
|
||||
gold.visible = true;
|
||||
if(Tournament.FLOWER_CONNECTIONS){
|
||||
_updateFlower(true);
|
||||
}else{
|
||||
g.height = 3;
|
||||
g.gotoAndStop(1);
|
||||
}
|
||||
};
|
||||
self.dehighlight = function(){
|
||||
gray.visible = true;
|
||||
gold.visible = false;
|
||||
if(Tournament.FLOWER_CONNECTIONS){
|
||||
_updateFlower(false);
|
||||
}else{
|
||||
g.height = 1;
|
||||
g.gotoAndStop(0);
|
||||
}
|
||||
};
|
||||
self.dehighlight();
|
||||
|
||||
|
@ -435,9 +497,28 @@ function TournamentConnection(config){
|
|||
|
||||
g.x = f.x;
|
||||
g.y = f.y;
|
||||
g.rotation = a;
|
||||
|
||||
gray.width = gold.width = dist;
|
||||
if(Tournament.FLOWER_CONNECTIONS){
|
||||
if(dist<250){
|
||||
_flowerLong = false;
|
||||
if(config.flower_flip){
|
||||
g.rotation = a+Math.TAU/10;
|
||||
}else{
|
||||
g.rotation = a-Math.TAU/10;
|
||||
}
|
||||
}else{
|
||||
_flowerLong = true;
|
||||
if(config.flower_flip){
|
||||
g.rotation = a+Math.TAU/5;
|
||||
}else{
|
||||
g.rotation = a-Math.TAU/5;
|
||||
}
|
||||
}
|
||||
_updateFlower();
|
||||
}else{
|
||||
g.rotation = a;
|
||||
g.width = dist;
|
||||
}
|
||||
|
||||
};
|
||||
self.updateGraphics();
|
||||
|
|
|
@ -113,16 +113,16 @@ SLIDES.push({
|
|||
_hide(o.info);
|
||||
|
||||
// ROUNDS
|
||||
/*var ROUNDS = [
|
||||
var ROUNDS = [
|
||||
{id:"tft", num:1},
|
||||
];*/ // FOR TESTING
|
||||
var ROUNDS = [ // and min & max score...
|
||||
]; // FOR TESTING
|
||||
/*var ROUNDS = [ // and min & max score...
|
||||
{id:"tft", num:5}, // min 3, max 11
|
||||
{id:"all_d", num:4}, // min -4, max 0
|
||||
{id:"all_c", num:4}, // min 8, max 12
|
||||
{id:"grudge", num:5}, // min -1, max 11
|
||||
{id:"prober", num:7} // min 2, max 15
|
||||
]; // TOTAL... MIN 8, MAX 49
|
||||
]; // TOTAL... MIN 8, MAX 49*/
|
||||
ROUND_INDEX = 0;
|
||||
ROUND_NUM = 0;
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ SLIDES.push({
|
|||
onstart: function(self){
|
||||
|
||||
// Tournament
|
||||
Tournament.resetGlobalVariables();
|
||||
Tournament.INITIAL_AGENTS = [
|
||||
{strategy:"tft", count:1},
|
||||
{strategy:"all_d", count:1},
|
||||
|
@ -11,6 +12,7 @@ SLIDES.push({
|
|||
{strategy:"grudge", count:1},
|
||||
{strategy:"prober", count:1}
|
||||
];
|
||||
Tournament.FLOWER_CONNECTIONS = true;
|
||||
self.add({id:"tournament", type:"Tournament", x:-20, y:20});
|
||||
|
||||
// Words to the side
|
||||
|
@ -21,37 +23,142 @@ SLIDES.push({
|
|||
});
|
||||
|
||||
// Button
|
||||
var _addButton = function(character, x, y){
|
||||
(function(character, x, y){
|
||||
self.add({
|
||||
id:"button", type:"Button",
|
||||
x:510, y:400,
|
||||
text_id:"label_tft",
|
||||
id:"bet_"+character, type:"Button", x:x, y:y,
|
||||
text_id: "icon_"+character,
|
||||
onclick:function(){
|
||||
_.answer = "tft";
|
||||
_.answer = character;
|
||||
publish("slideshow/next");
|
||||
}
|
||||
});
|
||||
})(character, x, y);
|
||||
};
|
||||
_addButton("tft", 510, 220+25);
|
||||
_addButton("all_c", 730, 220+25);
|
||||
_addButton("all_d", 510, 300+25);
|
||||
_addButton("grudge", 730, 300+25);
|
||||
_addButton("prober", 510, 380+25);
|
||||
|
||||
},
|
||||
onend: function(self){
|
||||
self.remove("bet_tft");
|
||||
self.remove("bet_all_c");
|
||||
self.remove("bet_all_d");
|
||||
self.remove("bet_grudge");
|
||||
self.remove("bet_prober");
|
||||
}
|
||||
});
|
||||
|
||||
// Alright, let's start!
|
||||
SLIDES.push({
|
||||
onstart: function(self){
|
||||
|
||||
var o = self.objects;
|
||||
|
||||
// What was your bet?
|
||||
var tournament_intro = Words.get("tournament_intro");
|
||||
tournament_intro = tournament_intro.replace(/\[CHAR\]/g, "<span class='"+_.answer+"'>"+Words.get("label_"+_.answer)+"</span>");
|
||||
o.text.setText(tournament_intro);
|
||||
_hide(o.text); _fadeIn(o.text, 100);
|
||||
|
||||
// "First Match" Button
|
||||
self.add({
|
||||
id:"button", type:"Button",
|
||||
x:510, y:130,
|
||||
text_id:"first_match",
|
||||
message: "slideshow/next"
|
||||
});
|
||||
_hide(o.button); _fadeIn(o.button, 100+500);
|
||||
|
||||
},
|
||||
onend: function(self){
|
||||
self.remove("text");
|
||||
self.remove("button");
|
||||
}
|
||||
});
|
||||
|
||||
// go through it ONE BY ONE
|
||||
// The matches... ONE BY ONE.
|
||||
SLIDES.push({
|
||||
onstart: function(self){
|
||||
|
||||
// Button
|
||||
var o = self.objects;
|
||||
|
||||
var showTournament = function(num){
|
||||
|
||||
var words = "";
|
||||
var match_header;
|
||||
|
||||
// PLAY MATCH
|
||||
var matchData = o.tournament.playMatch(num);
|
||||
var charA = matchData.charA;
|
||||
var charB = matchData.charB;
|
||||
var scoreA = matchData.scoreA
|
||||
var scoreB = matchData.scoreB;
|
||||
var roundPayoffs = matchData.payoffs;
|
||||
|
||||
// Match N: [A] versus [B]
|
||||
match_header = Words.get("match_header_1");
|
||||
match_header = match_header.replace(/\[N\]/g, (num+1)+"");
|
||||
match_header = match_header.replace(/\[A\]/g, "<span class='"+charA+"'>"+Words.get("label_"+charA)+"</span>");
|
||||
match_header = match_header.replace(/\[B\]/g, "<span class='"+charB+"'>"+Words.get("label_"+charB)+"</span>");
|
||||
words += match_header+"<br>";
|
||||
|
||||
// The rounds
|
||||
words += Words.get("match_header_2")+"<br>";
|
||||
for(var i=0;i<roundPayoffs.length;i++){
|
||||
var payoff = roundPayoffs[i][0];
|
||||
if(payoff==PD.PAYOFFS.P) payoff="P"; // Punishment
|
||||
if(payoff==PD.PAYOFFS.R) payoff="R"; // Reward
|
||||
if(payoff==PD.PAYOFFS.S) payoff="S"; // Sucker
|
||||
if(payoff==PD.PAYOFFS.T) payoff="T"; // Temptation
|
||||
words += "<span class='score_small' payoff='"+payoff+"'></span>";
|
||||
}
|
||||
words += "<br>";
|
||||
|
||||
// The total scores
|
||||
if(scoreA>0) scoreA="+"+scoreA;
|
||||
if(scoreB>0) scoreB="+"+scoreB;
|
||||
match_header = Words.get("match_header_3");
|
||||
match_header = match_header.replace(/\[A\]/g, "<span class='"+charA+"'>"+scoreA+"</span>");
|
||||
match_header = match_header.replace(/\[B\]/g, "<span class='"+charB+"'>"+scoreB+"</span>");
|
||||
words += match_header+"<br><br><br>";
|
||||
|
||||
// Extra info
|
||||
words += Words.get("tournament_"+(num+1));
|
||||
|
||||
// PUT IN THE WORDS
|
||||
o.text.setText(words);
|
||||
_hide(o.text); _fadeIn(o.text, 100);
|
||||
|
||||
// FINAL MATCH?
|
||||
if(_matchNumber==9){
|
||||
_switchButton();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// MATCH NUMBER!
|
||||
_matchNumber = 0;
|
||||
showTournament(_matchNumber);
|
||||
|
||||
// "Next Match" Button
|
||||
self.add({
|
||||
id:"button", type:"Button",
|
||||
x:510, y:400,
|
||||
x:510, y:420, size:"long",
|
||||
text_id:"next_match",
|
||||
onclick:function(){
|
||||
_.answer = "tft";
|
||||
publish("slideshow/next");
|
||||
_matchNumber++;
|
||||
showTournament(_matchNumber);
|
||||
}
|
||||
});
|
||||
var _switchButton = function(){
|
||||
o.button.setText("the_winner_is");
|
||||
o.button.config.onclick = function(){
|
||||
publish("slideshow/next");
|
||||
};
|
||||
};
|
||||
_hide(o.button); _fadeIn(o.button, 100+500);
|
||||
|
||||
},
|
||||
onend: function(self){
|
||||
|
@ -63,20 +170,33 @@ SLIDES.push({
|
|||
SLIDES.push({
|
||||
onstart: function(self){
|
||||
|
||||
// Words to the side
|
||||
self.add({
|
||||
id:"text", type:"TextBox",
|
||||
x:510, y:30, width:450, height:500,
|
||||
text_id:"tournament_winner"
|
||||
});
|
||||
var o = self.objects;
|
||||
o.tournament.dehighlightAllConnections();
|
||||
|
||||
// Button
|
||||
// WORDS
|
||||
var words = "";
|
||||
words += Words.get("tournament_winner_1");
|
||||
if(_.answer=="tft"){
|
||||
words += Words.get("tournament_winner_2_yay");
|
||||
}else{
|
||||
words += Words.get("tournament_winner_2_nay").replace(/\[CHAR\]/g, "<span class='"+_.answer+"'>"+Words.get("label_"+_.answer)+"</span>");
|
||||
}
|
||||
words += "<br><br>";
|
||||
words += Words.get("tournament_winner_3");
|
||||
o.text.setText(words);
|
||||
|
||||
// Next...
|
||||
self.add({
|
||||
id:"button", type:"Button", x:385, y:466,
|
||||
text_id:"tournament_teaser", fontSize:16, upperCase:false,
|
||||
id:"button", type:"Button",
|
||||
x:510, y:430, size:"long",
|
||||
text_id:"tournament_teaser",
|
||||
message: "slideshow/scratch"
|
||||
});
|
||||
|
||||
// FADE
|
||||
_hide(o.text); _fadeIn(o.text, 100);
|
||||
_hide(o.button); _fadeIn(o.button, 100+500);
|
||||
|
||||
},
|
||||
onend: function(self){
|
||||
self.clear();
|
||||
|
|
|
@ -3,17 +3,44 @@ SLIDES.push({
|
|||
id: "evolution",
|
||||
onstart: function(self){
|
||||
|
||||
// Words to the side
|
||||
// WORDS
|
||||
self.add({
|
||||
id:"text", type:"TextBox",
|
||||
x:510, y:30, width:450, height:500,
|
||||
id:"text1", type:"TextBox",
|
||||
x:0, y:20, width:774, height:42,
|
||||
text_id:"evolution_intro"
|
||||
});
|
||||
self.add({
|
||||
id:"text2", type:"TextBox",
|
||||
x:0, y:235, width:287, height:117, align:"center",
|
||||
text_id:"evolution_intro_1"
|
||||
});
|
||||
self.add({
|
||||
id:"text3", type:"TextBox",
|
||||
x:336, y:235, width:287, height:117, align:"center",
|
||||
text_id:"evolution_intro_2"
|
||||
});
|
||||
self.add({
|
||||
id:"text4", type:"TextBox",
|
||||
x:669, y:235, width:287, height:117, align:"center",
|
||||
text_id:"evolution_intro_3"
|
||||
});
|
||||
self.add({
|
||||
id:"text5", type:"TextBox",
|
||||
x:132, y:370, width:817, height:95, align:"right",
|
||||
text_id:"evolution_intro_footer"
|
||||
});
|
||||
|
||||
// IMAGE
|
||||
self.add({
|
||||
id:"img", type:"ImageBox",
|
||||
src: "assets/evolution/evolution_intro.png",
|
||||
x:0, y:60, width:960, height:170
|
||||
});
|
||||
|
||||
// Button
|
||||
self.add({
|
||||
id:"button", type:"Button", x:385, y:466,
|
||||
text_id:"evolution_intro_button", fontSize:16, upperCase:false,
|
||||
id:"button", type:"Button", x:615, y:466,
|
||||
text_id:"evolution_intro_button", size:"long",
|
||||
message:"slideshow/scratch"
|
||||
});
|
||||
|
||||
|
@ -28,6 +55,7 @@ SLIDES.push({
|
|||
onstart: function(self){
|
||||
|
||||
// Tournament
|
||||
Tournament.resetGlobalVariables();
|
||||
Tournament.INITIAL_AGENTS = [
|
||||
{strategy:"all_c", count:15},
|
||||
{strategy:"all_d", count:5},
|
||||
|
@ -39,45 +67,249 @@ SLIDES.push({
|
|||
self.add({
|
||||
id:"text", type:"TextBox",
|
||||
x:510, y:30, width:450, height:500,
|
||||
text_id:"evo_bets"
|
||||
text_id:"evo_1"
|
||||
});
|
||||
|
||||
// Button
|
||||
// BETS
|
||||
var _addButton = function(character, x, y){
|
||||
(function(character, x, y){
|
||||
self.add({
|
||||
id:"button_step", type:"Button",
|
||||
x:510, y:300, size:"short",
|
||||
text_id:"button_step",
|
||||
message: "tournament/step"
|
||||
});
|
||||
|
||||
// Button
|
||||
self.add({
|
||||
id:"button_next", type:"Button",
|
||||
x:510, y:400, size:"short",
|
||||
text_id:"label_next",
|
||||
id:"bet_"+character, type:"Button", x:x, y:y,
|
||||
text_id: "icon_"+character,
|
||||
onclick:function(){
|
||||
_.answer = "tft";
|
||||
publish("slideshow/scratch");
|
||||
_.answer = character;
|
||||
publish("slideshow/next");
|
||||
}
|
||||
});
|
||||
})(character, x, y);
|
||||
};
|
||||
_addButton("all_c", 510, 295);
|
||||
_addButton("all_d", 510, 295+70);
|
||||
_addButton("tft", 510, 295+70*2);
|
||||
|
||||
},
|
||||
onend: function(self){
|
||||
self.clear();
|
||||
self.remove("bet_tft");
|
||||
self.remove("bet_all_c");
|
||||
self.remove("bet_all_d");
|
||||
}
|
||||
});
|
||||
|
||||
// Result: First Round
|
||||
// Result: ROUNDS ALL THE WAY 'TIL THE END
|
||||
SLIDES.push({
|
||||
onstart: function(self){
|
||||
|
||||
// Result: Second Round
|
||||
var o = self.objects;
|
||||
|
||||
// Result: til the end...
|
||||
// What was your bet?
|
||||
var response = Words.get("evo_2_"+_.answer)+" "+Words.get("evo_2");
|
||||
o.text.setText(response);
|
||||
_hide(o.text); _fadeIn(o.text, 100);
|
||||
|
||||
// Explanation
|
||||
// The tournament control buttons
|
||||
var x = 510;
|
||||
var y = 200;
|
||||
var nextStep;
|
||||
var textStep = 2;
|
||||
// var textStep = 8;
|
||||
self.add({
|
||||
id:"step_1", type:"Button", x:x, y:y,
|
||||
text_id: "label_play_tournament", size:"long",
|
||||
onclick:function(){
|
||||
o.step_1.deactivate();
|
||||
nextStep = o.step_2;
|
||||
publish("tournament/play");
|
||||
}
|
||||
});
|
||||
self.add({
|
||||
id:"step_2", type:"Button", x:x, y:y+70,
|
||||
text_id: "label_eliminate_bottom_5", size:"long",
|
||||
onclick:function(){
|
||||
o.step_2.deactivate();
|
||||
nextStep = o.step_3;
|
||||
publish("tournament/eliminate");
|
||||
},
|
||||
active: false
|
||||
});
|
||||
self.add({
|
||||
id:"step_3", type:"Button", x:x, y:y+70*2,
|
||||
text_id: "label_reproduce_top_5", size:"long",
|
||||
onclick:function(){
|
||||
o.step_3.deactivate();
|
||||
nextStep = o.step_1;
|
||||
publish("tournament/reproduce");
|
||||
},
|
||||
active: false
|
||||
});
|
||||
listen(_, "tournament/step/completed", function(step){
|
||||
nextStep.activate();
|
||||
if(step=="reproduce"){
|
||||
textStep++;
|
||||
var response;
|
||||
if(textStep<9){
|
||||
if(textStep==3){
|
||||
response = Words.get("evo_3_"+_.answer)+" "+Words.get("evo_3");
|
||||
}else{
|
||||
response = Words.get("evo_"+textStep);
|
||||
}
|
||||
o.text.setText(response);
|
||||
_hide(o.text); _fadeIn(o.text, 100);
|
||||
_showButtons();
|
||||
}else{
|
||||
publish("slideshow/next");
|
||||
}
|
||||
}
|
||||
});
|
||||
var _showButtons = function(){
|
||||
_hide(o.step_1); _fadeIn(o.step_1, 500);
|
||||
_hide(o.step_2); _fadeIn(o.step_2, 600);
|
||||
_hide(o.step_3); _fadeIn(o.step_3, 700);
|
||||
};
|
||||
_showButtons();
|
||||
|
||||
},
|
||||
onend: function(self){
|
||||
unlisten(_);
|
||||
self.remove("step_1");
|
||||
self.remove("step_2");
|
||||
self.remove("step_3");
|
||||
}
|
||||
});
|
||||
|
||||
// Result Explanation
|
||||
SLIDES.push({
|
||||
onstart: function(self){
|
||||
|
||||
var o = self.objects;
|
||||
|
||||
// What was your bet?
|
||||
var response = Words.get("evo_9")+"<br><br>"+Words.get("evo_9_"+_.answer)+" "+Words.get("evo_9_end");
|
||||
o.text.setText(response);
|
||||
_hide(o.text); _fadeIn(o.text, 100);
|
||||
|
||||
// Oh by the way...
|
||||
self.add({
|
||||
id:"button", type:"Button", x:510, y:320,
|
||||
text_id:"evo_9_btn", size:"long",
|
||||
message: "slideshow/next"
|
||||
});
|
||||
_hide(o.button); _fadeIn(o.button, 400);
|
||||
|
||||
},
|
||||
onend: function(self){
|
||||
self.remove("button");
|
||||
}
|
||||
});
|
||||
|
||||
// (Yup, even w Grudgers & Detectives)
|
||||
SLIDES.push({
|
||||
onstart: function(self){
|
||||
|
||||
// Tournament
|
||||
var o = self.objects;
|
||||
Tournament.resetGlobalVariables();
|
||||
Tournament.INITIAL_AGENTS = [
|
||||
{strategy:"all_c", count:5},
|
||||
{strategy:"all_d", count:5},
|
||||
{strategy:"tft", count:5},
|
||||
{strategy:"grudge", count:5},
|
||||
{strategy:"prober", count:6}
|
||||
];
|
||||
o.tournament.reset();
|
||||
_hide(o.tournament); _fadeIn(o.tournament, 10);
|
||||
|
||||
// The same with grudger & detetive!
|
||||
o.text.setTextID("evo_10");
|
||||
_hide(o.text); _fadeIn(o.text, 400);
|
||||
|
||||
// Button: start/stop
|
||||
var isPlaying = false;
|
||||
self.add({
|
||||
id:"autoplay", type:"Button", x:510, y:100,
|
||||
text_id:"evo_autoplay", size:"long",
|
||||
onclick: function(){
|
||||
if(!isPlaying){
|
||||
o.autoplay.setText("evo_autoplay_stop");
|
||||
publish("tournament/autoplay/start");
|
||||
isPlaying = true;
|
||||
}else{
|
||||
o.autoplay.setText("evo_autoplay");
|
||||
publish("tournament/autoplay/stop");
|
||||
isPlaying = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
_hide(o.autoplay); _fadeIn(o.autoplay, 600);
|
||||
|
||||
// Listen...
|
||||
var step = 0;
|
||||
listen(_, "tournament/step/completed", function(aahhhh){
|
||||
step++;
|
||||
if(step==13){
|
||||
_goOn();
|
||||
}
|
||||
});
|
||||
|
||||
var _goOn = function(){
|
||||
|
||||
// Text followup (hidden)
|
||||
self.add({
|
||||
id:"text2", type:"TextBox",
|
||||
x:510, y:180, width:450, height:500,
|
||||
text_id:"evo_10_followup"
|
||||
});
|
||||
_hide(o.text2); _fadeIn(o.text2, 400);
|
||||
|
||||
// Button: next (hidden)
|
||||
self.add({
|
||||
id:"next", type:"Button", x:510, y:450,
|
||||
text_id:"evo_10_btn", size:"long",
|
||||
message: "slideshow/next"
|
||||
});
|
||||
_hide(o.next); _fadeIn(o.next, 600);
|
||||
|
||||
};
|
||||
|
||||
},
|
||||
onend: function(self){
|
||||
unlisten(_);
|
||||
self.remove("autoplay");
|
||||
self.remove("text2");
|
||||
self.remove("next");
|
||||
}
|
||||
});
|
||||
|
||||
// Problem 1: Number of interactions
|
||||
SLIDES.push({
|
||||
onstart: function(self){
|
||||
var o = self.objects;
|
||||
|
||||
// Oh no
|
||||
Tournament.resetGlobalVariables();
|
||||
Tournament.INITIAL_AGENTS = [
|
||||
{strategy:"all_d", count:24},
|
||||
{strategy:"tft", count:1}
|
||||
];
|
||||
o.tournament.reset();
|
||||
|
||||
// Text
|
||||
o.text.setTextID("evo_11");
|
||||
_hide(o.text); _fadeIn(o.text, 200);
|
||||
|
||||
// Next
|
||||
self.add({
|
||||
id:"next", type:"Button", x:510, y:415,
|
||||
text_id:"evo_11_btn", size:"long",
|
||||
message: "slideshow/next"
|
||||
});
|
||||
_hide(o.next); _fadeIn(o.next, 500);
|
||||
|
||||
},
|
||||
onend: function(self){
|
||||
self.remove("text");
|
||||
self.remove("next");
|
||||
}
|
||||
});
|
||||
|
||||
// Problem 2: Payoffs
|
||||
|
||||
|
|
|
@ -10,10 +10,15 @@ SLIDES.push({
|
|||
// Screw it, just ALL of the Sandbox UI
|
||||
self.add({id:"sandbox", type:"SandboxUI"});
|
||||
|
||||
// Button for next...
|
||||
// Label & Button for next...
|
||||
self.add({
|
||||
id:"label_next", type:"TextBox",
|
||||
x:14, y:481, width:800, align:"right",
|
||||
text_id: "sandbox_end"
|
||||
});
|
||||
self.add({
|
||||
id:"button_next", type:"Button",
|
||||
x:510, y:500,
|
||||
x:831, y:465, size:"short",
|
||||
text_id:"label_next",
|
||||
message: "slideshow/scratch"
|
||||
});
|
||||
|
|
353
lang/en.html
353
lang/en.html
|
@ -2,6 +2,8 @@
|
|||
<!-- - - - - - INTRO! - - - - - - - - -->
|
||||
<!-- - - - - - - - - - - - - - - - - -->
|
||||
|
||||
<!-- TODO: Focus ONLY on social trust, not governments -->
|
||||
|
||||
<p id="intro">
|
||||
During World War I, peace broke out.
|
||||
<br><br>
|
||||
|
@ -117,6 +119,8 @@ But what happens if we can...
|
|||
<!-- - - - - - ITERATED - - - - - - - -->
|
||||
<!-- - - - - - - - - - - - - - - - - -->
|
||||
|
||||
<!-- TO DO: WEAVE IN MORE ABOUT TRENCHES. "CHOOSE WISELY" -->
|
||||
|
||||
<p id="iterated_intro_top">
|
||||
<b>Now, let's play for real.</b><br>
|
||||
You'll be playing against 5 different opponents, each with their own "personality".
|
||||
|
@ -182,15 +186,15 @@ Let's be best friends! <3
|
|||
|
||||
<p id="character_grudge">
|
||||
<b>GRUDGER:</b>
|
||||
Listen, stranger. I'll start cooperatin', and keep cooperation',
|
||||
but if y'all ever cheat me, I'LL CHEAT YOU BACK TIL THE END OF DAYS.
|
||||
Listen, pardner. I'll start cooperatin', and keep cooperation',
|
||||
but if y'all ever cheat me, I'LL CHEAT YOU BACK 'TIL THE END OF TARNATION.
|
||||
</p>
|
||||
|
||||
<p id="character_prober">
|
||||
<b>DETECTIVE:</b>
|
||||
First: I analyze you. I start: Cooperate, Cheat, Cooperate, Cooperate.
|
||||
If you cheat back, I'll act like Copycat.
|
||||
If you never cheat back, I'll act like Always Cheat, to exploit you.
|
||||
If you cheat back, I'll act like <span class="tft">Copycat</span>.
|
||||
If you never cheat back, I'll act like <span class="all_d">Always Cheat</span>, to exploit you.
|
||||
Elementary, my dear Watson.
|
||||
</p>
|
||||
|
||||
|
@ -208,31 +212,93 @@ Now, what if these characters were to play...
|
|||
|
||||
<p id="place_your_bets">
|
||||
It's tournament time!
|
||||
These five characters will now play against each other – 10 paired games, 10 rounds per game.
|
||||
Each character will now play against every other character:
|
||||
that's 10 paired matches, and 10 rounds per match.
|
||||
<br><br>
|
||||
Place your bets: who do you think will get the highest *total* score?
|
||||
Who do you think will get the highest <i>total</i> score?
|
||||
Think carefully about it, and then<br>
|
||||
<b>PLACE YOUR BETS:</b>
|
||||
</p>
|
||||
|
||||
<p id="tournament_intro">
|
||||
Alright, you placed your bet on [CHAR]!
|
||||
Let's go through the matches one by one, and see how the tournament plays out...
|
||||
</p>
|
||||
|
||||
<p id="first_match">
|
||||
first match →
|
||||
</p>
|
||||
|
||||
<p id="next_match">
|
||||
next match
|
||||
next match →
|
||||
</p>
|
||||
|
||||
<p id="tournament_winner">
|
||||
COPYCAT! (Note: this play-style is also known in game theory as "Tit For Tat")
|
||||
<br><br>
|
||||
<p id="match_header_1">
|
||||
<b>Match #[N]:</b> [A] vs [B]
|
||||
</p>
|
||||
<p id="match_header_2">
|
||||
<b>Rounds:</b>
|
||||
</p>
|
||||
<p id="match_header_3">
|
||||
<b>Total Scores:</b> [A] vs [B]
|
||||
</p>
|
||||
|
||||
<p id="tournament_1">
|
||||
|
||||
</p>
|
||||
<p id="tournament_2">
|
||||
Oh, by the way...
|
||||
</p>
|
||||
<p id="tournament_3">
|
||||
[trench live & let live stuff]
|
||||
</p>
|
||||
<p id="tournament_4">
|
||||
[trench live & let live stuff]
|
||||
</p>
|
||||
<p id="tournament_5">
|
||||
[trench live & let live stuff]
|
||||
</p>
|
||||
<p id="tournament_6">
|
||||
[trench live & let live stuff]
|
||||
</p>
|
||||
<p id="tournament_7">
|
||||
[trench live & let live stuff]
|
||||
</p>
|
||||
<p id="tournament_8">
|
||||
[trench live & let live stuff]
|
||||
</p>
|
||||
<p id="tournament_9">
|
||||
[trench live & let live stuff]
|
||||
</p>
|
||||
<p id="tournament_10">
|
||||
Anyway -- and the winner is...
|
||||
</p>
|
||||
|
||||
<p id="the_winner_is">
|
||||
(drumroll please...) →
|
||||
</p>
|
||||
|
||||
<p id="tournament_winner_1">
|
||||
<b class="tft">COPYCAT!</b>
|
||||
</p>
|
||||
<p id="tournament_winner_2_yay">
|
||||
Congrats, you placed your bet on the right horse.
|
||||
<br><br>
|
||||
Sorry, //////.
|
||||
<br><br>
|
||||
Now, here's the strange thing: Copycat can _never_ beat another player in the trust game (because it never tries to take advantage of others), it can only ever do _as well as_ the other player. And yet overall, Copycat wins! This, despite being simpler than Detective, nicer than Always Cheat, and more forgiving than Grudger. It almost seems to imply that the Golden Rule is not just a moral truth, but a *mathematical* truth:
|
||||
<br><br>
|
||||
*Do unto others as you would have them do unto you.* ~Copycat
|
||||
<br><br>
|
||||
And *that's* why "peace" broke out in the trenches of World War I. Each side was playing a deadly game of trust with each other, but because the nature of trench warfare means they have to face the same group of soldiers over and over again, that allowed a Copycat-like strategy – the unspoken law of "live and let live" – to evolve.
|
||||
</p>
|
||||
|
||||
<p id="tournament_winner_2_nay">
|
||||
(Sorry, [CHAR].)
|
||||
</p>
|
||||
<p id="tournament_winner_3">
|
||||
<span class="tft">Copycat</span> goes by many names.
|
||||
The Golden Rule, reciprocal altruism, tit for tat, or... <i>live and let live.</i>
|
||||
That's why "peace" could emerge in the trenches of World War I:
|
||||
when you're forced to play the same game with the
|
||||
same <i>specific people</i> (not just the same generic "enemy") over and over again --
|
||||
<span class="tft">Copycat</span> doesn't just win the battle, it wins the war.
|
||||
<br><br>
|
||||
But if things change a lot when you play multiple rounds of the same game, what if we play...
|
||||
</p>
|
||||
<p id="tournament_teaser">
|
||||
...but does Copycat *always* win? →
|
||||
...multiple <i>tournaments?</i> →
|
||||
</p>
|
||||
|
||||
|
||||
|
@ -241,13 +307,185 @@ And *that's* why "peace" broke out in the trenches of World War I. Each side was
|
|||
<!-- - - - - - - - - - - - - - - - - -->
|
||||
|
||||
<p id="evolution_intro">
|
||||
Now, let's let our population of players <i>evolve over time</i>. It's a 3-step dance:
|
||||
</p>
|
||||
<p id="evolution_intro_1">
|
||||
<b>1. PLAY A TOURNAMENT</b><br>
|
||||
Let them all play against each other, and tally up their scores.
|
||||
</p>
|
||||
<p id="evolution_intro_2">
|
||||
<b>2. ELIMINATE LOSERS</b><br>
|
||||
Get rid of the 5 worst players. (if there's a tie, pick randomly between them)
|
||||
</p>
|
||||
<p id="evolution_intro_3">
|
||||
<b>3. REPRODUCE WINNERS</b><br>
|
||||
Clone the 5 best players. (if there's a tie, pick randomly between them)
|
||||
</p>
|
||||
<p id="evolution_intro_footer">
|
||||
...and REPEAT, for as long as you'd like.
|
||||
Note: you don't have to wait for people to literally die & reproduce for culture to evolve --
|
||||
all that's needed is that "unsuccessful" behaviors go away, and "successful" behaviors are imitated.
|
||||
So now...
|
||||
</p>
|
||||
|
||||
<p id="evolution_intro_button">
|
||||
...let's see this in action. →
|
||||
</p>
|
||||
|
||||
<p id="button_step">
|
||||
step
|
||||
<p id="evo_1">
|
||||
Say we start with the following population of players:
|
||||
<span class="all_c">15 Always Cooperates</span>,
|
||||
<span class="all_d">5 Always Cheats</span>, and
|
||||
<span class="tft">5 Copycats</span>.
|
||||
(We'll ignore <span class="grudge">Grudger</span> & <span class="prober">Detective</span> for now)
|
||||
<br><br>
|
||||
We're going to do the tournament-eliminate-reproduce dance a dozen times or so.
|
||||
Let's make another bet! Who do you think will win the <i>first</i> tournament?
|
||||
</p>
|
||||
|
||||
<p id="evo_2_all_c">
|
||||
Makes sense, <span class="all_c">Always Cooperate</span> outnumbers everyone else right now...
|
||||
</p>
|
||||
<p id="evo_2_all_d">
|
||||
Makes sense, <span class="all_d">Always Cheat</span> has a lot of <span class="all_c">Always Cooperates</span> to exploit...
|
||||
</p>
|
||||
<p id="evo_2_tft">
|
||||
Makes sense, <span class="tft">Copycat</span> won the tournament last time, why not again?...
|
||||
</p>
|
||||
<p id="evo_2">
|
||||
Let's see if you're correct:
|
||||
</p>
|
||||
|
||||
<p id="label_play_tournament">
|
||||
1) play tournament
|
||||
</p>
|
||||
<p id="label_eliminate_bottom_5">
|
||||
2) eliminate bottom 5
|
||||
</p>
|
||||
<p id="label_reproduce_top_5">
|
||||
3) reproduce top 5
|
||||
</p>
|
||||
|
||||
<p id="evo_3_all_c">
|
||||
Alas, <span class="all_c">Always Cooperate</span> got eaten up by
|
||||
<span class="all_d">Always Cheat</span>, whose numbers have now increased by 5.
|
||||
</p>
|
||||
<p id="evo_3_all_d">
|
||||
Sadly, you were correct! The <span class="all_d">Always Cheaters</span> won this time,
|
||||
and their numbers increased by 5.
|
||||
</p>
|
||||
<p id="evo_3_tft">
|
||||
Alas, <span class="tft">Copycat</span> did not win – but at least they didn't do as bad
|
||||
as <span class="all_c">Always Cooperate</span>, who got eaten up by <span class="all_d">Always Cheat</span>,
|
||||
whose numbers have now increased by 5.
|
||||
</p>
|
||||
<p id="evo_3">
|
||||
But let's try a few more rounds of this...
|
||||
</p>
|
||||
|
||||
<p id="evo_4">
|
||||
<span class="all_d">Always Cheat</span> is still growing,
|
||||
at the expense of <span class="all_c">Always Cooperate</span>...
|
||||
</p>
|
||||
|
||||
<p id="evo_5">
|
||||
And now, all the <span class="all_c">Always Cooperates</span> are dead.
|
||||
But, wait...
|
||||
</p>
|
||||
|
||||
<p id="evo_6">
|
||||
That's right: the <span class="all_d">Always Cheats</span> became a victim of their own success!
|
||||
They exploited the naive <span class="all_c">Always Cooperaters</span>,
|
||||
but once they ran out of them, they had to face the <span class="tft">Copycats</span>:
|
||||
who <i>are</i> nice, but not naive.
|
||||
</p>
|
||||
|
||||
<!-- TODO: Freeman-Dyson???? -->
|
||||
<!-- TODO: (other strategies will be introduced later) -->
|
||||
|
||||
<p id="evo_7">
|
||||
By simply copying the other player's moves,
|
||||
<span class="tft">Copycats</span> can play nice with each other,
|
||||
while <span class="all_d">Always Cheats</span> just cheat themselves.
|
||||
Not only that, but it also means <span class="tft">Copycat</span>
|
||||
can give <span class="all_d">Always Cheat</span>
|
||||
a taste of their own medicine.
|
||||
</p>
|
||||
|
||||
<p id="evo_8">
|
||||
And so, as a result...
|
||||
</p>
|
||||
|
||||
<p id="evo_9">
|
||||
...<span class="tft">Copycat</span> inherits the earth.
|
||||
</p>
|
||||
<p id="evo_9_all_c">
|
||||
So, although your bet was off -- the nice-but-naive <span class="all_c">Always Cooperaters</span>
|
||||
were doomed from the start -- in the end, a <i>smart</i> form of niceness prevailed,
|
||||
and the <span class="all_d">Always Cheaters</span> were squashed.
|
||||
</p>
|
||||
<p id="evo_9_all_d">
|
||||
So, in the short run you were right - <span class="all_d">Always Cheat</span> won the first few rounds,
|
||||
but in the end, its exploitativeness was its downfall.
|
||||
</p>
|
||||
<p id="evo_9_tft">
|
||||
So, in the long run, you were right - <span class="tft">Copycat</span> wins!
|
||||
<span class="all_d">Always Cheat</span> may have won in the short run,
|
||||
but its exploitativeness was its downfall.
|
||||
</p>
|
||||
<p id="evo_9_end">
|
||||
This reminds me of a quote:
|
||||
<br><br>
|
||||
<i>"We are punished by our sins, not for them."</i><br>
|
||||
~ Elbert Hubbard
|
||||
</p>
|
||||
<p id="evo_9_btn">
|
||||
(oh, and by the way...)
|
||||
</p>
|
||||
|
||||
<p id="evo_10">
|
||||
(...this result is similar even if we put
|
||||
<span class="grudge">Grudger</span> & <span class="prober">Detective</span> back in:)
|
||||
</p>
|
||||
|
||||
<p id="evo_autoplay">
|
||||
start the evolution process!
|
||||
</p>
|
||||
<p id="evo_autoplay_stop">
|
||||
stop the evolution process
|
||||
</p>
|
||||
|
||||
<!-- More reference to game theory earlier? -->
|
||||
<!-- TODO: More "me" and "I"??? -->
|
||||
|
||||
<p id="evo_10_followup">
|
||||
(Note: occasionally, a few <span class="grudge">Grudgers</span> may stick around,
|
||||
because when all players except <span class="grudge">Grudger</span> & <span class="tft">Copycat</span>
|
||||
are eliminated, the two tie.)
|
||||
<br><br>
|
||||
So, it seems the math of game theory is telling us something:
|
||||
that <span class="tft">Copycat's</span> philosophy,
|
||||
"Do unto others as you would have them do unto you", may be not just a
|
||||
<i>moral</i> truth, but also a <i>mathematical</i> truth.
|
||||
However...
|
||||
</p>
|
||||
<p id="evo_10_btn">
|
||||
...there's a problem: →
|
||||
</p>
|
||||
|
||||
<p id="evo_11">
|
||||
There are jerks. Look around.
|
||||
<br><br>
|
||||
If <span class="tft">Copycat</span> is the strategy in this repeated game of trust that's so powerful --
|
||||
that even soldiers in the trenches of World War I independently "evolved" a similar strategy --
|
||||
why, then, are there so many un-trusting, un-trustworthy people around?
|
||||
<br><br>
|
||||
A clue's in that sentence itself. "In <i>this</i> repeated game of trust."
|
||||
So far we've only talked about change in the players:
|
||||
what about <i>a change in the game?</i>
|
||||
What could lead to...
|
||||
</p>
|
||||
<p id="evo_11_btn">
|
||||
...the evolution of <i>distrust?</i>
|
||||
</p>
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - -->
|
||||
|
@ -293,6 +531,11 @@ After each tournament, eliminate the bottom [N] player & reproduce the top [
|
|||
In each round of a one-on-one game, there's a [N]% chance a player makes a mistake
|
||||
</p>
|
||||
|
||||
<p id="sandbox_end">
|
||||
...once you're done playing around in Sandbox Mode, click:
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - -->
|
||||
<!-- - - - - CONCLUSION! - - - - - - -->
|
||||
|
@ -322,40 +565,60 @@ blah blah blah blah<br>
|
|||
<!-- - - - - THE PLAYERS - - - - - - -->
|
||||
<!-- - - - - - - - - - - - - - - - - -->
|
||||
|
||||
<p id="label_tft">
|
||||
Copycat
|
||||
</p>
|
||||
<p id="label_tft">Copycat</p>
|
||||
<p id="label_short_tft">
|
||||
copycat
|
||||
</p>
|
||||
|
||||
<p id="label_all_d">
|
||||
Always Cheat
|
||||
<p id="icon_tft">
|
||||
<span class="tft">
|
||||
<span class="icon"></span>
|
||||
<span class="icon_label">Copycat</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p id="label_all_d">Always Cheat</p>
|
||||
<p id="label_short_all_d">
|
||||
cheater
|
||||
</p>
|
||||
|
||||
<p id="label_all_c">
|
||||
Always Cooperate
|
||||
<p id="icon_all_d">
|
||||
<span class="all_d">
|
||||
<span class="icon"></span>
|
||||
<span class="icon_label">All Cheat</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p id="label_all_c">Always Cooperate</p>
|
||||
<p id="label_short_all_c">
|
||||
cooperater
|
||||
</p>
|
||||
|
||||
<p id="label_grudge">
|
||||
Grudger
|
||||
<p id="icon_all_c">
|
||||
<span class="all_c">
|
||||
<span class="icon"></span>
|
||||
<span class="icon_label">All Cooperate</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p id="label_grudge">Grudger</p>
|
||||
<p id="label_short_grudge">
|
||||
grudger
|
||||
</p>
|
||||
|
||||
<p id="label_prober">
|
||||
Detective
|
||||
<p id="icon_grudge">
|
||||
<span class="grudge">
|
||||
<span class="icon"></span>
|
||||
<span class="icon_label">Grudger</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p id="label_prober">Detective</p>
|
||||
<p id="label_short_prober">
|
||||
detective
|
||||
</p>
|
||||
<p id="icon_prober">
|
||||
<span class="prober">
|
||||
<span class="icon"></span>
|
||||
<span class="icon_label">Detective</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p id="label_tf2t">
|
||||
Copykitten
|
||||
|
@ -419,20 +682,8 @@ payoffs
|
|||
rules
|
||||
</p>
|
||||
|
||||
<p id="label_play_tournament">
|
||||
1) play tournament
|
||||
</p>
|
||||
|
||||
<p id="label_eliminate_bottom_5">
|
||||
2) eliminate bottom 5
|
||||
</p>
|
||||
|
||||
<p id="label_reproduce_top_5">
|
||||
3) reproduce top 5
|
||||
</p>
|
||||
|
||||
<p id="label_next">
|
||||
next
|
||||
next →
|
||||
</p>
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue