メインコンテンツへスキップ
記事一覧に戻る
programming

テトリスは運ゲーじゃない!7-bagアルゴリズムとマルチプレイ同期の仕組み

なぜテトリスは「運ゲー」ではないのか?公式ルールで採用されている7-bagアルゴリズムと、オンライン対戦で同じピース順を実現するシード乱数の仕組みを、実装コード付きで解説します。

2025-12-2413 min readAdabana Saki
-
テトリスアルゴリズムゲーム開発JavaScriptTypeScript乱数マルチプレイヤー

テトリスは運ゲーじゃない!7-bagアルゴリズムの仕組み

「テトリスって結局、運ゲーでしょ?」

そう思っている方も多いかもしれません。でも実は、公式テトリスには「運」を排除する巧妙な仕組みがあります。

この記事では、テトリスの7-bagアルゴリズムと、オンライン対戦で両プレイヤーに同じピース順を配る仕組みを、実際のコードと共に解説します。

7-bagアルゴリズムとは?

「完全ランダム」の問題点

もしピースが完全にランダムに出てきたらどうなるでしょう?

Text

完全ランダムでは、理論上「永遠にIミノが来ない」ことも起こりえます。これでは運の要素が強すぎて、スキルゲームとして成立しません。

7-bagの解決策

**7-bag(セブンバッグ)**は、この問題を解決するアルゴリズムです。

Text

7-bagの保証

このアルゴリズムにより、以下が数学的に保証されます:

保証内容詳細
最大待ち時間どのピースも最大12個以内に必ず来る
最小間隔同じピースが連続することはない
公平性全プレイヤーが同じ条件でプレイ可能
Text

実装してみよう

Fisher-Yatesシャッフル

7-bagの実装には「Fisher-Yates(フィッシャー・イェーツ)シャッフル」を使います。

これは配列を完全にランダムかつ均等な確率でシャッフルするアルゴリズムです。

TypeScript

なぜFisher-Yatesなのか?

他のシャッフル方法と比較してみましょう:

方法問題点
array.sort(() => Math.random() - 0.5)偏りが生じる(均等でない)
単純なループでswap同じ要素が何度も動く可能性
Fisher-Yates全ての並び順が等確率で出現
JavaScript

7-bag生成器の完全実装

TypeScript

マルチプレイヤーでの同期問題

7-bagが実装できました。でも、オンライン対戦ではどうでしょう?

問題:各プレイヤーのピース順がバラバラ

Text

解決策:シード付き乱数

**シード(種)**を使うことで、同じ乱数列を再現できます。

Text

シード付き乱数生成器の実装

線形合同法(LCG)

最もシンプルなシード乱数の実装が「線形合同法(Linear Congruential Generator)」です。

TypeScript

数学的な説明

Text

7-bagとシード乱数を組み合わせる

TypeScript

オンライン対戦での実装例

サーバー側:シードの生成と共有

TypeScript

クライアント側:シードを受け取って初期化

TypeScript

シーケンス図

Text

テストで正しさを検証

シード乱数が正しく動作することをテストで確認しましょう。

TypeScript

応用:お邪魔ブロックの穴位置

7-bagと同じ考え方は、お邪魔ブロックの穴位置にも使えます。

ぷよぷよテトリスの仕様

ぷよぷよテトリスでは、お邪魔ブロックの穴位置に70%継続ルールがあります:

Text

実装

TypeScript

なぜ70%なのか?

確率プレイ体験
100%(常に同じ)簡単すぎる。1列掘るだけで全消し
0%(常に変更)難しすぎる。ランダムに近い
70%適度な難易度。戦略的に対処可能

まとめ

概念目的実装方法
7-bag運要素を排除し公平にFisher-Yatesシャッフル
シード乱数マルチプレイで同期線形合同法(LCG)
70%ルールお邪魔ブロックの難易度調整確率的な穴位置継続

テトリスは「運ゲー」ではなく、数学とアルゴリズムで設計されたスキルゲームです。

この記事で紹介した技術は、テトリスに限らず様々なゲーム開発に応用できます:

  • カードゲームのデッキシャッフル
  • ローグライクのダンジョン生成
  • 対戦ゲームのマッチング条件

ぜひ自分のゲーム開発に活用してみてください!

完全な実装コード

この記事で紹介したコードの完全版は、GitHubで公開しています:

このシリーズの他の記事

このサイトでは、他にもオンライン対戦ゲームの実装記事を公開しています:

参考リンク