前回(第12回)では、Singleton Matchmaker DOを利用したマッチングシステムを実装し、プレイヤー同士が対戦を開始できる環境を構築しました。
今回はゲーム本体の実装編(モックアップ作成)です。
モックアップによる対戦テストを通じて見えてきた課題を解決するため、『Logic High and Low』のルールを「v1」として大幅に見直しました。また、それに合わせてゲーム画面の実装と、今後の機能追加に耐えられるようフロントエンドのモジュール化(ファイル分離)も行いました。

1Deck制からセットマッチ制への進化(ルール策定の背景)
当初のサンプルでは、「1Deck(7枚引き切り)」で終了するシンプルな仕様でテストを行っていました。しかし、実際にプレイヤー同士で動かしてみたところ、以下の2つの大きな課題が浮き彫りになりました。
- 「完全試合」によるハメの発生
アイテム(透視など)の組み合わせによって山札のルートが確定してしまうと、先手をとったプレイヤーがそのまま1手も渡さずに引き切る「完全試合(ハメ)」が頻発し、対戦ゲームとしてのインタラクティブ性が損なわれる。 - 運の要素によるスコアのインフレ
数Deck分の全スコア総計制も検討しましたが、これでは「たまたま運良く高い数字が連続してPushが繋がった1回のDeck」の稼ぎが勝敗のすべてを決めてしまい、実力差が出にくい。
そこで、テニスや卓球、あるいは格闘ゲームのような「セット先取制」を導入することにしました。さらに、1つのセットに深みを持たせるため、1セット=3Deck(計21枚の消化)で競う形へとルールをアップデートしました。
1.『Logic High and Low』コアルールの確定
前回のP2P導通テストとモックアップでの検証を経て、ゲーム本編のルールを「ただの運ゲー」から「競技性の高いロジカル・マインドスポーツ」となれるようにルールを調整しました。
■ コンセプトと世界観
ジャンルは「対戦型ロジカル・ハイアンドロー」。プレイヤーはサイバーパンク世界のエージェントとなり、コマンド(アイテム)を駆使してシステム(盤面)の完全なパスを導き出すハードコアな頭脳戦です。
■ デッキと盤面の仕様(カウンティングと不完全情報)
- 基本構成: 1〜10の数字が書かれた「10枚」のカードを使用。
- Void(除外)システム: ゲーム開始時、ランダムに「3枚」が裏向きのままVoid(除外領域)に送られ、残った「7枚」を引き切った時点で1Deckが終了します。
公開されたカードから残りの数字を推測(カウンティング)できますが、Voidの存在により、コマンドを使わない限り「100%の確証」は得られないという絶妙なジレンマを生み出しています。
■ プレイヤーのアクションとBust(失敗)の代償
手番プレイヤーは「HIGH / LOW の予想」「FOLD(利確)」「アイテムの使用」からアクションを選択します。
- 成功と利確: 予想が当たればカードは「ポット」に貯まり、手番が継続します。好きなタイミングでFOLD(利確)すれば、ポットの枚数を自身のスコアとして獲得できます。
- Bust(失敗)の恐怖: もし予想が外れた場合、ポットに貯まっていたカードは「すべて相手のスコア」として加算され、手番を失います。欲張れば欲張るほど、ミスした時の相手への塩送りが致命傷になります。
■ 勝利条件(セットマッチ制)
格闘ゲームのようなセット先取制(例:2セット先取でマッチ勝利)を採用しました。
1セットは、以下のいずれかの条件で決着します。
- 11点(枚)先取: セット内で累計11枚のスコアを先に獲得する。
- 21枚消化による判定: 3Deck(7枚×3回=21枚)を引き切った時点で、スコアが多い方が獲得。
これにより、1セットが冗長になるのを防ぎ、スピーディな展開を強制しています。
■ 【新要素】アイテム・ドラフトピック制
今回、ゲームの戦略性を根本から引き上げる要素として「ドラフトピック制」を導入しました。
各セットの開始前インターバルで、システムからランダムなコマンド(アイテム)が複数提示されます。1Pと2Pは交互にアイテムをピックし、自分のインベントリ(3枠)を構築してからセットを開始します。
「相手が防御系の透視を取ったから、自分は盤面を荒らすModを取る」といった、試合開始前からのメタゲーム(読み合い)が発生し、単なる運ゲーを完全に排除しました。
2. 実装
実装するにあたり、1ファイル管理は大変なので、以下のようなよくある形式でファイル分離することにしました。
#フォルダ構成イメージ
public/logic-highandlow/
├── index.html # SPAの土台(すべての画面要素をここに記述し、非表示で切り替える)
├── css/
│ ├── base.css # CSS変数(色やサイズ)、全体のリセット
│ ├── components.css # ボタン、カード、モーダルなど共通のUI部品
│ └── views.css # 各画面固有のレイアウトと、レスポンシブの制御
├── js/
│ ├── main.js # エントリーポイント(全体の初期化とモジュール連携)
│ ├── ui.js # DOM操作、画面の切り替え、アニメーション専用
│ ├── network/
│ │ ├── match.js # 受付係(Matchmaker DO)とのWebSocket通信
│ │ └── webrtc.js # 試合会場(GameLobby DO)とのシグナリング・P2P通信
│ └── game/
│ ├── state.js # ゲームの「状態(点数、カード、ターン)」だけを保持する変数群
│ ├── draft.js # ドラフトピック専用のロジック
│ └── core.js # ゲームのルール判定(勝敗、アイテム効果の処理)
└── assets/ # アイコン画像や効果音とか配置用3. 実装結果(UI)
実装したモックアップの各フェーズでの現状の実装状況をまとめます。
3-1.アイテムドラフト
ゲームが開始(マッチ成功)すると、まず双方の準備完了待ちがあり、準備完了するとまずアイテムのドラフトができます。ここでは、ランダムに選択された6つのアイテムが表示され、双方とも3つほしい順にアイテムを選択します。
アイテム選択で同じドラフトでかぶらなければ双方獲得、かぶったら乱数で獲得できるかどうかが決まるようにしました。
実装画面


3-2.ゲーム画面
ゲーム画面はゲームルールを考える:ハイアンドローモックアップ【CFW P2P心理戦ゲーム開発記】 #9とほぼ同じですが、アイテムを使えるようになりました。


3-3.リザルト画面
リザルト画面は、セット情報とスコアを表示し、レート変動の結果などを表示するようにしました。
レートは第6回に実装したEloのレートAPIをたたくようにしているため、安全にレート変更できます。

まとめ
今回は、今後の拡張のためのフォルダ-ファイル構成の見直しと、ゲームの基本1セッション(マッチ、ゲーム待機、アイテムドラフト、ゲーム、3セット先取でのリザルト移行)までを行えるようにしました。
関連記事
CloudFlare Workersセットアップ
Cloudflare Workersの始め方:Wranglerによるローカル環境構築と世界公開の手順
【第4回】ユーザデータベース実装
D1データベース実装:ユーザデータ管理 【CFW P2P心理戦ゲーム開発記】 #4
【第6回】Eloレート実装
Cloudflare Workersで創るP2Pゲーム記:チートを断つEloレーティング実装とアトミック検証 【CFW P2P心理戦ゲーム開発記】 #6
【第9回】ゲームデザインとアイテム実装
ゲームルールを考える:ハイアンドローモックアップ【CFW P2P心理戦ゲーム開発記】 #9
次回予告
次回は、今回作ったゲームの基本的流れに合わせてUIを作り込んでいこうと思います。コンセプトアートの作成と3d風の奥行きを持たせたUIをcssとjsを駆使して実装していく予定です。
次回:コンセプトアートとゲームUIに着手
関連記事は、2026年6月24日に公開予定 (あと46分)
ここまで読んでいただきありがとうございます。 では、次の記事で。 lumenHero