Skip to content

Instantly share code, notes, and snippets.

@binarymax
Last active December 24, 2015 19:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save binarymax/6854806 to your computer and use it in GitHub Desktop.
Save binarymax/6854806 to your computer and use it in GitHub Desktop.
Elo rating simulation
/*********************************
*
* 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