NICE ANIMATION YO
This commit is contained in:
parent
27dd21b6a0
commit
2224888fc4
8 changed files with 431 additions and 157 deletions
Binary file not shown.
Before Width: | Height: | Size: 96 B After Width: | Height: | Size: 96 B |
BIN
assets/connection_gold.png
Normal file
BIN
assets/connection_gold.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 96 B |
BIN
assets/o0006.png
BIN
assets/o0006.png
Binary file not shown.
Before Width: | Height: | Size: 141 B |
|
@ -1,9 +1,15 @@
|
|||
@font-face{
|
||||
font-family: 'FuturaHandwritten';
|
||||
font-style: normal;
|
||||
src: url('FuturaHandwritten.ttf') format('truetype');
|
||||
}
|
||||
|
||||
body{
|
||||
margin:0;
|
||||
overflow: hidden;
|
||||
|
||||
background: url('paper@2x.png');
|
||||
background-size: 100px 100px;
|
||||
background: #fff; /*url('paper@2x.png');
|
||||
background-size: 100px 100px;*/
|
||||
}
|
||||
#main{
|
||||
width: 100%;
|
||||
|
@ -23,7 +29,7 @@ body{
|
|||
|
||||
#slideshow{
|
||||
/*background: #bada55;*/
|
||||
border: 1px solid rgba(0,0,0,0.2);
|
||||
/*border: 1px solid rgba(0,0,0,0.2);*/
|
||||
width:960px;
|
||||
height:540px;
|
||||
|
||||
|
@ -32,6 +38,9 @@ body{
|
|||
margin: auto;
|
||||
top:0; left:0; right:0; bottom:0;
|
||||
|
||||
/* Font */
|
||||
font-family: 'FuturaHandwritten';
|
||||
|
||||
}
|
||||
#slideshow .object{
|
||||
position: absolute;
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
<script src="js/lib/minpubsub.src.js"></script>
|
||||
<script src="js/lib/q.js"></script>
|
||||
<script src="js/lib/pixi.min.js"></script>
|
||||
<script>var createjs = window;</script>
|
||||
<script src="js/lib/tweenjs-0.6.2.min.js"></script>
|
||||
<script>Ticker.framerate=60;</script>
|
||||
|
||||
<!-- Core Engine -->
|
||||
<script src="js/core/Slideshow.js"></script>
|
||||
|
@ -27,6 +30,7 @@
|
|||
<script src="js/core/WordBox.js"></script>
|
||||
|
||||
<!-- Simulations -->
|
||||
<script src="js/sims/PD.js"></script>
|
||||
<script src="js/sims/SillyPixi.js"></script>
|
||||
<script src="js/sims/TournamentSim.js"></script>
|
||||
|
||||
|
@ -49,8 +53,8 @@ window.onload = function(){
|
|||
});
|
||||
|
||||
// First slide!
|
||||
slideshow.nextSlide();
|
||||
//slideshow.gotoSlide("intro3");
|
||||
//slideshow.nextSlide();
|
||||
slideshow.gotoSlide("intro1");
|
||||
|
||||
};
|
||||
</script>
|
12
js/lib/tweenjs-0.6.2.min.js
vendored
Normal file
12
js/lib/tweenjs-0.6.2.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
114
js/sims/PD.js
Normal file
114
js/sims/PD.js
Normal file
|
@ -0,0 +1,114 @@
|
|||
var PD = {};
|
||||
PD.COOPERATE = "COOPERATE";
|
||||
PD.CHEAT = "CHEAT";
|
||||
|
||||
PD.P = 0; // punishment: neither of you get anything
|
||||
PD.S = -1; // sucker: you put in coin, other didn't.
|
||||
PD.R = 2; // reward: you both put 1 coin in, both got 3 back
|
||||
PD.T = 3; // temptation: you put no coin, got 3 coins anyway
|
||||
|
||||
PD.getPayoffs = function(move1, move2){
|
||||
if(move1==PD.CHEAT && move2==PD.CHEAT) return [PD.P, PD.P]; // both punished
|
||||
if(move1==PD.COOPERATE && move2==PD.CHEAT) return [PD.S, PD.T]; // sucker - temptation
|
||||
if(move1==PD.CHEAT && move2==PD.COOPERATE) return [PD.T, PD.S]; // temptation - sucker
|
||||
if(move1==PD.COOPERATE && move2==PD.COOPERATE) return [PD.R, PD.R]; // both rewarded
|
||||
};
|
||||
|
||||
PD.playOneGame = function(playerA, playerB){
|
||||
|
||||
var A = playerA.play();
|
||||
var B = playerB.play();
|
||||
|
||||
var payoffs = PD.getPayoffs(A,B);
|
||||
|
||||
playerA.remember(B);
|
||||
playerB.remember(A);
|
||||
|
||||
playerA.addPayoff(payoffs[0]);
|
||||
playerB.addPayoff(payoffs[1]);
|
||||
|
||||
};
|
||||
|
||||
PD.playRepeatedGame = function(playerA, playerB, turns){
|
||||
|
||||
// I've never met you before, let's pretend
|
||||
playerA.resetLogic();
|
||||
playerB.resetLogic();
|
||||
|
||||
// Play N turns
|
||||
for(var i=0; i<turns; i++){
|
||||
PD.playOneGame(playerA, playerB);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
PD.playOneTournament = function(agents, turns){
|
||||
|
||||
// Reset everyone's coins
|
||||
for(var i=0; i<agents.length; i++){
|
||||
agents[i].resetCoins();
|
||||
}
|
||||
|
||||
// Round robin!
|
||||
for(var i=0; i<agents.length; i++){
|
||||
var playerA = agents[i];
|
||||
for(var j=i+1; j<agents.length; j++){
|
||||
var playerB = agents[j];
|
||||
PD.playRepeatedGame(playerA, playerB, turns);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
function Logic_tft(){
|
||||
var self = this;
|
||||
var otherMove = PD.COOPERATE;
|
||||
self.play = function(){
|
||||
return otherMove;
|
||||
};
|
||||
self.remember = function(other){
|
||||
otherMove = other;
|
||||
};
|
||||
}
|
||||
function Logic_grim(){
|
||||
var self = this;
|
||||
var everCheatedMe = false;
|
||||
self.play = function(){
|
||||
if(everCheatedMe) return PD.CHEAT;
|
||||
return PD.COOPERATE;
|
||||
};
|
||||
self.remember = function(other){
|
||||
if(other==PD.CHEAT) everCheatedMe=true;
|
||||
};
|
||||
}
|
||||
function Logic_all_d(){
|
||||
var self = this;
|
||||
self.play = function(){
|
||||
return PD.CHEAT;
|
||||
};
|
||||
self.remember = function(other){
|
||||
// nah
|
||||
};
|
||||
}
|
||||
function Logic_all_c(){
|
||||
var self = this;
|
||||
self.play = function(){
|
||||
return PD.COOPERATE;
|
||||
};
|
||||
self.remember = function(other){
|
||||
// nah
|
||||
};
|
||||
}
|
||||
/*
|
||||
function Logic_prober(){
|
||||
var self = this;
|
||||
self.play = function(){
|
||||
};
|
||||
self.remember = function(other){
|
||||
};
|
||||
}
|
||||
*/
|
|
@ -14,14 +14,14 @@ function TournamentSim(config){
|
|||
//self.dom.classList.add("fader");
|
||||
self.dom.style.left = config.x+"px";
|
||||
self.dom.style.top = config.y+"px";
|
||||
self.dom.style.border = "1px solid rgba(0,0,0,0.2)";
|
||||
//self.dom.style.border = "1px solid rgba(0,0,0,0.2)";
|
||||
|
||||
// CREATE A RING OF AGENTS
|
||||
var AGENTS = [
|
||||
{strategy:"all_c", count:20},
|
||||
{strategy:"all_c", count:15},
|
||||
{strategy:"all_d", count:5},
|
||||
{strategy:"grim", count:2},
|
||||
{strategy:"tft", count:2},
|
||||
{strategy:"grim", count:0},
|
||||
{strategy:"tft", count:5},
|
||||
];
|
||||
|
||||
var _convertCountToArray = function(countList){
|
||||
|
@ -37,6 +37,9 @@ function TournamentSim(config){
|
|||
return array;
|
||||
};
|
||||
|
||||
self.agents = [];
|
||||
self.connections = [];
|
||||
|
||||
self.networkContainer = new PIXI.Container();
|
||||
self.agentsContainer = new PIXI.Container();
|
||||
app.stage.addChild(self.networkContainer);
|
||||
|
@ -45,7 +48,7 @@ function TournamentSim(config){
|
|||
self.populateAgents = function(){
|
||||
|
||||
// Clear EVERYTHING
|
||||
app.stage.removeChildren();
|
||||
self.agentsContainer.removeChildren();
|
||||
|
||||
// Convert to an array
|
||||
self.agents = _convertCountToArray(AGENTS);
|
||||
|
@ -54,32 +57,66 @@ function TournamentSim(config){
|
|||
var count = 0;
|
||||
for(var i=0; i<self.agents.length; i++){
|
||||
|
||||
// Position
|
||||
// Angle
|
||||
var angle = (i/self.agents.length)*Math.TAU - Math.TAU/4;
|
||||
var x = Math.cos(angle)*200 + 250;
|
||||
var y = Math.sin(angle)*200 + 250;
|
||||
|
||||
// What kind of agent?
|
||||
var strategy = self.agents[i];
|
||||
var agent = new TournamentAgent({x:x, y:y, strategy:strategy});
|
||||
app.stage.addChild(agent.graphics);
|
||||
var agent = new TournamentAgent({angle:angle, strategy:strategy, tournament:self});
|
||||
self.agentsContainer.addChild(agent.graphics);
|
||||
|
||||
// Remember me!
|
||||
self.agents[i] = agent;
|
||||
|
||||
}
|
||||
|
||||
// (sort agents by depth)
|
||||
self.sortAgentsByDepth();
|
||||
|
||||
};
|
||||
self.sortAgentsByDepth = function(){
|
||||
self.agentsContainer.children.sort(function(a,b){
|
||||
return a.y - b.y;
|
||||
});
|
||||
};
|
||||
self.populateAgents();
|
||||
|
||||
self.createNetwork = function(){
|
||||
|
||||
// Clear EVERYTHING
|
||||
self.connections = [];
|
||||
self.networkContainer.removeChildren();
|
||||
for(var i=0; i<self.agents.length; i++){
|
||||
self.agents[i].clearConnections();
|
||||
}
|
||||
|
||||
// Connect all of 'em
|
||||
for(var i=0; i<self.agents.length; i++){
|
||||
var playerA = self.agents[i];
|
||||
for(var j=i+1; j<self.agents.length; j++){
|
||||
var playerB = self.agents[j];
|
||||
var connection = new TournamentConnection({
|
||||
from:playerA,
|
||||
to:playerB
|
||||
});
|
||||
self.networkContainer.addChild(connection.graphics);
|
||||
self.connections.push(connection);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
self.createNetwork();
|
||||
|
||||
////////////////////////////////////
|
||||
// EVOLUTION ///////////////////////
|
||||
////////////////////////////////////
|
||||
|
||||
// Play one tournament
|
||||
self.agentsSorted = null;
|
||||
self.playOneTournament = function(){
|
||||
PD.playOneTournament(self.agents, 10);
|
||||
self.agents.sort(function(a,b){
|
||||
self.agentsSorted = self.agents.slice();
|
||||
self.agentsSorted.sort(function(a,b){
|
||||
if(a.coins==b.coins) return (Math.random()<0.5); // if equal, random
|
||||
return a.coins-b.coins; // otherwise, sort as per usual
|
||||
});
|
||||
|
@ -89,7 +126,7 @@ function TournamentSim(config){
|
|||
self.eliminateBottom = function(X){
|
||||
|
||||
// The worst X
|
||||
var worst = self.agents.slice(0,X);
|
||||
var worst = self.agentsSorted.slice(0,X);
|
||||
|
||||
// For each one, subtract from AGENTS count, and KILL.
|
||||
for(var i=0; i<worst.length; i++){
|
||||
|
@ -98,16 +135,20 @@ function TournamentSim(config){
|
|||
return config.strategy==badAgent.strategyName;
|
||||
});
|
||||
config.count--; // remove one
|
||||
app.stage.removeChild(badAgent.graphics); // get rid of this // TODO: KILL?
|
||||
badAgent.kill(); // KILL
|
||||
}
|
||||
|
||||
};
|
||||
self.actuallyRemoveAgent = function(agent){
|
||||
var index = self.agents.indexOf(agent);
|
||||
self.agents.splice(index,1);
|
||||
};
|
||||
|
||||
// Reproduce the top X
|
||||
self.reproduceTop = function(X){
|
||||
|
||||
// The top X
|
||||
var best = self.agents.slice(self.agents.length-X, self.agents.length);
|
||||
var best = self.agentsSorted.slice(self.agentsSorted.length-X, self.agentsSorted.length);
|
||||
|
||||
// For each one, add to AGENTS count
|
||||
for(var i=0; i<best.length; i++){
|
||||
|
@ -118,27 +159,110 @@ function TournamentSim(config){
|
|||
config.count++; // ADD one
|
||||
}
|
||||
|
||||
// ...and REPOPULATE THE THING
|
||||
self.populateAgents();
|
||||
// ADD agents, splicing right AFTER
|
||||
for(var i=0; i<best.length; i++){
|
||||
|
||||
// Properties...
|
||||
var goodAgent = best[i];
|
||||
var angle = goodAgent.angle + 0.1;
|
||||
var strategy = goodAgent.strategyName;
|
||||
|
||||
// Create agent!
|
||||
var agent = new TournamentAgent({angle:angle, strategy:strategy, tournament:self});
|
||||
self.agentsContainer.addChild(agent.graphics);
|
||||
|
||||
// Splice RIGHT AFTER
|
||||
var index = self.agents.indexOf(goodAgent);
|
||||
self.agents.splice(index, 0, agent);
|
||||
|
||||
}
|
||||
|
||||
// What are the agents' GO-TO angles?
|
||||
for(var i=0; i<self.agents.length; i++){
|
||||
var agent = self.agents[i];
|
||||
var angle = (i/self.agents.length)*Math.TAU - Math.TAU/4;
|
||||
agent.gotoAngle = angle;
|
||||
}
|
||||
|
||||
// ADD connections
|
||||
self.createNetwork();
|
||||
|
||||
};
|
||||
|
||||
// HACK: ALL AT ONCE
|
||||
// ANIMATE the PLAYING, ELIMINATING, or REPRODUCING
|
||||
var STAGE_REST = 0;
|
||||
var STAGE_PLAY = 1;
|
||||
var STAGE_ELIMINATE = 2;
|
||||
var STAGE_REPRODUCE = 3;
|
||||
self.STAGE = STAGE_REST;
|
||||
|
||||
self.ALL_AT_ONCE = function(){
|
||||
self.playOneTournament();
|
||||
setTimeout(function(){
|
||||
self.eliminateBottom(5);
|
||||
},300);
|
||||
setTimeout(function(){
|
||||
self.reproduceTop(5);
|
||||
},600);
|
||||
publish("tournament/play");
|
||||
setTimeout(function(){ publish("tournament/eliminate"); },500);
|
||||
setTimeout(function(){ publish("tournament/reproduce"); },1000);
|
||||
setTimeout(self.ALL_AT_ONCE, 1500);
|
||||
};
|
||||
setInterval(self.ALL_AT_ONCE, 1000);
|
||||
setTimeout(self.ALL_AT_ONCE, 100);
|
||||
|
||||
// ANIMATE
|
||||
/*app.ticker.add(function(delta) {
|
||||
bunny.rotation += 0.1 * delta;
|
||||
});*/
|
||||
var _playIndex = 0;
|
||||
var _tweenTimer = 0;
|
||||
app.ticker.add(function(delta) {
|
||||
|
||||
// PLAY!
|
||||
if(self.STAGE == STAGE_PLAY){
|
||||
if(_playIndex>0) self.agents[_playIndex-1].dehighlightConnections();
|
||||
if(_playIndex<self.agents.length){
|
||||
self.agents[_playIndex].highlightConnections();
|
||||
_playIndex++;
|
||||
}else{
|
||||
self.playOneTournament(); // FOR REAL, NOW.
|
||||
_playIndex = 0;
|
||||
self.STAGE = STAGE_REST;
|
||||
}
|
||||
}
|
||||
|
||||
// ELIMINATE!
|
||||
if(self.STAGE == STAGE_ELIMINATE){
|
||||
self.eliminateBottom(5);
|
||||
self.STAGE = STAGE_REST;
|
||||
}
|
||||
|
||||
// REPRODUCE!
|
||||
if(self.STAGE == STAGE_REPRODUCE){
|
||||
|
||||
// Start
|
||||
if(_tweenTimer==0){
|
||||
self.reproduceTop(5);
|
||||
}
|
||||
|
||||
// Middle...
|
||||
for(var i=0;i<self.agents.length;i++){
|
||||
var a = self.agents[i];
|
||||
a.tweenAngle(_tweenTimer);
|
||||
a.updatePosition();
|
||||
}
|
||||
self.sortAgentsByDepth();
|
||||
for(var i=0;i<self.connections.length;i++) self.connections[i].updateGraphics();
|
||||
_tweenTimer += 0.05;
|
||||
|
||||
// End
|
||||
if(_tweenTimer>=1){
|
||||
_tweenTimer = 0;
|
||||
self.STAGE = STAGE_REST;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// PLAY A TOURNAMENT
|
||||
self._startPlay = function(){ self.STAGE=STAGE_PLAY; };
|
||||
subscribe("tournament/play", self._startPlay);
|
||||
self._startEliminate = function(){ self.STAGE=STAGE_ELIMINATE; };
|
||||
subscribe("tournament/eliminate", self._startEliminate);
|
||||
self._startReproduce = function(){ self.STAGE=STAGE_REPRODUCE; };
|
||||
subscribe("tournament/reproduce", self._startReproduce);
|
||||
|
||||
// Add...
|
||||
self.add = function(INSTANT){
|
||||
|
@ -152,10 +276,94 @@ function TournamentSim(config){
|
|||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
function TournamentConnection(config){
|
||||
|
||||
var self = this;
|
||||
|
||||
// Connect from & to
|
||||
self.from = config.from;
|
||||
self.to = config.to;
|
||||
self.from.connections.push(self);
|
||||
self.to.connections.push(self);
|
||||
|
||||
// Graphics!
|
||||
var g = new PIXI.Container();
|
||||
var gray = PIXI.Sprite.fromImage("assets/connection.png");
|
||||
var gold = PIXI.Sprite.fromImage("assets/connection_gold.png");
|
||||
gray.height = 1;
|
||||
gold.height = 2;
|
||||
gray.anchor.y = gold.anchor.y = 0.5;
|
||||
g.addChild(gray);
|
||||
g.addChild(gold);
|
||||
self.graphics = g;
|
||||
|
||||
// Highlight or no?
|
||||
self.highlight = function(){
|
||||
gray.visible = false;
|
||||
gold.visible = true;
|
||||
};
|
||||
self.dehighlight = function(){
|
||||
gray.visible = true;
|
||||
gold.visible = false;
|
||||
};
|
||||
self.dehighlight();
|
||||
|
||||
// Stretch dat bad boy
|
||||
self.updateGraphics = function(){
|
||||
|
||||
var f = self.from.graphics;
|
||||
var t = self.to.graphics;
|
||||
var dx = t.x-f.x;
|
||||
var dy = t.y-f.y;
|
||||
var a = Math.atan2(dy,dx);
|
||||
var dist = Math.sqrt(dx*dx+dy*dy);
|
||||
|
||||
g.x = f.x;
|
||||
g.y = f.y;
|
||||
g.rotation = a;
|
||||
|
||||
gray.width = gold.width = dist;
|
||||
|
||||
};
|
||||
self.updateGraphics();
|
||||
|
||||
// KILL
|
||||
self.IS_DEAD = false;
|
||||
self.kill = function(){
|
||||
if(self.IS_DEAD) return;
|
||||
self.IS_DEAD = true;
|
||||
self.graphics.parent.removeChild(self.graphics); // remove self's graphics
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
function TournamentAgent(config){
|
||||
|
||||
var self = this;
|
||||
self.strategyName = config.strategy;
|
||||
self.tournament = config.tournament;
|
||||
self.angle = config.angle;
|
||||
self.gotoAngle = self.angle;
|
||||
|
||||
// Connections
|
||||
self.connections = [];
|
||||
self.highlightConnections = function(){
|
||||
for(var i=0;i<self.connections.length;i++) self.connections[i].highlight();
|
||||
};
|
||||
self.dehighlightConnections = function(){
|
||||
for(var i=0;i<self.connections.length;i++) self.connections[i].dehighlight();
|
||||
};
|
||||
self.clearConnections = function(){
|
||||
self.connections = [];
|
||||
};
|
||||
|
||||
// Number of coins
|
||||
self.coins = 0;
|
||||
|
@ -166,31 +374,37 @@ function TournamentAgent(config){
|
|||
|
||||
// What's the image?
|
||||
var g = new PIXI.Container();
|
||||
g.x = config.x;
|
||||
g.y = config.y;
|
||||
self.graphics = g;
|
||||
|
||||
// Body!
|
||||
var body = PIXI.Sprite.fromImage("assets/"+self.strategyName+".png");
|
||||
body.scale.set(0.5);
|
||||
if(g.x>250) body.scale.x*=-1;
|
||||
body.anchor.set(0.5);
|
||||
body.anchor.x = 0.5;
|
||||
body.anchor.y = 0.75;
|
||||
g.addChild(body);
|
||||
|
||||
// Score!
|
||||
var textStyle = new PIXI.TextStyle({
|
||||
fontFamily: 'Arial',
|
||||
fontFamily: "FuturaHandwritten",
|
||||
fontSize: 16,
|
||||
fill: "#444"
|
||||
});
|
||||
var scoreText = new PIXI.Text("", textStyle);
|
||||
scoreText.anchor.x = 0.5;
|
||||
scoreText.x = 0;
|
||||
scoreText.y = -40;
|
||||
g.addChild(scoreText);
|
||||
self.updateScore = function(){
|
||||
scoreText.visible = true;
|
||||
scoreText.text = self.coins;
|
||||
};
|
||||
self.updateScore();
|
||||
scoreText.visible = false;
|
||||
/*subscribe("tournament/play",function(){
|
||||
scoreText.visible = false;
|
||||
});*/
|
||||
subscribe("tournament/reproduce",function(){
|
||||
scoreText.visible = false;
|
||||
});
|
||||
|
||||
// What's the play logic?
|
||||
var LogicClass = window["Logic_"+self.strategyName];
|
||||
|
@ -211,123 +425,44 @@ function TournamentAgent(config){
|
|||
self.logic = new LogicClass(); // reset logic
|
||||
};
|
||||
|
||||
// Tween angle...
|
||||
self.tweenAngle = function(t){
|
||||
self.angle = self.gotoAngle*t + self.angle*(1-t);
|
||||
};
|
||||
self.updatePosition = function(){
|
||||
g.x = Math.cos(self.angle)*200 + 250;
|
||||
g.y = Math.sin(self.angle)*200 + 250;
|
||||
scoreText.x = -Math.cos(self.angle)*40;
|
||||
scoreText.y = -Math.sin(self.angle)*48 - 22;
|
||||
};
|
||||
self.updatePosition();
|
||||
|
||||
// KILL
|
||||
self.kill = function(){
|
||||
|
||||
// KILL ALL CONNECTIONS
|
||||
for(var i=0;i<self.connections.length;i++){
|
||||
self.connections[i].kill();
|
||||
}
|
||||
|
||||
// Tween -- DIE!
|
||||
scoreText.visible = false;
|
||||
Tween.get(g).to({
|
||||
alpha: 0,
|
||||
x: g.x+Math.random()*20-10,
|
||||
y: g.y+Math.random()*20-10,
|
||||
rotation: Math.random()*0.5-0.25
|
||||
}, 300, Ease.circOut).call(function(){
|
||||
|
||||
// NOW remove graphics.
|
||||
self.graphics.parent.removeChild(self.graphics);
|
||||
|
||||
// AND remove self from tournament
|
||||
self.tournament.actuallyRemoveAgent(self);
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
var PD = {};
|
||||
PD.COOPERATE = "COOPERATE";
|
||||
PD.CHEAT = "CHEAT";
|
||||
|
||||
PD.P = 0; // punishment: neither of you get anything
|
||||
PD.S = -1; // sucker: you put in coin, other didn't.
|
||||
PD.R = 2; // reward: you both put 1 coin in, both got 3 back
|
||||
PD.T = 3; // temptation: you put no coin, got 3 coins anyway
|
||||
|
||||
PD.getPayoffs = function(move1, move2){
|
||||
if(move1==PD.CHEAT && move2==PD.CHEAT) return [PD.P, PD.P]; // both punished
|
||||
if(move1==PD.COOPERATE && move2==PD.CHEAT) return [PD.S, PD.T]; // sucker - temptation
|
||||
if(move1==PD.CHEAT && move2==PD.COOPERATE) return [PD.T, PD.S]; // temptation - sucker
|
||||
if(move1==PD.COOPERATE && move2==PD.COOPERATE) return [PD.R, PD.R]; // both rewarded
|
||||
};
|
||||
|
||||
PD.playOneGame = function(playerA, playerB){
|
||||
|
||||
var A = playerA.play();
|
||||
var B = playerB.play();
|
||||
|
||||
var payoffs = PD.getPayoffs(A,B);
|
||||
|
||||
playerA.remember(B);
|
||||
playerB.remember(A);
|
||||
|
||||
playerA.addPayoff(payoffs[0]);
|
||||
playerB.addPayoff(payoffs[1]);
|
||||
|
||||
};
|
||||
|
||||
PD.playRepeatedGame = function(playerA, playerB, turns){
|
||||
|
||||
// I've never met you before, let's pretend
|
||||
playerA.resetLogic();
|
||||
playerB.resetLogic();
|
||||
|
||||
// Play N turns
|
||||
for(var i=0; i<turns; i++){
|
||||
PD.playOneGame(playerA, playerB);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
PD.playOneTournament = function(agents, turns){
|
||||
|
||||
// Reset everyone's coins
|
||||
for(var i=0; i<agents.length; i++){
|
||||
agents[i].resetCoins();
|
||||
}
|
||||
|
||||
// Round robin!
|
||||
for(var i=0; i<agents.length; i++){
|
||||
var playerA = agents[i];
|
||||
for(var j=i+1; j<agents.length; j++){
|
||||
var playerB = agents[j];
|
||||
PD.playRepeatedGame(playerA, playerB, turns);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
function Logic_tft(){
|
||||
var self = this;
|
||||
var otherMove = PD.COOPERATE;
|
||||
self.play = function(){
|
||||
return otherMove;
|
||||
};
|
||||
self.remember = function(other){
|
||||
otherMove = other;
|
||||
};
|
||||
}
|
||||
function Logic_grim(){
|
||||
var self = this;
|
||||
var everCheatedMe = false;
|
||||
self.play = function(){
|
||||
if(everCheatedMe) return PD.CHEAT;
|
||||
return PD.COOPERATE;
|
||||
};
|
||||
self.remember = function(other){
|
||||
if(other==PD.CHEAT) everCheatedMe=true;
|
||||
};
|
||||
}
|
||||
function Logic_all_d(){
|
||||
var self = this;
|
||||
self.play = function(){
|
||||
return PD.CHEAT;
|
||||
};
|
||||
self.remember = function(other){
|
||||
// nah
|
||||
};
|
||||
}
|
||||
function Logic_all_c(){
|
||||
var self = this;
|
||||
self.play = function(){
|
||||
return PD.COOPERATE;
|
||||
};
|
||||
self.remember = function(other){
|
||||
// nah
|
||||
};
|
||||
}
|
||||
/*
|
||||
function Logic_prober(){
|
||||
var self = this;
|
||||
self.play = function(){
|
||||
};
|
||||
self.remember = function(other){
|
||||
};
|
||||
}
|
||||
*/
|
Loading…
Reference in a new issue