tabs, pages, controls
This commit is contained in:
parent
14bf47f11a
commit
e8c18fdbe9
15 changed files with 452 additions and 214 deletions
BIN
assets/sandbox_tabs.png
Normal file
BIN
assets/sandbox_tabs.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
|
@ -5,11 +5,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
body{
|
body{
|
||||||
|
|
||||||
margin:0;
|
margin:0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
background: #fff; /*url('paper@2x.png');
|
background: #fff; /*url('paper@2x.png');
|
||||||
background-size: 100px 100px;*/
|
background-size: 100px 100px;*/
|
||||||
|
|
||||||
|
font-family: 'FuturaHandwritten';
|
||||||
|
color: #333;
|
||||||
|
font-size: 20px;
|
||||||
|
|
||||||
}
|
}
|
||||||
#main{
|
#main{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -30,7 +36,7 @@ body{
|
||||||
#slideshow{
|
#slideshow{
|
||||||
|
|
||||||
/*background: #bada55;*/
|
/*background: #bada55;*/
|
||||||
/*border: 1px solid rgba(0,0,0,0.2);*/
|
border: 1px solid rgba(0,0,0,0.2);
|
||||||
width:960px;
|
width:960px;
|
||||||
height:540px;
|
height:540px;
|
||||||
|
|
||||||
|
@ -55,15 +61,15 @@ body{
|
||||||
|
|
||||||
/******** Text Box ********/
|
/******** Text Box ********/
|
||||||
|
|
||||||
.textbox{
|
.textbox{}
|
||||||
font-family: 'FuturaHandwritten';
|
|
||||||
color: #333;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
.textbox > div{
|
.textbox > div{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.label{
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
/********* Button ********/
|
/********* Button ********/
|
||||||
|
|
||||||
.button{
|
.button{
|
||||||
|
@ -112,6 +118,33 @@ body{
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************/
|
||||||
|
/****** SANDBOX UI *******/
|
||||||
|
/*************************/
|
||||||
|
|
||||||
|
#sandbox_tabs{
|
||||||
|
position: absolute;
|
||||||
|
left: 460px; top:-10px;
|
||||||
|
background: url(../assets/sandbox_tabs.png);
|
||||||
|
width:500px; height:470px;
|
||||||
|
background-size: auto 100%;
|
||||||
|
}
|
||||||
|
#sandbox_tabs > div{
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
#sandbox_tabs .hitbox{
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 25px;
|
||||||
|
top: 22px;
|
||||||
|
}
|
||||||
|
#sandbox_tabs .sandbox_page{
|
||||||
|
width: 433px;
|
||||||
|
height: 385px;
|
||||||
|
left: 33px;
|
||||||
|
top: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
/*************************/
|
/*************************/
|
||||||
/***** SLIDE SELECT ******/
|
/***** SLIDE SELECT ******/
|
||||||
/*************************/
|
/*************************/
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
<!-- Libraries -->
|
<!-- Libraries -->
|
||||||
<script src="js/lib/helpers.js"></script>
|
<script src="js/lib/helpers.js"></script>
|
||||||
<script src="js/lib/pegasus.min.js"></script>
|
<script src="js/lib/pegasus.js"></script>
|
||||||
<script src="js/lib/minpubsub.src.js"></script>
|
<script src="js/lib/minpubsub.src.js"></script>
|
||||||
<script src="js/lib/q.js"></script>
|
<script src="js/lib/q.js"></script>
|
||||||
<script src="js/lib/pixi.min.js"></script>
|
<script src="js/lib/pixi.min.js"></script>
|
||||||
|
@ -36,9 +36,10 @@
|
||||||
<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/Tournament.js"></script>
|
<script src="js/sims/Tournament.js"></script>
|
||||||
|
<script src="js/sims/SandboxUI.js"></script>
|
||||||
|
|
||||||
<!-- Slides -->
|
<!-- Slides -->
|
||||||
<script src="js/slides/Slides_Ecology.js"></script>
|
<script src="js/slides/Slides_Sandbox.js"></script>
|
||||||
|
|
||||||
<!-- Main Code -->
|
<!-- Main Code -->
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -24,7 +24,10 @@ function Button(config){
|
||||||
// Customize DOM
|
// Customize DOM
|
||||||
button.style.left = config.x+"px";
|
button.style.left = config.x+"px";
|
||||||
button.style.top = config.y+"px";
|
button.style.top = config.y+"px";
|
||||||
text.innerHTML = Words.get(config.text_id);
|
config.upperCase = (config.upperCase===undefined) ? true : config.upperCase;
|
||||||
|
var words = Words.get(config.text_id);
|
||||||
|
if(config.upperCase) words=words.toUpperCase();
|
||||||
|
text.innerHTML = words;
|
||||||
|
|
||||||
// On hover...
|
// On hover...
|
||||||
hitbox.onmouseover = function(){
|
hitbox.onmouseover = function(){
|
||||||
|
|
|
@ -46,6 +46,18 @@ var _removeFade = function(self, INSTANT){
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Make Label
|
||||||
|
var _makeLabel = function(wordID, x, y, width, height){
|
||||||
|
var dom = document.createElement("div");
|
||||||
|
dom.className = "label";
|
||||||
|
if(x!==undefined) dom.style.left = x+"px";
|
||||||
|
if(y!==undefined) dom.style.top = y+"px";
|
||||||
|
if(width!==undefined) dom.style.width = width+"px";
|
||||||
|
if(height!==undefined) dom.style.height = height+"px";
|
||||||
|
dom.innerHTML = Words.get(wordID);
|
||||||
|
return dom;
|
||||||
|
};
|
||||||
|
|
||||||
/*******
|
/*******
|
||||||
|
|
||||||
Make a Sprite. e.g:
|
Make a Sprite. e.g:
|
||||||
|
|
53
js/lib/pegasus.js
Normal file
53
js/lib/pegasus.js
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
// a url (naming it a, because it will be reused to store callbacks)
|
||||||
|
// e timeout error placeholder to avoid using var, not to be used
|
||||||
|
// xhr placeholder to avoid using var, not to be used
|
||||||
|
function pegasus(a, e, xhr) {
|
||||||
|
xhr = new XMLHttpRequest();
|
||||||
|
|
||||||
|
// Set URL
|
||||||
|
xhr.open('GET', a);
|
||||||
|
|
||||||
|
// Don't need a to store URL anymore
|
||||||
|
// Reuse it to store callbacks
|
||||||
|
a = [];
|
||||||
|
|
||||||
|
pegasus.timeout && (xhr.timeout = pegasus.timeout);
|
||||||
|
|
||||||
|
xhr.ontimeout = function (event) {
|
||||||
|
e = event
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.onreadystatechange = xhr.then = function(onSuccess, onError, cb, data) {
|
||||||
|
// Test if onSuccess is a function
|
||||||
|
// Means that the user called xhr.then
|
||||||
|
if (onSuccess && onSuccess.call) {
|
||||||
|
a = [,onSuccess, onError];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test if there's a timeout error
|
||||||
|
e && a[2] && a[2](e, xhr)
|
||||||
|
|
||||||
|
// Test if request is complete
|
||||||
|
if (xhr.readyState == 4) {
|
||||||
|
// index will be:
|
||||||
|
// 0 if undefined
|
||||||
|
// 1 if status is between 200 and 399
|
||||||
|
// 2 if status is over
|
||||||
|
cb = a[0|xhr.status / 200];
|
||||||
|
if (cb) {
|
||||||
|
/*try {
|
||||||
|
data = JSON.parse(xhr.responseText) // NICKY FIX -- don't be helpful
|
||||||
|
} catch (e) {*/
|
||||||
|
data = null;
|
||||||
|
//}
|
||||||
|
cb(data, xhr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Send the GET request
|
||||||
|
xhr.send();
|
||||||
|
|
||||||
|
// Return request
|
||||||
|
return xhr;
|
||||||
|
}
|
2
js/lib/pegasus.min.js
vendored
2
js/lib/pegasus.min.js
vendored
|
@ -1,2 +0,0 @@
|
||||||
//0.3.5
|
|
||||||
function pegasus(a,b,c){return c=new XMLHttpRequest,c.open("GET",a),a=[],pegasus.timeout&&(c.timeout=pegasus.timeout),c.ontimeout=function(a){b=a},c.onreadystatechange=c.then=function(d,e,f,g){if(d&&d.call&&(a=[,d,e]),b&&a[2]&&a[2](b,c),4==c.readyState&&(f=a[0|c.status/200])){try{g=JSON.parse(c.responseText)}catch(a){g=null}f(g,c)}},c.send(),c}
|
|
|
@ -81,7 +81,7 @@
|
||||||
|
|
||||||
var hasStacks = false;
|
var hasStacks = false;
|
||||||
try {
|
try {
|
||||||
throw new Error();
|
// throw new Error(); // NICKY FIX -- STOP TRYING TO BE HELPFUL
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
hasStacks = !!e.stack;
|
hasStacks = !!e.stack;
|
||||||
}
|
}
|
||||||
|
@ -461,7 +461,7 @@ function captureLine() {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
throw new Error();
|
// throw new Error(); // NICKY FIX -- STOP TRYING TO BE HELPFUL
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
var lines = e.stack.split("\n");
|
var lines = e.stack.split("\n");
|
||||||
var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2];
|
var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2];
|
||||||
|
|
107
js/main.js
107
js/main.js
|
@ -1,107 +0,0 @@
|
||||||
/*var slides = [
|
|
||||||
|
|
||||||
// SIM
|
|
||||||
{
|
|
||||||
id: "sim",
|
|
||||||
add:[
|
|
||||||
{id:"tournament", type:"Tournament", x:0, y:20},
|
|
||||||
{
|
|
||||||
id:"_w1", type:"WordBox",
|
|
||||||
x:500, y:0, width:460, height:50,
|
|
||||||
text:"Let's say there are three kinds of players:<br>"+
|
|
||||||
"<span style='color:#FF75FF;'>Always Cooperate</span>, "+
|
|
||||||
"<span style='color:#52537F;'>Always Cheat</span> & "+
|
|
||||||
"<span style='color:#4089DD;'>Tit For Tat</span>"+
|
|
||||||
"<br><br>"+
|
|
||||||
"What happens when you let a mixed population play against each other, and evolve over time?"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id:"_b1", type:"Button",
|
|
||||||
x:500, y:150, width:140,
|
|
||||||
text:"1) play tournament",
|
|
||||||
message:"tournament/play"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id:"_b2", type:"Button",
|
|
||||||
x:500, y:220, width:140,
|
|
||||||
text:"2) eliminate bottom 5",
|
|
||||||
message:"tournament/eliminate",
|
|
||||||
active:false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id:"_b3", type:"Button",
|
|
||||||
x:500, y:290, width:140,
|
|
||||||
text:"3) reproduce top 5",
|
|
||||||
message:"tournament/reproduce",
|
|
||||||
active:false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id:"_w3", type:"WordBox",
|
|
||||||
x:500, y:370, width:460, height:200,
|
|
||||||
text:"Always Cheat dominates at first, but when it runs out of suckers to exploit, "+
|
|
||||||
"its empire collapses – and the fairer Tit For Tat takes over.<br>"+
|
|
||||||
"<br>"+
|
|
||||||
"<i>We are not punished for our sins, but by them.</i><br>"+
|
|
||||||
"- Elbert Hubbard"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// Intro
|
|
||||||
{
|
|
||||||
id: "intro0",
|
|
||||||
add:[
|
|
||||||
{id:"button", type:"Button", x:550, y:200, width:100, height:100, text:"NEXT SLIDE", message:"slideshow/next"},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// Intro 1
|
|
||||||
{
|
|
||||||
id: "intro1",
|
|
||||||
add:[
|
|
||||||
{id:"wordbox1", type:"WordBox", x:500, y:0, width:100, height:200, text:"foo bar <b>foo bar</b> <i>foo<i> bar"},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// Intro 2
|
|
||||||
{
|
|
||||||
id: "intro2",
|
|
||||||
add:[
|
|
||||||
{id:"wordbox2", type:"WordBox", x:500, y:100, width:100, height:200, text:"even more foo bar"},
|
|
||||||
{id:"silly", type:"SillyPixi", x:700, y:50, width:200, height:200}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// Intro 3
|
|
||||||
{
|
|
||||||
id: "intro3",
|
|
||||||
remove:[
|
|
||||||
{id:"wordbox1"},
|
|
||||||
{id:"wordbox2"}
|
|
||||||
],
|
|
||||||
add:[
|
|
||||||
{id:"wordbox3", type:"WordBox", x:500, y:0, width:100, height:200, text:"aaAAAAHHHHhhh"}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// Intro 4
|
|
||||||
{
|
|
||||||
id: "intro4",
|
|
||||||
remove:[
|
|
||||||
{id:"wordbox3"}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// Intro 5
|
|
||||||
{
|
|
||||||
id: "intro5",
|
|
||||||
remove:[
|
|
||||||
{id:"button"},
|
|
||||||
{id:"silly"}
|
|
||||||
],
|
|
||||||
add:[
|
|
||||||
{id:"the_end", type:"WordBox", x:600, y:300, width:100, height:200, text:"THE END"}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
];*/
|
|
|
@ -11,7 +11,7 @@ PD.PAYOFFS_DEFAULT = {
|
||||||
|
|
||||||
PD.PAYOFFS = PD.PAYOFFS_DEFAULT;
|
PD.PAYOFFS = PD.PAYOFFS_DEFAULT;
|
||||||
|
|
||||||
PD.NOISE = 0.05;
|
PD.NOISE = 0;
|
||||||
|
|
||||||
PD.getPayoffs = function(move1, move2){
|
PD.getPayoffs = function(move1, move2){
|
||||||
var payoffs = PD.PAYOFFS;
|
var payoffs = PD.PAYOFFS;
|
||||||
|
|
108
js/sims/SandboxUI.js
Normal file
108
js/sims/SandboxUI.js
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
function SandboxUI(config){
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
self.id = config.id;
|
||||||
|
|
||||||
|
// Create DOM
|
||||||
|
self.dom = document.createElement("div");
|
||||||
|
self.dom.className = "object";
|
||||||
|
var dom = self.dom;
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
// BUTTONS for playing //////////////////
|
||||||
|
/////////////////////////////////////////
|
||||||
|
|
||||||
|
var playButton = new Button({x:130, y:135, text_id:"label_play", message:"tournament/autoplay"});
|
||||||
|
dom.appendChild(playButton.dom);
|
||||||
|
var stepButton = new Button({x:130, y:135+70, text_id:"label_step", message:"tournament/step"});
|
||||||
|
dom.appendChild(stepButton.dom);
|
||||||
|
var resetButton = new Button({x:130, y:135+70*2, text_id:"label_reset", message:"tournament/reset"});
|
||||||
|
dom.appendChild(resetButton.dom);
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
// Create TABS & PAGES //////////////////
|
||||||
|
/////////////////////////////////////////
|
||||||
|
|
||||||
|
// Tabs
|
||||||
|
var tabs = document.createElement("div");
|
||||||
|
tabs.id = "sandbox_tabs";
|
||||||
|
dom.appendChild(tabs);
|
||||||
|
|
||||||
|
// Tab Hitboxes
|
||||||
|
var _makeHitbox = function(label, x, width, pageIndex){
|
||||||
|
|
||||||
|
label = label.toUpperCase();
|
||||||
|
|
||||||
|
var hitbox = document.createElement("div");
|
||||||
|
hitbox.className = "hitbox";
|
||||||
|
hitbox.style.left = x+"px";
|
||||||
|
hitbox.style.width = width+"px";
|
||||||
|
hitbox.innerHTML = label;
|
||||||
|
tabs.appendChild(hitbox);
|
||||||
|
|
||||||
|
(function(pageIndex){
|
||||||
|
hitbox.onclick = function(){
|
||||||
|
_goToPage(pageIndex);
|
||||||
|
};
|
||||||
|
})(pageIndex);
|
||||||
|
|
||||||
|
};
|
||||||
|
_makeHitbox(Words.get("label_population"), 30, 100, 0);
|
||||||
|
_makeHitbox(Words.get("label_payoffs"), 220, 100, 1);
|
||||||
|
_makeHitbox(Words.get("label_rules"), 366, 100, 2);
|
||||||
|
|
||||||
|
// Pages
|
||||||
|
var pages = [];
|
||||||
|
var _makePage = function(){
|
||||||
|
var page = document.createElement("div");
|
||||||
|
page.className = "sandbox_page";
|
||||||
|
tabs.appendChild(page);
|
||||||
|
pages.push(page);
|
||||||
|
};
|
||||||
|
for(var i=0; i<3; i++) _makePage(); // make three pages
|
||||||
|
|
||||||
|
// Go To Page
|
||||||
|
var _goToPage = function(showIndex){
|
||||||
|
|
||||||
|
// Background
|
||||||
|
tabs.style.backgroundPosition = (-showIndex*500)+"px 0px";
|
||||||
|
|
||||||
|
// Show page
|
||||||
|
for(var i=0; i<pages.length; i++) pages[i].style.display = "none";
|
||||||
|
pages[showIndex].style.display = "block";
|
||||||
|
|
||||||
|
};
|
||||||
|
_goToPage(0);
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
// PAGE 0: POPULATION ///////////////////
|
||||||
|
/////////////////////////////////////////
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
// PAGE 1: PAYOFFS //////////////////////
|
||||||
|
/////////////////////////////////////////
|
||||||
|
|
||||||
|
var page = pages[1];
|
||||||
|
|
||||||
|
var label = _makeLabel("sandbox_payoffs", 0, 0, 433);
|
||||||
|
page.appendChild(label);
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
// PAGE 2: RULES ////////////////////////
|
||||||
|
/////////////////////////////////////////
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
// Add & Remove Object //////////////////
|
||||||
|
/////////////////////////////////////////
|
||||||
|
|
||||||
|
// Add...
|
||||||
|
self.add = function(INSTANT){
|
||||||
|
return _add(self);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Remove...
|
||||||
|
self.remove = function(INSTANT){
|
||||||
|
return _remove(self);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -8,17 +8,20 @@ Tournament.NUM_TURNS = 10;
|
||||||
{strategy:"grudge", count:0},
|
{strategy:"grudge", count:0},
|
||||||
{strategy:"tft", count:5},
|
{strategy:"tft", count:5},
|
||||||
];*/
|
];*/
|
||||||
Tournament.AGENTS = [
|
Tournament.INITIAL_AGENTS = [
|
||||||
{strategy:"all_c", count:13}, // OH THAT'S SO COOL. Mostly C: Pavlov wins, Mostly D: tit for two tats wins (with 5% mistake!)
|
{strategy:"all_c", count:15},
|
||||||
//{strategy:"all_d", count:13},
|
{strategy:"all_d", count:5},
|
||||||
{strategy:"tft", count:3},
|
{strategy:"tft", count:5},
|
||||||
//{strategy:"grudge", count:3},
|
//{strategy:"grudge", count:3},
|
||||||
//{strategy:"prober", count:6},
|
//{strategy:"prober", count:6},
|
||||||
{strategy:"tf2t", count:3},
|
//{strategy:"tf2t", count:8},
|
||||||
{strategy:"pavlov", count:3},
|
//{strategy:"pavlov", count:3},
|
||||||
{strategy:"random", count:3}
|
//{strategy:"random", count:3}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// OH THAT'S SO COOL. Mostly C: Pavlov wins, Mostly D: tit for two tats wins (with 5% mistake!)
|
||||||
|
// ALSO, NOISE: tft vs all_d. no random: tft wins. low random: tf2t wins. high random: all_d wins. totally random: nobody wins
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -57,8 +60,8 @@ function Tournament(config){
|
||||||
|
|
||||||
var _convertCountToArray = function(countList){
|
var _convertCountToArray = function(countList){
|
||||||
var array = [];
|
var array = [];
|
||||||
for(var i=0; i<Tournament.AGENTS.length; i++){
|
for(var i=0; i<AGENTS.length; i++){
|
||||||
var A = Tournament.AGENTS[i];
|
var A = 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++){
|
||||||
|
@ -82,7 +85,7 @@ function Tournament(config){
|
||||||
self.agentsContainer.removeChildren();
|
self.agentsContainer.removeChildren();
|
||||||
|
|
||||||
// Convert to an array
|
// Convert to an array
|
||||||
self.agents = _convertCountToArray(Tournament.AGENTS);
|
self.agents = _convertCountToArray(AGENTS);
|
||||||
|
|
||||||
// Put 'em in a ring
|
// Put 'em in a ring
|
||||||
var count = 0;
|
var count = 0;
|
||||||
|
@ -110,7 +113,6 @@ function Tournament(config){
|
||||||
return a.y - b.y;
|
return a.y - b.y;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
self.populateAgents();
|
|
||||||
|
|
||||||
self.createNetwork = function(){
|
self.createNetwork = function(){
|
||||||
|
|
||||||
|
@ -136,7 +138,23 @@ function Tournament(config){
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
self.createNetwork();
|
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
// RESET //////////////
|
||||||
|
///////////////////////
|
||||||
|
|
||||||
|
var AGENTS;
|
||||||
|
self.reset = function(){
|
||||||
|
AGENTS = JSON.parse(JSON.stringify(Tournament.INITIAL_AGENTS));
|
||||||
|
self.populateAgents();
|
||||||
|
self.createNetwork();
|
||||||
|
self.isAutoPlaying = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
subscribe("tournament/reset", self.reset);
|
||||||
|
|
||||||
|
self.reset();
|
||||||
|
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
// EVOLUTION ///////////////////////
|
// EVOLUTION ///////////////////////
|
||||||
|
@ -159,10 +177,10 @@ function Tournament(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 Tournament.AGENTS count, and KILL.
|
// For each one, subtract from 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 = Tournament.AGENTS.find(function(config){
|
var config = AGENTS.find(function(config){
|
||||||
return config.strategy==badAgent.strategyName;
|
return config.strategy==badAgent.strategyName;
|
||||||
});
|
});
|
||||||
config.count--; // remove one
|
config.count--; // remove one
|
||||||
|
@ -181,10 +199,10 @@ function Tournament(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 Tournament.AGENTS count
|
// For each one, add to 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 = Tournament.AGENTS.find(function(config){
|
var config = AGENTS.find(function(config){
|
||||||
return config.strategy==goodAgent.strategyName;
|
return config.strategy==goodAgent.strategyName;
|
||||||
});
|
});
|
||||||
config.count++; // ADD one
|
config.count++; // ADD one
|
||||||
|
@ -227,15 +245,27 @@ function Tournament(config){
|
||||||
var STAGE_REPRODUCE = 3;
|
var STAGE_REPRODUCE = 3;
|
||||||
self.STAGE = STAGE_REST;
|
self.STAGE = STAGE_REST;
|
||||||
|
|
||||||
/*
|
// AUTOPLAY
|
||||||
self.ALL_AT_ONCE = function(){
|
self.isAutoPlaying = false;
|
||||||
publish("tournament/play");
|
var _step = 0;
|
||||||
setTimeout(function(){ publish("tournament/eliminate"); },500);
|
var _nextStep = function(){
|
||||||
setTimeout(function(){ publish("tournament/reproduce"); },1000);
|
if(_step==0) publish("tournament/play");
|
||||||
setTimeout(self.ALL_AT_ONCE, 1500);
|
if(_step==1) publish("tournament/eliminate");
|
||||||
|
if(_step==2) publish("tournament/reproduce");
|
||||||
|
_step = (_step+1)%3;
|
||||||
};
|
};
|
||||||
setTimeout(self.ALL_AT_ONCE, 100);
|
var _startAutoPlay = function(){
|
||||||
*/
|
self.isAutoPlaying = true;
|
||||||
|
_nextStep();
|
||||||
|
setTimeout(function(){
|
||||||
|
if(self.isAutoPlaying) _startAutoPlay();
|
||||||
|
},500);
|
||||||
|
};
|
||||||
|
subscribe("tournament/autoplay", _startAutoPlay);
|
||||||
|
subscribe("tournament/step", function(){
|
||||||
|
self.isAutoPlaying = false;
|
||||||
|
_nextStep();
|
||||||
|
});
|
||||||
|
|
||||||
// ANIMATE
|
// ANIMATE
|
||||||
var _playIndex = 0;
|
var _playIndex = 0;
|
||||||
|
@ -252,7 +282,7 @@ function Tournament(config){
|
||||||
self.playOneTournament(); // FOR REAL, NOW.
|
self.playOneTournament(); // FOR REAL, NOW.
|
||||||
_playIndex = 0;
|
_playIndex = 0;
|
||||||
self.STAGE = STAGE_REST;
|
self.STAGE = STAGE_REST;
|
||||||
slideshow.objects._b2.activate(); // activate NEXT button!
|
// slideshow.objects._b2.activate(); // activate NEXT button!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +290,7 @@ function Tournament(config){
|
||||||
if(self.STAGE == STAGE_ELIMINATE){
|
if(self.STAGE == STAGE_ELIMINATE){
|
||||||
self.eliminateBottom(Tournament.SELECTION);
|
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!
|
||||||
}
|
}
|
||||||
|
|
||||||
// REPRODUCE!
|
// REPRODUCE!
|
||||||
|
@ -285,7 +315,7 @@ function Tournament(config){
|
||||||
if(_tweenTimer>=1){
|
if(_tweenTimer>=1){
|
||||||
_tweenTimer = 0;
|
_tweenTimer = 0;
|
||||||
self.STAGE = STAGE_REST;
|
self.STAGE = STAGE_REST;
|
||||||
slideshow.objects._b1.activate(); // activate NEXT button!
|
// slideshow.objects._b1.activate(); // activate NEXT button!
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -294,23 +324,23 @@ function Tournament(config){
|
||||||
|
|
||||||
// PLAY A TOURNAMENT
|
// PLAY A TOURNAMENT
|
||||||
self.deactivateAllButtons = function(){
|
self.deactivateAllButtons = function(){
|
||||||
slideshow.objects._b1.deactivate();
|
// slideshow.objects._b1.deactivate();
|
||||||
slideshow.objects._b2.deactivate();
|
// slideshow.objects._b2.deactivate();
|
||||||
slideshow.objects._b3.deactivate();
|
// slideshow.objects._b3.deactivate();
|
||||||
};
|
};
|
||||||
self._startPlay = function(){
|
self._startPlay = function(){
|
||||||
self.STAGE=STAGE_PLAY;
|
self.STAGE=STAGE_PLAY;
|
||||||
self.deactivateAllButtons();
|
// self.deactivateAllButtons();
|
||||||
};
|
};
|
||||||
subscribe("tournament/play", self._startPlay);
|
subscribe("tournament/play", self._startPlay);
|
||||||
self._startEliminate = function(){
|
self._startEliminate = function(){
|
||||||
self.STAGE=STAGE_ELIMINATE;
|
self.STAGE=STAGE_ELIMINATE;
|
||||||
self.deactivateAllButtons();
|
// self.deactivateAllButtons();
|
||||||
};
|
};
|
||||||
subscribe("tournament/eliminate", self._startEliminate);
|
subscribe("tournament/eliminate", self._startEliminate);
|
||||||
self._startReproduce = function(){
|
self._startReproduce = function(){
|
||||||
self.STAGE=STAGE_REPRODUCE;
|
self.STAGE=STAGE_REPRODUCE;
|
||||||
self.deactivateAllButtons();
|
// self.deactivateAllButtons();
|
||||||
};
|
};
|
||||||
subscribe("tournament/reproduce", self._startReproduce);
|
subscribe("tournament/reproduce", self._startReproduce);
|
||||||
|
|
||||||
|
@ -324,6 +354,9 @@ function Tournament(config){
|
||||||
return _remove(self);
|
return _remove(self);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: KILL ALL LISTENERS, TOO.
|
||||||
|
// TODO: Don't screw up when paused or looking at new tab
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
|
@ -386,7 +419,7 @@ function TournamentConnection(config){
|
||||||
self.kill = function(){
|
self.kill = function(){
|
||||||
if(self.IS_DEAD) return;
|
if(self.IS_DEAD) return;
|
||||||
self.IS_DEAD = true;
|
self.IS_DEAD = true;
|
||||||
self.graphics.parent.removeChild(self.graphics); // remove self's graphics
|
if(self.graphics.parent) self.graphics.parent.removeChild(self.graphics); // remove self's graphics
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -506,7 +539,7 @@ function TournamentAgent(config){
|
||||||
}, 300, Ease.circOut).call(function(){
|
}, 300, Ease.circOut).call(function(){
|
||||||
|
|
||||||
// NOW remove graphics.
|
// NOW remove graphics.
|
||||||
self.graphics.parent.removeChild(self.graphics);
|
if(self.graphics.parent) self.graphics.parent.removeChild(self.graphics);
|
||||||
|
|
||||||
// AND remove self from tournament
|
// AND remove self from tournament
|
||||||
self.tournament.actuallyRemoveAgent(self);
|
self.tournament.actuallyRemoveAgent(self);
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
SLIDES.push({
|
|
||||||
|
|
||||||
id: "sim",
|
|
||||||
add:[
|
|
||||||
|
|
||||||
// The tournament simulation
|
|
||||||
{id:"tournament", type:"Tournament", x:0, y:20},
|
|
||||||
|
|
||||||
// All the words!
|
|
||||||
{
|
|
||||||
id:"textbox", type:"TextBox",
|
|
||||||
boxes:[
|
|
||||||
{ x:500, y:0, width:460, height:50, text_id:"sandbox_1" },
|
|
||||||
{ x:500, y:370, width:460, height:200, text_id:"sandbox_2" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
// Buttons
|
|
||||||
{
|
|
||||||
id:"_b1", type:"Button", x:500, y:150, width:140,
|
|
||||||
text_id: "label_play_tournament",
|
|
||||||
message: "tournament/play"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id:"_b2", type:"Button", x:500, y:220, width:140,
|
|
||||||
text_id: "label_eliminate_bottom_5",
|
|
||||||
message: "tournament/eliminate",
|
|
||||||
active:false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id:"_b3", type:"Button", x:500, y:290, width:140,
|
|
||||||
text_id: "label_reproduce_top_5",
|
|
||||||
message: "tournament/reproduce",
|
|
||||||
active:false
|
|
||||||
}
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
});
|
|
14
js/slides/Slides_Sandbox.js
Normal file
14
js/slides/Slides_Sandbox.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
SLIDES.push({
|
||||||
|
|
||||||
|
id: "sim",
|
||||||
|
add:[
|
||||||
|
|
||||||
|
// The tournament simulation
|
||||||
|
{id:"tournament", type:"Tournament", x:-20, y:-20},
|
||||||
|
|
||||||
|
// Screw it, just ALL of the Sandbox UI
|
||||||
|
{id:"sandbox", type:"SandboxUI"}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
});
|
167
lang/en.html
167
lang/en.html
|
@ -1,5 +1,152 @@
|
||||||
|
<!-- - - - - - - - - - - - - - - - - -->
|
||||||
|
<!-- - - - - - SANDBOX! - - - - - - - -->
|
||||||
|
<!-- - - - - - - - - - - - - - - - - -->
|
||||||
|
|
||||||
<!-- SANDBOX! -->
|
<p id="sandbox_population">
|
||||||
|
Start the simulation with this distribution of players:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="sandbox_payoffs">
|
||||||
|
The payoffs in a one-on-one game are:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
When translating the following, keep the "[N]", with square brackets,
|
||||||
|
as a placeholder for the number. Some of these need double-translations,
|
||||||
|
one for the plural version, one for the singular version.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<p id="sandbox_rules_1">
|
||||||
|
Play [N] rounds per one-on-one game
|
||||||
|
</p>
|
||||||
|
<p id="sandbox_rules_1_single">
|
||||||
|
Play [N] round per one-on-one game
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="sandbox_rules_2">
|
||||||
|
After each tournament, eliminate the bottom [N] players & reproduce the top [N] players
|
||||||
|
</p>
|
||||||
|
<p id="sandbox_rules_2_single">
|
||||||
|
After each tournament, eliminate the bottom [N] player & reproduce the top [N] player
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="sandbox_rules_3">
|
||||||
|
In a one-on-one game, there's a [N]% chance in each round that a player will make a mistake
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- - - - - - - - - - - - - - - - - -->
|
||||||
|
<!-- - - - - THE PLAYERS - - - - - - -->
|
||||||
|
<!-- - - - - - - - - - - - - - - - - -->
|
||||||
|
|
||||||
|
<p id="label_tft">
|
||||||
|
Tit For Tat
|
||||||
|
</p>
|
||||||
|
<p id="desc_tft">
|
||||||
|
I Cooperate on the first round.
|
||||||
|
Then, I just do whatever you did the last round.
|
||||||
|
If you Cheat me, I'll Cheat you back &em;
|
||||||
|
but if you Cooperate, I'll forgive you immediately!
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="label_all_d">
|
||||||
|
Always Cheat
|
||||||
|
</p>
|
||||||
|
<p id="desc_all_d">
|
||||||
|
Ain't I a stinker?
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="label_all_c">
|
||||||
|
Always Cooperate
|
||||||
|
</p>
|
||||||
|
<p id="desc_all_c">
|
||||||
|
💖 💖 💖
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="label_grudge">
|
||||||
|
Grudger
|
||||||
|
</p>
|
||||||
|
<p id="desc_grudge">
|
||||||
|
I'll always Cooperate... until you Cheat me even once.
|
||||||
|
Then, I'll <i>always</i> Cheat you back. NO FORGIVENESS.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="label_prober">
|
||||||
|
Prober
|
||||||
|
</p>
|
||||||
|
<p id="desc_prober">
|
||||||
|
First: I analyze you.
|
||||||
|
I start: Cooperate, Cheat, Cooperate, Cooperate.
|
||||||
|
Then: if you retaliated with a Cheat, I switch to playing Tit For Tat.
|
||||||
|
But: if you never fight back, I Cheat the heck out of you.
|
||||||
|
My dear Watson: elementary.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="label_tf2t">
|
||||||
|
Tit For Two Tats
|
||||||
|
</p>
|
||||||
|
<p id="desc_tf2t">
|
||||||
|
I Cooperate on the first round.
|
||||||
|
After that, if you Cheat me... well, I'll forgive you once.
|
||||||
|
However, if you Cheat me twice in a row, <i>then</i> I'll Cheat back.
|
||||||
|
(But again, if you Cooperate, I'll forgive you immediately!)
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="label_pavlov">
|
||||||
|
Pavlov's Dog
|
||||||
|
</p>
|
||||||
|
<p id="desc_pavlov">
|
||||||
|
I Cooperate on the first round.
|
||||||
|
After that, if you Cooperated in the previous round,
|
||||||
|
I'll just do what I did last time (even if it was a mistake).
|
||||||
|
But if you Cheated in the previous round,
|
||||||
|
I'll do the <i>opposite</i> of what I did last time (even if it was a mistake).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="label_random">
|
||||||
|
Lol So Random
|
||||||
|
</p>
|
||||||
|
<p id="desc_random">
|
||||||
|
monkey tacos! robot ninja bacon pirate!
|
||||||
|
i randomly play Cheat or Cooperate coz lol i'm so random
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- - - - - - - - - - - - - - - - - -->
|
||||||
|
<!-- - - - - SMALL LABELS! - - - - - -->
|
||||||
|
<!-- - - - - - - - - - - - - - - - - -->
|
||||||
|
|
||||||
|
<p id="label_cooperate">
|
||||||
|
cooperate
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="label_cheat">
|
||||||
|
cheat
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="label_play">
|
||||||
|
play
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="label_step">
|
||||||
|
step
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="label_reset">
|
||||||
|
reset
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="label_population">
|
||||||
|
population
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="label_payoffs">
|
||||||
|
payoffs
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p id="label_rules">
|
||||||
|
rules
|
||||||
|
</p>
|
||||||
|
|
||||||
<p id="label_play_tournament">
|
<p id="label_play_tournament">
|
||||||
1) play tournament
|
1) play tournament
|
||||||
|
@ -12,21 +159,3 @@
|
||||||
<p id="label_reproduce_top_5">
|
<p id="label_reproduce_top_5">
|
||||||
3) reproduce top 5
|
3) reproduce top 5
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p id="sandbox_1">
|
|
||||||
Let's say there are three kinds of players:
|
|
||||||
<br>
|
|
||||||
<span style='color:#FF75FF;'>Always Cooperate</span>,
|
|
||||||
<span style='color:#52537F;'>Always Cheat</span> &
|
|
||||||
<span style='color:#4089DD;'>Tit For Tat</span>
|
|
||||||
<br><br>
|
|
||||||
"What happens when you let a mixed population play against each other, and evolve over time?
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p id="sandbox_2">
|
|
||||||
Always Cheat dominates at first, but when it runs out of suckers to exploit,
|
|
||||||
its empire collapses – and the fairer Tit For Tat takes over.
|
|
||||||
<br><br>
|
|
||||||
<i>We are not punished for our sins, but by them.</i><br>
|
|
||||||
- Elbert Hubbard
|
|
||||||
</p>
|
|
Loading…
Reference in a new issue