From f64c502086f2263e5bac40bba1dd6239e4e4a858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8E=E5=8F=A3=E7=85=8C=E9=99=BD?= Date: Fri, 30 Oct 2026 22:56:37 +0900 Subject: [PATCH] Wait for the host to press "next hand" on every table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously only the review CPU table paused after each hand; cash-only, friends and CPU tables moved on automatically after a short delay. Now every table keeps the result on screen until the host presses 次のハンドへ, and the next hand is dealt right away. If the host has left, the new host presses it; with no human seated the table still advances on its own. Co-Authored-By: Claude Opus 5.5 --- README.md | 2 +- public/assets/table.js | 24 ++++++++++++------ public/table.html | 6 ++--- server/index.js | 2 +- server/tables.js | 37 +++++++++++++++++----------- test/engine.test.js | 55 +++++++++++++++++++++++++++++++++++++++++- test/review.test.js | 6 ++--- test/seating.test.js | 2 ++ 8 files changed, 103 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index f8d6645..999fd17 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ | レビュー付きCPU戦 | 管理者だけが作れる。作成者と CPU だけで遊び(友達は入れない・ロビーにも出ない)、ハンドごとにレビューが出る(下の「管理者」を参照) | - ポーカーのルール(ブラインド・手番・最低レイズ額・再レイズ権・返金・サイドポット・ショーダウンの判定と分配)と役の判定は、公開ライブラリ [@pokertools/engine](https://www.npmjs.com/package/@pokertools/engine) / [@pokertools/evaluator](https://www.npmjs.com/package/@pokertools/evaluator)(MIT、バージョン固定)に任せている。 -- ノーリミット・テキサスホールデムのリングゲーム(最大9人)。ホストが START を押すと、以降は2人以上いる限り自動でハンドが続く。 +- ノーリミット・テキサスホールデムのリングゲーム(最大9人)。ホストが START を押すとハンドが始まる。ハンドが終わると結果を表示したまま止まり、ホストが「次のハンドへ」を押すと次のハンドが配られる(ホストが退席したら次のホストが押す。人間が誰も着席していなければ待たずに進む)。 - 画面にディーラーボタン(D)・SB・BB と、いまのストリート(PREFLOP / FLOP / TURN / RIVER)が出るので、それに合わせて実物のカードを配る。 - ブラインドは自動で支払われ、ハンド開始時のレベルで固定。BB は SB より大きくする。ヘッズアップはボタンが SB。 - 各自が自分のスマホで Fold / Check / Call / Bet / Raise を行う。最低レイズ額は直前のレイズ幅以上。足りないオールインのレイズは、すでにアクションした人に再レイズ権を与えない。 diff --git a/public/assets/table.js b/public/assets/table.js index aca6ad0..f9ff01a 100644 --- a/public/assets/table.js +++ b/public/assets/table.js @@ -464,9 +464,12 @@ let status = ''; if (!s.started) status = s.isHost ? '2人以上揃ったら START を押してください' : 'ホストの開始を待っています'; else if (s.paused) status = '一時停止中'; - else if (s.review && s.review.waiting) status = 'レビューを確認したら「次のハンドへ」を押してください'; + else if (s.awaitingNext && s.isHost) { + status = s.review ? 'レビューを確認したら「次のハンドへ」を押してください' : '「次のハンドへ」を押すと次のハンドを始めます'; + } else if (m.sittingOut) status = '離席中です。復帰すると次のハンドから参加します'; else if (m.canRebuy) status = 'チップがなくなりました'; + else if (s.awaitingNext) status = 'ホストが次のハンドを始めるのを待っています'; else if (o) status = o.canCheck ? 'あなたの番です' : `あなたの番です(コール ${chips(o.toCall)})`; else if (awaiting) status = m.canAward ? 'カードを見せ合って、勝った人を選んでください' : 'ホストが勝者を選んでいます'; else if (h && !h.finished && s.toAct != null) { @@ -488,15 +491,19 @@ if (awarding) renderAwardPanel(h.pots); // ボタン - const reviewWaiting = Boolean(s.review && s.review.waiting); - const alt = (m.sittingOut || m.canRebuy) && !awarding && !reviewWaiting; + // ハンドが終わったら、ホストが「次のハンドへ」を押すまで待つ(レビュー付きCPU戦はレビューも開ける) + const nexting = Boolean(s.awaitingNext && s.isHost && !s.paused); + const alt = (m.sittingOut || m.canRebuy) && !awarding; if (!o) raising = false; - $('review-actions').hidden = !reviewWaiting; + $('next-actions').hidden = !nexting; + $('next-actions').classList.toggle('raising', Boolean(s.review)); + $('next-actions').classList.toggle('single', !s.review); + $('review-show').hidden = !s.review; $('alt-actions').hidden = !alt; $('sit-in').hidden = !m.sittingOut; $('rebuy').hidden = !m.canRebuy; $('rebuy').textContent = `リバイ(${chips(s.startingStack)})`; - $('actions').hidden = alt || awarding || reviewWaiting; + $('actions').hidden = alt || awarding || nexting; if (raising && o && !alt) { renderRaisePanel(o); betSheet.open(); @@ -593,7 +600,8 @@ // 同じタブで開き、レビューの画面の「テーブル」で戻ってこられるようにテーブルIDを渡す const back = `t=${encodeURIComponent(tableId)}`; $('review-link').href = r.sessionId ? `/review?s=${encodeURIComponent(r.sessionId)}&${back}` : `/review?${back}`; - $('review-modal-next').hidden = !r.waiting; + const waiting = Boolean(s.awaitingNext && s.isHost); + $('review-modal-next').hidden = !waiting; const key = JSON.stringify(r); if (key !== reviewKey) { reviewKey = key; @@ -602,7 +610,7 @@ // 新しいハンドのレビューが届いたら自動で開く if (r.last.number !== seenReview) { seenReview = r.last.number; - if (r.waiting) reviewSheet.open(); + if (waiting) reviewSheet.open(); } } @@ -626,7 +634,7 @@ emit('table:next'); }; $('review-copy').addEventListener('click', () => copyHandPrompt(state && state.review)); - $('review-next').addEventListener('click', nextHand); + $('next-hand').addEventListener('click', nextHand); $('review-modal-next').addEventListener('click', nextHand); // ---------- ランキング(スタック順・収支順を切り替える) ---------- diff --git a/public/table.html b/public/table.html index c021c74..27fcfe9 100644 --- a/public/table.html +++ b/public/table.html @@ -96,9 +96,9 @@ -