@truell20, absolutely. My initial simulation was overly simplistic so below is a slightly more rigorous simulation. It's in javascript, so those who dont like curly braces, cover your eyes please.
TLDR : in total across all 1600 players, many tens of thousands of games are run. To converge to 0.1 score difference between two identical players, one of whom is penalised to simulate timeouts, it seems to take 200-400 games (source: ran 4x , very scientific )
Key points:
1) requires trueskill, lodash, probability-distributions, all installable via npm
2) an array of 1600 players with true rank 0,1,...1599 (0 is the best) is initialised. Players 2 and 3 are set to the same true rank . Every player has an initial skill array = [mu, sigma ] = [25,25/3] , and score = mu-3*sigma
3) We pick 2-6 players according to the halite distribution, and weighted by the square of their sigma ^2
(this is the way halite does it iirc, ie not the stdev but the variance?)
4) Each player gets an in-game rank which is : their true rank plus some randomness. This is to ensure a player could be beaten by someone 10 true places on average below them
5) player 2 is forced to lose 10% of the first 40 games (this is pretty tame, i can see some of you have 8-10 losses )
6) we run till players 2 and 3 have completed at least 41 games and their scores converge to within 0.1
(the 41 games is to prevent termination at 0 games , when their scores are within 0.1 of each other)
for example, the final output of a run could look like :
...
65870 total games played ------
Player 2 ngames : 177
Player 2 score : 70.65178381699933
Player 2 skill : 83.38413422814966,4.264651198306916
Player 3 ngames : 373
Player 3 score : 70.72401365247441
Player 3 skill : 89.62387460208126,4.856915870295299
in total across all 1600 players, many tens of thousands of games are run, for players 2 and 3 to converge to within 0.1 it seems to take 200-400 games (source: ran 4x , very scientific )
and now the code
var trueskill = require("trueskill")
var _ = require('lodash')
var PD = require("probability-distributions");
var nplayers = 1600
var nplayersDistr = [2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6]
var players = [],totalGames = 0.0
var gamePlayers, nplayersInGame, pickProbs, showStatus
// initialise the player array
for (var i = 0; i < nplayers; i++) {
players.push(
{
index: i,
truerank: i,
skill: [25.0, 25.0 / 3.0],
score: 0,
ngames: 0
})
}
// set player 2 and player 3 to have the same true rank
players[3].truerank = players[2].truerank
while (players[2].ngames <= 40 || players[3].ngames <= 40 || Math.abs(players[2].score - players[3].score) > .1) {
//the probability of getting picked = square of current trueskill sigma
pickProbs = _.map(players, function(p) {
return Math.pow(p.skill[1], 2)
})
nplayersInGame = PD.sample(nplayersDistr, 1)[0]
gamePlayers = PD.sample(players, nplayersInGame, false, pickProbs)
showStatus = false
_.forEach(gamePlayers, function(p)
{
// set the players rank for this game
p.rank = p.truerank + Math.random() * 20
//force player 2 to lose 10% of the first 40 games
if (p.index == 2 && p.ngames <= 40)
{
p.rank = Math.random()<.1?2000:p.rank
}
p.score = p.skill[0]-3*p.skill[1]
p.ngames++
// log info if either player 2 or 3 was in this game
showStatus = showStatus || (p.index == 2 || p.index == 3)
})
//update skill mu and sigma
try
{
trueskill.AdjustPlayers(gamePlayers)
}
catch(err) {}
totalGames++
if (showStatus)
{
console.log(totalGames + " total games played ------")
console.log("Player 2 ngames : " + players[2].ngames)
console.log("Player 2 score : " + players[2].score)
console.log("Player 2 skill : " + players[2].skill + '\n')
console.log("Player 3 ngames : " + players[3].ngames)
console.log("Player 3 score : " + players[3].score)
console.log("Player 3 skill : " + players[3].skill + '\n')
console.log("----------------")
}
}