Last active
December 24, 2015 19:59
-
-
Save binarymax/6854806 to your computer and use it in GitHub Desktop.
Elo rating simulation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/********************************* | |
* | |
* Elo Rating Simulation | |
* Copyright (c) 2013, Max Irwin | |
* MIT License | |
* | |
*********************************/ | |
(function(){ | |
var players = []; | |
var names = 'pawn,knight,bishop,rook,queen,king'.split(','); | |
var skills = 'dead,weak,lame,student,bold,artful,strong,master'.split(','); | |
//------------------------------------------------------------------ | |
//Random number helpers | |
var rand1 = function(max){ return Math.floor(Math.random()*max); } | |
var rand2 = function(min,max){ return Math.floor(Math.random() * (max - min + 1)) + min; } | |
//------------------------------------------------------------------ | |
//elo Rating calculation | |
var elo = function (whiteRating,blackRating,whiteResult,blackResult,kwhite,kblack) { | |
var expected = function(a,b) { return (1/(1+(Math.pow(10,(a-b)/400)))) }; | |
return { | |
white: (whiteRating+(kwhite*(whiteResult-expected(blackRating,whiteRating)))), | |
black: (blackRating+(kblack*(blackResult-expected(whiteRating,blackRating)))) | |
} | |
} | |
//------------------------------------------------------------------ | |
//Plays and rates one game | |
var game = function(white,black) { | |
white.games++;black.games++; | |
var chance; | |
var whiteresult,blackresult; | |
var wchance = rand1(white.skill); | |
var bchance = rand1(black.skill); | |
if (white.skill===black.skill) { | |
chance = rand1(2)-1; | |
} else if (wchance===bchance) { | |
chance = 0; | |
} else if (wchance<bchance) { | |
chance = 1; | |
} else { | |
chance = -1; | |
} | |
switch (chance) { | |
case -1: whiteresult=1; blackresult=0; white.won++; black.lost++; break; | |
case 1: whiteresult=0; blackresult=1; white.lost++; black.won++; break; | |
case 0: whiteresult=0.5; blackresult=0.5; white.drawn++; black.drawn++; break; | |
} | |
var kwhite = (white.games<400)?400:150; | |
var kblack = (black.games<400)?400:150; | |
var ratings = elo(white.rating,black.rating,whiteresult,blackresult,kwhite,kblack); | |
white.rating = ratings.white; | |
black.rating = ratings.black; | |
} | |
//------------------------------------------------------------------ | |
//Initialize players | |
var init = function(){ | |
var player = function(name,skill){ | |
var self = this; | |
self.name = 'The ' + skills[skill] + ' ' + names[name]; | |
self.skill = name+skill+1; | |
//self.rating = 1000+rand1(skill*200); | |
self.rating = 1400; | |
self.games = 0; | |
self.won = 0; | |
self.lost = 0; | |
self.drawn = 0; | |
} | |
player.prototype.toString = function() { | |
var self = this; | |
var pct = function(a,b) { return Math.floor(a/b*100) + '%'; } | |
return [self.name+(self.name.length<16?'\t':''),Math.floor(self.rating),self.games,pct(self.won,self.games),pct(self.lost,self.games),pct(self.drawn,self.games)].join('\t\t'); | |
} | |
for(var n=0,nl=names.length;n<nl;n++) { | |
for(var s=0,sl=skills.length;s<sl;s++) { | |
players.push(new player(n,s)); | |
} | |
} | |
} | |
//------------------------------------------------------------------ | |
//Run simulation: | |
var simulate = function() { | |
for(var i=0,l=players.length;i<1000000;i++) { | |
var p1 = rand1(l),p2 = rand1(l); | |
if (p1===p2) p2=p2?p2-1:1; //A player cannot play himself | |
game(players[p1],players[p2]); | |
} | |
} | |
//------------------------------------------------------------------ | |
//Output results: | |
var output = function() { | |
players.sort(function(a,b) {return a.rating>b.rating?-1:1;}).map(function(player){console.log(player.toString())}) | |
}; | |
//================================================================== | |
//Do It! | |
init(); | |
simulate(); | |
output(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment