diff options
author | Tor Andersson <tor@ccxvii.net> | 2024-01-02 16:28:48 +0100 |
---|---|---|
committer | Tor Andersson <tor@ccxvii.net> | 2024-01-02 17:06:50 +0100 |
commit | f794c5379baf12d6dbc4b4d02a1e44604e1def00 (patch) | |
tree | 4da8d1fe1badc05437ec8e862a32c77be64a47b6 /tools/elo.js | |
parent | c7fb66f0903d4d7b7e6c04dc33a3e5e9d3a3068d (diff) | |
download | server-f794c5379baf12d6dbc4b4d02a1e44604e1def00.tar.gz |
Handle multiple winners for Elo calculations.
Diffstat (limited to 'tools/elo.js')
-rw-r--r-- | tools/elo.js | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/tools/elo.js b/tools/elo.js index a6f9c9d..ad0dbad 100644 --- a/tools/elo.js +++ b/tools/elo.js @@ -8,6 +8,11 @@ const SQL_SELECT_GAMES = db.prepare("select * from rated_games_view order by mti const SQL_SELECT_RATING = db.prepare("select * from player_rating_view where game_id=?") const SQL_INSERT_RATING = db.prepare("insert or replace into ratings (title_id,user_id,rating,count,last) values (?,?,?,?,?)") +function is_winner(role, result) { + // NOTE: uses substring matching for multiple winners instead of splitting result on comma. + return (result === "Draw" || result === role || result.includes(role)) +} + function elo_k(n) { return n < 10 ? 60 : 30 } @@ -27,28 +32,29 @@ function elo_change(a, players, s) { function update_elo_ratings(game) { let players = SQL_SELECT_RATING.all(game.game_id) + if (game.player_count !== players.length) return - let winner = null + if (!game.result || game.result === "None") + return + + let winners = 0 + for (let p of players) + if (is_winner(p.role, game.result)) + winners ++ + + if (winners === 0) + return + for (let p of players) - if (p.role === game.result) - winner = p - - if (winner) { - for (let p of players) { - if (p === winner) - p.change = elo_change(p, players, 1) - else - p.change = elo_change(p, players, 0) - } - } else { - for (let p of players) - p.change = elo_change(p, players, 1 / game.player_count) - } + if (is_winner(p.role, game.result)) + p.change = elo_change(p, players, 1 / winners) + else + p.change = elo_change(p, players, 0) for (let p of players) - SQL_INSERT_RATING.run(game.title_id, p.user_id, p.rating + p.change, p.count+1, game.xtime) + SQL_INSERT_RATING.run(game.title_id, p.user_id, p.rating + p.change, p.count + 1, game.mtime) } db.exec("begin transaction") |