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

2048オンライン対戦で「公平」を実現する方法:シード乱数の魔法

2048のオンライン対戦で両プレイヤーに同じタイル配置を保証するシード乱数の仕組みと、リアルタイム同期の実装方法を解説します。クライアント側でゲームロジックを実行しながら公平性を担保するテクニック。

2026-01-0514 min readAdabana Saki
-
2048シード乱数Cloudflare WorkersWebSocketリアルタイム通信TypeScriptゲーム開発

2048オンライン対戦で「公平」を実現する方法

「2048の対戦版を作りたい」

そう思ったとき、最初にぶつかる壁は公平性です。2048は新しいタイルがランダムに出現するゲーム。対戦で両者に違うタイルが出てきたら、それは純粋に運ゲーになってしまいます。

この記事では、シード乱数を使って2048対戦の公平性を実現する方法と、リアルタイム同期の実装を解説します。

公平な対戦とは?

2048のランダム要素

2048には2つの重要なランダム要素があります:

  1. 初期タイル: ゲーム開始時に2つのタイルが配置される
  2. 新規タイル: 移動後に新しいタイル(2か4)が出現する
Text

対戦では、両プレイヤーにまったく同じランダム結果を提供する必要があります。

シード乱数という解決策

シード乱数は、「種(シード)」となる数値から決定的な乱数列を生成します。

Text

これにより、サーバーはシード値だけを両プレイヤーに送れば、両者が同じタイル配置でプレイできます。

シード乱数生成器の実装

線形合同法

最もシンプルで高速なシード乱数は「線形合同法(LCG)」です:

TypeScript

なぜこのパラメータ?

Text

2048でのタイル配置

初期タイルの配置

ゲーム開始時、同じシードから同じ初期配置を生成します:

TypeScript

タイル配置関数

TypeScript

両プレイヤーで同じ結果になる理由

Text

重要なのは、乱数を呼び出す順序が両者で同じであること。移動の操作ごとに1回addSeededTileを呼ぶので、同じ手順でプレイすれば同じ結果になります。

グリッド操作の実装

回転によるスライド処理の統一

2048は4方向にスライドできますが、実装では「左にスライド」だけを実装し、グリッドを回転させることで全方向に対応しています:

TypeScript

グリッドの時計回り回転

TypeScript
Text

スライドとマージ

TypeScript

サーバー側の実装

Durable Objectでルーム管理

TypeScript

ゲーム開始時のシード生成

TypeScript

スコアのリアルタイム同期

2048はクライアント側でゲームロジックを実行しますが、スコアは定期的にサーバーに送信します:

TypeScript

クライアント側の実装

React Hookでの状態管理

TypeScript

ゲームコンポーネントでのシード初期化

TypeScript

勝敗判定のロジック

勝利条件

2048対戦には複数の勝利条件があります:

条件説明
2048達成最初に2048を作ったプレイヤーが勝利
時間切れスコアが高い方が勝利
相手ゲームオーバー相手が動けなくなったら5秒後に判定
退出相手が離脱したら自動勝利

2048達成時の処理

TypeScript

片方がゲームオーバーになった場合

TypeScript

この「5秒ルール」により、相手がゲームオーバーになっても少し時間をもらえます。逆転の可能性を残しつつ、無限に待たされることも防ぎます。

相手の盤面表示

対戦の緊張感を高めるため、相手の盤面もリアルタイムで表示します:

TypeScript

これにより、相手がどんな状況かを把握しながらプレイできます。

アニメーションの実装

Framer Motionを使って、タイルのアニメーションを実装しています:

TypeScript

タイルのIDを使って、Reactが正しくアニメーションを追跡できるようにしています。

まとめ

技術要素採用した解決策
公平性シード乱数で同じタイル配置を保証
通信WebSocket(Durable Objects)
ロジッククライアント側で実行(レスポンス向上)
同期スコアと盤面を定期送信
アニメーションFramer Motion

シード乱数を使うことで、サーバーはシード値を1回送るだけで公平な対戦を実現できます。クライアント側でゲームロジックを実行するため、レスポンスも良好です。

この「シードだけ共有してクライアントで計算」というパターンは、他のパズルゲームやローグライクにも応用できます。

遊んでみる

実際に2048バトルを遊んでみたい方は、こちらからどうぞ:

ソースコード

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

このシリーズの他の記事

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

参考リンク