なぜチーム分けツールを作ったのか
ゲーム仲間と集まって遊ぶとき、いつも困るのが「チーム分け」です。
じゃんけんで決める?リーダーが交互にメンバーを選ぶ?どちらも悪くないのですが、人数が多いと時間がかかります。それに、同じ人ばかりが組んでしまって不公平感が出ることも。
「もっと公平に、サクッとチーム分けできたら便利なのに…」
そんな思いから、ブラウザで動くグループ分けツールを自作しました。ChatGPTを活用しながら試行錯誤した過程を、この記事でお伝えします。
最初の挑戦:シンプルなランダムシャッフル
どこでも使えるHTML版を目指す
まずは、HTMLファイル1つで動くシンプルなツールを作ることにしました。
作りたい機能は次の通りです:
- テキストボックスに参加者の名前を入力
- ボタンを押すと、JavaScriptの
Math.random()でシャッフル - 4人ずつのグループに自動で振り分け
理論上は完璧なはず。早速作って試してみました。
すぐに見つかった問題点
ところが、実際に使ってみると大きな問題が発覚しました。
短時間で何度も「グループ分け」ボタンを押すと、ほぼ同じ組み合わせが出てくるのです。
これでは意味がありません。せっかく作ったのに、実用性はゼロです。
解決策:シード値で乱数をコントロール
乱数の「偏り」の正体
問題の原因を調べてみると、乱数には「シード値」という初期値があることを知りました。
Math.random() は便利な関数ですが、短い時間で連続して実行すると似た結果になりやすい特徴があります。これが偏りの原因だったのです。
ならば、自分でシードを作って乱数をコントロールしてしまおう。
ChatGPTに助けてもらう
ここで頼りになったのがChatGPTです。
「シードを指定して乱数を作る方法を教えて」と質問すると、線形合同法(Linear Congruential Generator, LCG) を使ったサンプルコードを提案してくれました。
これを組み込めば、自分で好きなシード値を設定して乱数を生成できます。
ユニークなアイデア:円周率100桁を活用
シード値をどう作るか
次の課題は「どうやってシード値を作るか」です。
毎回違う値にしたいけど、完全にランダムだと再現性もない。そこで思いついたのが、円周率の小数点以下100桁を使う方法でした。
実装のステップ
具体的な仕組みはこうです:
- 円周率100桁を文字列として用意
あらかじめ定数として保存しておきます - ランダムに4桁を切り出す
100桁の中から任意の位置で4桁を取得 - 現在時刻を組み合わせる
切り出した数値に、現在のミリ秒を足してシード値を作成 - 乱数を生成
そのシードを使って線形合同法で乱数を作る
「時間+円周率」という2つの要素の組み合わせで、毎回異なる結果を生み出せるようになりました。
実際のコード
使った計算式は以下の通りです:
const PI100 = "14159265358979323846264338327950288419716939937510" + "58209749445923078164062862089986280348253421170679";
function seededRandomGenerator(seed) {
let value = seed % 2147483647;
if (value <= 0) value += 2147483646;
return function() {
<pre><code>value = value * 16807 % 2147483647;
return (value - 1) / 2147483646;
</code></pre>
};
}
コード内の定数について
このコードには、一見すると不思議な数字が2つ出てきます。これらには実はちゃんと意味があるんです。
2147483647という数字
これは 2^31 - 1(2の31乗マイナス1)という特別な数字で、メルセンヌ素数と呼ばれています。
なぜこの数字を使うかというと:
- コンピュータで扱いやすい範囲(32ビット整数の最大値付近)
- 素数なので、乱数の周期が長くなって偏りにくい
- 計算が効率的にできる
16807という数字
これは 7^5(7の5乗)です。線形合同法という乱数生成アルゴリズムで使われる「乗数」として、よく選ばれる値です。
この2つの数字の組み合わせはMINSTD(Minimum Standard) と呼ばれる、昔から使われている信頼性の高い乱数生成方法の定数なんです。
難しそうに見えますが、要は「ちゃんとバラけた乱数を作るために、数学的に検証された数字を使っている」ということです。
シンプルな計算式ですが、これだけで安定した乱数生成が可能になります。
結果:実用的なツールが完成
毎回グループ分けに苦労していた時間が大幅に短縮されました。
ボタン一つで公平なチーム分けができるようになり、ゲーム開始までがとてもスムーズになりました。
今後の改善ポイント
作ってみて、「ここをもっと良くしたいな」と思った点もいくつかあります:
機能面の強化
- 人数を自由に設定
今は4人固定ですが、3人や5人にも対応したい - 抽選アニメーション
結果が出るまでの演出を入れて盛り上げたい
利便性の向上
- 履歴機能の追加
過去の組み合わせを保存して、同じパターンを避ける - スマホ対応UI
現場で使うことが多いので、タッチ操作しやすいデザインに
今のツールはあくまで「ベース」です。使うシーンに合わせてカスタマイズすれば、もっと面白くなりそうです。
まとめ
「ゲームで4人1組のグループを作りたい」というシンプルな発想から始まったこのプロジェクト。
最初は偏りだらけの乱数に悩まされましたが、シード値の工夫で解決できました。円周率100桁と現在時刻を組み合わせるというアイデアで、よりバラけたチーム分けが実現しました。
難しい数式や高度なアルゴリズムを知らなくても、ChatGPTを活用すればここまで作れる──これは正直驚きでした。
もし同じように「チーム分けをもっと楽にしたい」と思っている方がいたら、ぜひこの方法を試してみてください。
ゲームの準備時間が短くなれば、その分プレイ時間を楽しめますよ!


コメント