概要、はじめに
本記事は「N/S高等学校 Advent Calendar 2022」の9日目にあたります。
私はN/S高で働いている傍ら、趣味として卓球をしています。
しかし、社会人が自分のレベルに合った練習相手を探すのは結構難しいものです・・・。
オンラインゲームのように「レーティングシステム」が一般の人たちにまで浸透していたら練習相手を探すのも幾分楽になりそうだと思い、自分でそのプログラムが組めないものか調べてみました。
すると、レーティングシステムの計算方法を取り込むだけならば、非常に簡単であることが判明したので、記事にしておきたいと思います。
前提、実施方法
レーティングシステム・・・イロレーティング
└様々なシステムで採用されているレート計算方法
実行環境・・・GAS、スプレッドシート
└レーティング計算さえ出来ればいいので、環境構築不要なgasで作成してみました。
まずは結果から
レーティングの記事を読むと前提となる式が難しいですが、結果的に出てくる計算式は至ってシンプルです。
以下の関数で一般的なイロレートの計算ができます。
function calculatePoint(winnerRate, loserRate){
const K = 32;
let point = K / (10 ** ( (winnerRate - loserRate) / 400 ) + 1);
return point;
}
いい感じですね。レート差が開いた状態で、レート上位者が下位者に勝っても得られるレートは少なく、逆にジャイアントキリングのような勝ち方をするとレートが大きく変動します。
また、Kの値が大きいほどレートの変更幅が大きく、小さいほど変更幅も小さくなります。Kには32を入れることが多いですが、(チェスや将棋などの)プロの世界では16を用いるのが一般的みたいです。
調整する
しかし、レート2000の人が1000の人に勝っても得られるのが0.1ポイントだと寂しいですよね。
そこでclampと言われる、得点の最低値、最大値を定めて調整することが多いそうです。
(clampはHTMLやCSSなどフロントで使うことも多い用語ですが、今回は上記の計算結果の範囲を設定すると言う意味でのclamp関数を作成します。)
clampの関数も簡単に自作して組み込むと以下の通り。
function calculatePoint(winnerRate, loserRate){
const K = 32;
let point = K / (10 ** ( (winnerRate - loserRate) / 400 ) + 1);
point = clamp(point, 2, 32);
return point;
}
function clamp(point, min, max){
if(point < min){
return min;
}else if(max < point){
return max;
}else{
return point;
}
}
これをGASに組み込んで実行すると以下のようになり、上位者も最低限のレートを得られるようになりました。
おわりに
今回はレート計算の方法について学びました。
実は草卓球界(?)でも少しずつこのレーティング方式が始まっているみたいです。もっと言うと、欧米などではみんなが自分のレートを把握していて、練習相手を見つけたり、大会を主催する目安にしたりしているそうです。
レーティングシステムを搭載した、スポーツマッチングサイトなどが作れたら面白そうですね。
参考Webページ
wikipedia・イロレーティング
Manicreator・イロレーティング完全に理解した
Debugging as Usual・[関数命名] 数値を範囲内に収める clamp