lil fixes yo

This commit is contained in:
Nicky Case 2017-06-23 17:57:22 -04:00
parent f99871b3e0
commit da3879474d
6 changed files with 145 additions and 43 deletions

14
TODO.md Normal file
View 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

View file

@ -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{

View file

@ -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>

View file

@ -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"

View file

@ -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
};
}

View file

@ -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!