観戦モード フローチャート v1

4人プレイ(A,B,C,D)+観戦者 S。仕様書 v1 に合わせ、room_status(waiting / playing / rematch_vote)、revision、spectate_room_ok / room_updated 必須・room_closed を反映。利用者のアクション/プログラムの反応/画面表示を段階ごとに示す。

観戦者 部屋(待機) ゲーム中 ロビー
段階
観戦者 S
A
B
C
D
① ロビー
(観戦準備/部屋待機)
S(観戦者)
ロビー(部屋一覧)
【アクション】部屋IDを入力し「観戦する」ボタンを押す
【送信】spectate_room(room_id)
A
部屋画面(参加者 4人)
「ゲーム開始」可能
B
部屋画面(参加者 4人)
C
部屋画面(参加者 4人)
D
部屋画面(参加者 4人)
↓ S が「観戦する」実行
② 観戦参加
(spectate_room_ok)
S
【表示】room_status で分岐。waiting→部屋画面/playing→snapshot で盤面/rematch_vote→終了・待機表示。受信前に画面確定しない。
【受信】spectate_room_ok(room_id, role, room_status, revision, players, spectators_count, snapshot?)
A
部屋 or ゲーム開始直後
S 参加で room_updated を必ず送る(spectators_count 含む)
B
部屋
C
部屋
D
部屋
↓ A が「ゲーム開始」→ 4人でゲーム開始
③ ゲーム進行中
S
観戦画面(盤面・カード・ポイント・誰のターンか)
【アクション】カードクリック不可。操作は「観戦をやめる」のみ
【受信】room_updated, game_started, pair_taken, turn_ended, tribe_effect, cards_revealed, turn_timeout, player_eliminated 等(いずれも revision 付与)。表示更新にのみ使用。
A
ゲーム画面(自分のターンで2枚選択)
B
ゲーム画面(待機)
C
ゲーム画面(待機)
D
ゲーム画面(待機)
↓ ゲーム終了(残り1人 or ペアなし)
④ ゲーム終了
S
終了表示(勝者名・ポイント・ペア数)。「観戦をやめる(ロビーへ)」ボタン表示
【受信】game_ended(revision, points, pairs, winner_indices, next_phase)。同一イベントで role により「観戦を続ける/ロビーに戻る」に分岐。YOU WIN は出さない
A
終了オーバーレイ「再戦しますか?」(はい・いいえ)
B
終了オーバーレイ「再戦しますか?」
C
終了オーバーレイ「再戦しますか?」
D
終了オーバーレイ「再戦しますか?」
↓ 再戦選択中(S は「観戦を続ける」or「ロビーに戻る」)
⑤ 再戦選択中
(rematch_vote)
S
「観戦を続ける」/「ロビーに戻る」。続ける場合は「再戦準備中」・ready 人数・countdown 表示。投票 UI は出さない。
【受信】rematch_status_updated(ready_count, countdown_sec 等)。【ロビーに戻る】→ leave_room(room_id)
A
カウントダウン or 「参加者を待っています…」
B
再戦選択オーバーレイ
C
再戦選択オーバーレイ
D
再戦選択オーバーレイ
↓ S が「ロビーに戻る」を選択
⑥ S が観戦をやめる
S
【アクション】「ロビーに戻る」クリック
【送信】leave_room(room_id)。【受信】leave_room_ok(moved_to: "lobby")。サーバーは spectators から削除し room 内に room_updated を必ず送る
A
room_updated で観戦者数が減ったことを受信
B
再戦選択中
C
再戦選択中
D
再戦選択中
↓ サーバー処理後
⑦ 最終(S ロビー)
S
ロビー(部屋一覧)。観戦前と同じ画面。room_closed 受信時は「部屋が終了しました」表示後にロビーへ
【表示】部屋一覧を再取得。disconnect 時は spectators から削除され観戦状態は復元しない
A
再戦カウントダウン or 2回目ゲーム開始後はゲーム画面
B
再戦選択 or ゲーム中
C
再戦選択 or ゲーム中
D
再戦選択 or ゲーム中

段階ごと:利用者のアクション/プログラムの反応/画面表示

段階 利用者のアクション プログラムの反応 画面に表示する内容
観戦者 S:ロビーで部屋IDを入力し「観戦する」を押す。プレイヤー A,B,C,D:部屋で待機または「ゲーム開始」を押す。 (S が送信するまでサーバー側の変化なし) S:ロビー(部屋一覧・部屋ID入力欄・「観戦する」ボタン)。A,B,C,D:部屋画面(参加者 4人・ゲーム開始ボタン)。
S:「観戦する」送信済み。A:ゲーム開始押下で全員ゲーム画面へ。 spectate_room 受信→部屋が存在し参加可能なら spectators に S を追加、socket を room に join。spectate_room_ok で room_status, revision, players, spectators_count, snapshot? を返却。競合時も最新の room_status を返す。room_updated を必ず送る(観戦者数含む)。 S:room_status で分岐。waiting→部屋画面(参加者・観戦者数)。playing→snapshot で盤面初期描画。rematch_vote→終了・待機表示。spectate_room_ok 受信前に画面確定しない。A,B,C,D:ゲーム画面 or 部屋。
S:カードをクリックしない(不可)。「観戦をやめる」のみ可能。A,B,C,D:通常プレイ(2枚選択・ペア取得・ターン終了)。 状態更新系イベントは revision 付与。room_updated, game_started, pair_taken, turn_ended, tribe_effect, cards_revealed, turn_timeout, player_eliminated を room 宛に emit → S も受信。spectator の flip_cards / start_game 等はサーバーで reject(action_rejected)。 S:プレイヤーと同じ盤面・ポイント・「○のターン」・ターンタイマー・脱落状態。カードはクリック不可・「観戦中」ラベル・「観戦をやめる」ボタン。A,B,C,D:通常のゲーム画面。
全員:ゲーム終了の結果を見る。S:勝者・ポイントを確認し、続けて観戦するかロビーに戻るか選ぶ準備。 game_ended を room 宛に emit(revision, points, pairs, winner_indices, next_phase: "rematch_vote")。観戦者専用イベントは作らず、同一 game_ended を S も受信。クライアントが role で UI 分岐。 S:終了オーバーレイ(勝者名・各プレイヤーのポイント・ペア数)。「観戦を続ける」「ロビーに戻る」ボタン。A,B,C,D:終了オーバーレイ「再戦しますか?」(はい・いいえ)。
S:「観戦を続ける」→ rematch_status_updated で再戦準備中・カウント表示。「ロビーに戻る」→ leave_room 送信。A,B,C,D:はい/いいえ選択。 rematch_status_updated(ready_count, countdown_sec 等) を spectator も受信。S が leave_room 送信→spectators から削除、leave_room_ok 返却。room 内に room_updated を必ず送る(観戦者数含む)。 S:「再戦準備中」・ready 人数・countdown。投票 UI は出さない。ロビーに戻る選択後はロビー画面。A,B,C,D:再戦カウントダウン or 「参加者を待っています…」。
⑥〜⑦ S:ロビーで他部屋を観戦したり、自分で部屋を作成・参加できる。A,B,C,D:再戦 or 人数不足でロビーへ。 disconnect 時は spectators から削除し room_updated を送る。観戦状態は自動復元しない。player が 0 人になったら room を closed とし、観戦者全員に room_closed(reason: "no_players") を送りロビーへ。再戦開始時は game_started を room 全体に送る(観戦者も受信)。 S:ロビー。room_closed 受信時は「部屋が終了しました」表示後にロビーへ。A,B,C,D:再戦でゲーム再開 or ロビー。

補足:観戦モードで送受信するイベント(仕様書 v1 準拠)

種別 イベント 観戦者 S の扱い
観戦参加spectate_room(room_id)S が送信。正常時は spectate_room_ok(room_status, revision, players, spectators_count, snapshot?)。失敗時は spectate_room_error。room_updated を必ず送る。
配信(受信・revision 付与)room_updated, game_started, cards_revealed, pair_taken, tribe_effect, turn_ended, turn_timeout, player_eliminated, game_ended, rematch_status_updated, room_closedroom 宛 emit のため S も受信。表示更新にのみ使用。古い revision は破棄。
観戦退出leave_room(room_id)S が送信。サーバーは spectators から削除し leave_room_ok を返す。room 内に room_updated を必ず送る。
送信禁止flip_cards, start_game, rematch_ready, rematch_declineS は送信不可。サーバーで reject し action_rejected(SPECTATOR_NOT_ALLOWED) を返す。UI でもボタン非表示/無効化。