lil fixes yo
This commit is contained in:
parent
f99871b3e0
commit
da3879474d
6 changed files with 145 additions and 43 deletions
14
TODO.md
Normal file
14
TODO.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
MAJOR SHTUFF
|
||||||
|
|
||||||
|
1. Sandbox with all parameters exposed // exposed... but time to make the UI!
|
||||||
|
2. Repeated game with all parameters exposed
|
||||||
|
3. Splash, with params for cool outro
|
||||||
|
4. Integrate *everything*. // slides, outro
|
||||||
|
5. Credits and rewards
|
||||||
|
|
||||||
|
MINOR SHTUFF
|
||||||
|
|
||||||
|
- Word box class less annoying
|
||||||
|
- Refactoring, ugh
|
||||||
|
- Logic: Prober, Pavlov, TF2T, Random? // done
|
||||||
|
- Slides in different files
|
|
@ -77,7 +77,7 @@ body{
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top:17px; left:5px;
|
top:18px; left:5px;
|
||||||
|
|
||||||
}
|
}
|
||||||
.button #hitbox{
|
.button #hitbox{
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
<!-- Simulations -->
|
<!-- Simulations -->
|
||||||
<script src="js/sims/PD.js"></script>
|
<script src="js/sims/PD.js"></script>
|
||||||
<script src="js/sims/SillyPixi.js"></script>
|
<script src="js/sims/SillyPixi.js"></script>
|
||||||
<script src="js/sims/TournamentSim.js"></script>
|
<script src="js/sims/Tournament.js"></script>
|
||||||
|
|
||||||
<!-- Main Code -->
|
<!-- Main Code -->
|
||||||
<script src="js/main.js"></script>
|
<script src="js/main.js"></script>
|
||||||
|
|
|
@ -4,7 +4,7 @@ var slides = [
|
||||||
{
|
{
|
||||||
id: "sim",
|
id: "sim",
|
||||||
add:[
|
add:[
|
||||||
{id:"tournament", type:"TournamentSim", x:0, y:20},
|
{id:"tournament", type:"Tournament", x:0, y:20},
|
||||||
{
|
{
|
||||||
id:"_w1", type:"WordBox",
|
id:"_w1", type:"WordBox",
|
||||||
x:500, y:0, width:460, height:50,
|
x:500, y:0, width:460, height:50,
|
||||||
|
@ -39,7 +39,7 @@ var slides = [
|
||||||
id:"_w3", type:"WordBox",
|
id:"_w3", type:"WordBox",
|
||||||
x:500, y:370, width:460, height:200,
|
x:500, y:370, width:460, height:200,
|
||||||
text:"Always Cheat dominates at first, but when it runs out of suckers to exploit, "+
|
text:"Always Cheat dominates at first, but when it runs out of suckers to exploit, "+
|
||||||
"its empires collapses – and the fairer Tit For Tat takes over.<br>"+
|
"its empire collapses – and the fairer Tit For Tat takes over.<br>"+
|
||||||
"<br>"+
|
"<br>"+
|
||||||
"<i>We are not punished for our sins, but by them.</i><br>"+
|
"<i>We are not punished for our sins, but by them.</i><br>"+
|
||||||
"- Elbert Hubbard"
|
"- Elbert Hubbard"
|
||||||
|
|
121
js/sims/PD.js
121
js/sims/PD.js
|
@ -2,28 +2,43 @@ var PD = {};
|
||||||
PD.COOPERATE = "COOPERATE";
|
PD.COOPERATE = "COOPERATE";
|
||||||
PD.CHEAT = "CHEAT";
|
PD.CHEAT = "CHEAT";
|
||||||
|
|
||||||
PD.P = 0; // punishment: neither of you get anything
|
PD.PAYOFFS_DEFAULT = {
|
||||||
PD.S = -1; // sucker: you put in coin, other didn't.
|
P: 0, // punishment: neither of you get anything
|
||||||
PD.R = 2; // reward: you both put 1 coin in, both got 3 back
|
S: -1, // sucker: you put in coin, other didn't.
|
||||||
PD.T = 3; // temptation: you put no coin, got 3 coins anyway
|
R: 2, // reward: you both put 1 coin in, both got 3 back
|
||||||
|
T: 3 // temptation: you put no coin, got 3 coins anyway
|
||||||
|
};
|
||||||
|
|
||||||
|
PD.PAYOFFS = PD.PAYOFFS_DEFAULT;
|
||||||
|
|
||||||
|
PD.NOISE = 0.0;
|
||||||
|
|
||||||
PD.getPayoffs = function(move1, move2){
|
PD.getPayoffs = function(move1, move2){
|
||||||
if(move1==PD.CHEAT && move2==PD.CHEAT) return [PD.P, PD.P]; // both punished
|
var payoffs = PD.PAYOFFS;
|
||||||
if(move1==PD.COOPERATE && move2==PD.CHEAT) return [PD.S, PD.T]; // sucker - temptation
|
if(move1==PD.CHEAT && move2==PD.CHEAT) return [payoffs.P, payoffs.P]; // both punished
|
||||||
if(move1==PD.CHEAT && move2==PD.COOPERATE) return [PD.T, PD.S]; // temptation - sucker
|
if(move1==PD.COOPERATE && move2==PD.CHEAT) return [payoffs.S, payoffs.T]; // sucker - temptation
|
||||||
if(move1==PD.COOPERATE && move2==PD.COOPERATE) return [PD.R, PD.R]; // both rewarded
|
if(move1==PD.CHEAT && move2==PD.COOPERATE) return [payoffs.T, payoffs.S]; // temptation - sucker
|
||||||
|
if(move1==PD.COOPERATE && move2==PD.COOPERATE) return [payoffs.R, payoffs.R]; // both rewarded
|
||||||
};
|
};
|
||||||
|
|
||||||
PD.playOneGame = function(playerA, playerB){
|
PD.playOneGame = function(playerA, playerB){
|
||||||
|
|
||||||
|
// Make your moves!
|
||||||
var A = playerA.play();
|
var A = playerA.play();
|
||||||
var B = playerB.play();
|
var B = playerB.play();
|
||||||
|
|
||||||
|
// Noise: random mistakes, flip around!
|
||||||
|
if(Math.random()<PD.NOISE) A = ((A==PD.COOPERATE) ? PD.CHEAT : PD.COOPERATE);
|
||||||
|
if(Math.random()<PD.NOISE) B = ((B==PD.COOPERATE) ? PD.CHEAT : PD.COOPERATE);
|
||||||
|
|
||||||
|
// Get payoffs
|
||||||
var payoffs = PD.getPayoffs(A,B);
|
var payoffs = PD.getPayoffs(A,B);
|
||||||
|
|
||||||
playerA.remember(B);
|
// Remember own & other's moves (or mistakes)
|
||||||
playerB.remember(A);
|
playerA.remember(A, B);
|
||||||
|
playerB.remember(B, A);
|
||||||
|
|
||||||
|
// Add to scores (only in tournament?)
|
||||||
playerA.addPayoff(payoffs[0]);
|
playerA.addPayoff(payoffs[0]);
|
||||||
playerB.addPayoff(payoffs[1]);
|
playerB.addPayoff(payoffs[1]);
|
||||||
|
|
||||||
|
@ -70,10 +85,30 @@ function Logic_tft(){
|
||||||
self.play = function(){
|
self.play = function(){
|
||||||
return otherMove;
|
return otherMove;
|
||||||
};
|
};
|
||||||
self.remember = function(other){
|
self.remember = function(own, other){
|
||||||
otherMove = other;
|
otherMove = other;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Logic_tf2t(){
|
||||||
|
var self = this;
|
||||||
|
var howManyTimesCheated = 0;
|
||||||
|
self.play = function(){
|
||||||
|
if(howManyTimesCheated>=2){
|
||||||
|
return PD.CHEAT; // retaliate ONLY after two betrayals
|
||||||
|
}else{
|
||||||
|
return PD.COOPERATE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
self.remember = function(own, other){
|
||||||
|
if(other==PD.CHEAT){
|
||||||
|
howManyTimesCheated++;
|
||||||
|
}else{
|
||||||
|
howManyTimesCheated = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function Logic_grim(){
|
function Logic_grim(){
|
||||||
var self = this;
|
var self = this;
|
||||||
var everCheatedMe = false;
|
var everCheatedMe = false;
|
||||||
|
@ -81,34 +116,84 @@ function Logic_grim(){
|
||||||
if(everCheatedMe) return PD.CHEAT;
|
if(everCheatedMe) return PD.CHEAT;
|
||||||
return PD.COOPERATE;
|
return PD.COOPERATE;
|
||||||
};
|
};
|
||||||
self.remember = function(other){
|
self.remember = function(own, other){
|
||||||
if(other==PD.CHEAT) everCheatedMe=true;
|
if(other==PD.CHEAT) everCheatedMe=true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function Logic_all_d(){
|
function Logic_all_d(){
|
||||||
var self = this;
|
var self = this;
|
||||||
self.play = function(){
|
self.play = function(){
|
||||||
return PD.CHEAT;
|
return PD.CHEAT;
|
||||||
};
|
};
|
||||||
self.remember = function(other){
|
self.remember = function(own, other){
|
||||||
// nah
|
// nah
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function Logic_all_c(){
|
function Logic_all_c(){
|
||||||
var self = this;
|
var self = this;
|
||||||
self.play = function(){
|
self.play = function(){
|
||||||
return PD.COOPERATE;
|
return PD.COOPERATE;
|
||||||
};
|
};
|
||||||
self.remember = function(other){
|
self.remember = function(own, other){
|
||||||
// nah
|
// nah
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
function Logic_prober(){
|
function Logic_random(){
|
||||||
var self = this;
|
var self = this;
|
||||||
self.play = function(){
|
self.play = function(){
|
||||||
|
return (Math.random()>0.5 ? PD.COOPERATE : PD.CHEAT);
|
||||||
};
|
};
|
||||||
self.remember = function(other){
|
self.remember = function(own, other){
|
||||||
|
// nah
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
// Start off Cooperating
|
||||||
|
// Then, if opponent cooperated, repeat past move. otherwise, switch.
|
||||||
|
function Logic_pavlov(){
|
||||||
|
var self = this;
|
||||||
|
var myLastMove = PD.COOPERATE;
|
||||||
|
self.play = function(){
|
||||||
|
return myLastMove;
|
||||||
|
};
|
||||||
|
self.remember = function(own, other){
|
||||||
|
myLastMove = own; // remember MISTAKEN move
|
||||||
|
if(other==PD.CHEAT) myLastMove = ((myLastMove==PD.COOPERATE) ? PD.CHEAT : PD.COOPERATE); // switch!
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// TEST by Cooperate | Cheat | Cooperate | Cooperate
|
||||||
|
// If EVER retaliates, keep playing TFT
|
||||||
|
// If NEVER retaliates, switch to ALWAYS DEFECT
|
||||||
|
function Logic_prober(){
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var moves = [PD.COOPERATE, PD.CHEAT, PD.COOPERATE, PD.COOPERATE];
|
||||||
|
var everCheatedMe = false;
|
||||||
|
|
||||||
|
var otherMove = PD.COOPERATE;
|
||||||
|
self.play = function(){
|
||||||
|
if(moves.length>0){
|
||||||
|
// Testing phase
|
||||||
|
var move = moves.pop();
|
||||||
|
return move;
|
||||||
|
}else{
|
||||||
|
if(everCheatedMe){
|
||||||
|
return otherMove; // TFT
|
||||||
|
}else{
|
||||||
|
return PD.CHEAT; // Always Cheat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
self.remember = function(own, other){
|
||||||
|
if(moves.length>0){
|
||||||
|
if(other==PD.CHEAT) everCheatedMe=true; // Testing phase: ever retaliated?
|
||||||
|
}
|
||||||
|
otherMove = other; // for TFT
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,15 @@
|
||||||
function TournamentSim(config){
|
Tournament.SELECTION = 5;
|
||||||
|
Tournament.NUM_TURNS = 5;
|
||||||
|
|
||||||
|
// CREATE A RING OF AGENTS
|
||||||
|
Tournament.AGENTS = [
|
||||||
|
{strategy:"all_c", count:15},
|
||||||
|
{strategy:"all_d", count:5},
|
||||||
|
{strategy:"grim", count:0},
|
||||||
|
{strategy:"tft", count:5},
|
||||||
|
];
|
||||||
|
|
||||||
|
function Tournament(config){
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
self.id = config.id;
|
self.id = config.id;
|
||||||
|
@ -16,18 +27,10 @@ function TournamentSim(config){
|
||||||
self.dom.style.top = config.y+"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:15},
|
|
||||||
{strategy:"all_d", count:5},
|
|
||||||
{strategy:"grim", count:0},
|
|
||||||
{strategy:"tft", count:5},
|
|
||||||
];
|
|
||||||
|
|
||||||
var _convertCountToArray = function(countList){
|
var _convertCountToArray = function(countList){
|
||||||
var array = [];
|
var array = [];
|
||||||
for(var i=0; i<AGENTS.length; i++){
|
for(var i=0; i<Tournament.AGENTS.length; i++){
|
||||||
var A = AGENTS[i];
|
var A = Tournament.AGENTS[i];
|
||||||
var strategy = A.strategy;
|
var strategy = A.strategy;
|
||||||
var count = A.count;
|
var count = A.count;
|
||||||
for(var j=0; j<count; j++){
|
for(var j=0; j<count; j++){
|
||||||
|
@ -51,7 +54,7 @@ function TournamentSim(config){
|
||||||
self.agentsContainer.removeChildren();
|
self.agentsContainer.removeChildren();
|
||||||
|
|
||||||
// Convert to an array
|
// Convert to an array
|
||||||
self.agents = _convertCountToArray(AGENTS);
|
self.agents = _convertCountToArray(Tournament.AGENTS);
|
||||||
|
|
||||||
// Put 'em in a ring
|
// Put 'em in a ring
|
||||||
var count = 0;
|
var count = 0;
|
||||||
|
@ -114,7 +117,7 @@ function TournamentSim(config){
|
||||||
// Play one tournament
|
// Play one tournament
|
||||||
self.agentsSorted = null;
|
self.agentsSorted = null;
|
||||||
self.playOneTournament = function(){
|
self.playOneTournament = function(){
|
||||||
PD.playOneTournament(self.agents, 10);
|
PD.playOneTournament(self.agents, Tournament.NUM_TURNS);
|
||||||
self.agentsSorted = self.agents.slice();
|
self.agentsSorted = self.agents.slice();
|
||||||
self.agentsSorted.sort(function(a,b){
|
self.agentsSorted.sort(function(a,b){
|
||||||
if(a.coins==b.coins) return (Math.random()<0.5); // if equal, random
|
if(a.coins==b.coins) return (Math.random()<0.5); // if equal, random
|
||||||
|
@ -128,10 +131,10 @@ function TournamentSim(config){
|
||||||
// The worst X
|
// The worst X
|
||||||
var worst = self.agentsSorted.slice(0,X);
|
var worst = self.agentsSorted.slice(0,X);
|
||||||
|
|
||||||
// For each one, subtract from AGENTS count, and KILL.
|
// For each one, subtract from Tournament.AGENTS count, and KILL.
|
||||||
for(var i=0; i<worst.length; i++){
|
for(var i=0; i<worst.length; i++){
|
||||||
var badAgent = worst[i];
|
var badAgent = worst[i];
|
||||||
var config = AGENTS.find(function(config){
|
var config = Tournament.AGENTS.find(function(config){
|
||||||
return config.strategy==badAgent.strategyName;
|
return config.strategy==badAgent.strategyName;
|
||||||
});
|
});
|
||||||
config.count--; // remove one
|
config.count--; // remove one
|
||||||
|
@ -150,10 +153,10 @@ function TournamentSim(config){
|
||||||
// The top X
|
// The top X
|
||||||
var best = self.agentsSorted.slice(self.agentsSorted.length-X, self.agentsSorted.length);
|
var best = self.agentsSorted.slice(self.agentsSorted.length-X, self.agentsSorted.length);
|
||||||
|
|
||||||
// For each one, add to AGENTS count
|
// For each one, add to Tournament.AGENTS count
|
||||||
for(var i=0; i<best.length; i++){
|
for(var i=0; i<best.length; i++){
|
||||||
var goodAgent = best[i];
|
var goodAgent = best[i];
|
||||||
var config = AGENTS.find(function(config){
|
var config = Tournament.AGENTS.find(function(config){
|
||||||
return config.strategy==goodAgent.strategyName;
|
return config.strategy==goodAgent.strategyName;
|
||||||
});
|
});
|
||||||
config.count++; // ADD one
|
config.count++; // ADD one
|
||||||
|
@ -227,7 +230,7 @@ function TournamentSim(config){
|
||||||
|
|
||||||
// ELIMINATE!
|
// ELIMINATE!
|
||||||
if(self.STAGE == STAGE_ELIMINATE){
|
if(self.STAGE == STAGE_ELIMINATE){
|
||||||
self.eliminateBottom(5);
|
self.eliminateBottom(Tournament.SELECTION);
|
||||||
self.STAGE = STAGE_REST;
|
self.STAGE = STAGE_REST;
|
||||||
slideshow.objects._b3.activate(); // activate NEXT button!
|
slideshow.objects._b3.activate(); // activate NEXT button!
|
||||||
}
|
}
|
||||||
|
@ -237,7 +240,7 @@ function TournamentSim(config){
|
||||||
|
|
||||||
// Start
|
// Start
|
||||||
if(_tweenTimer==0){
|
if(_tweenTimer==0){
|
||||||
self.reproduceTop(5);
|
self.reproduceTop(Tournament.SELECTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Middle...
|
// Middle...
|
||||||
|
@ -430,8 +433,8 @@ function TournamentAgent(config){
|
||||||
self.play = function(){
|
self.play = function(){
|
||||||
return self.logic.play();
|
return self.logic.play();
|
||||||
};
|
};
|
||||||
self.remember = function(other){
|
self.remember = function(own, other){
|
||||||
self.logic.remember(other);
|
self.logic.remember(own, other);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Reset!
|
// Reset!
|
Loading…
Reference in a new issue