Add CPU opponents and a table type selector (cash only / friends / CPU)
- Create screen: choose キャッシュオンリー (real cards, chips only), 友人戦 (server deals and settles) or CPU戦 (友人戦 plus 1–8 CPU players); replaces the card toggle. The lobby shows each table's type - Poker AI written from scratch (server/ai.js, no libraries): fast 7-card evaluator (checked against bestHand), Monte Carlo equity, and decisions from hand rank, pot odds, raise count, opponents and a per-CPU style (aggression, bluff rate); continuation bets via the last aggressor. It never sees other players' hole cards - CPU seats: think time of 0.7–1.8s (faster when no human is left in the hand), automatic rebuy, never the host, no new hand unless a human is playing, re-think after pause - Play UI: robot avatars and a "考えています…" status for CPU turns - Tests for the evaluator, equity, legality of AI actions and CPU tables Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
66907345ff
commit
0d3a054f0d
12 files changed
+550
-46
No files matched your search
+9
-3
@@ -6,7 +6,7 @@ const express = require('express');
|
||||
const { Server } = require('socket.io');
|
||||
const config = require('./config');
|
||||
const auth = require('./auth');
|
||||
const { TableManager } = require('./tables');
|
||||
const { TableManager, MODES } = require('./tables');
|
||||
|
||||
const PUBLIC = path.join(__dirname, '..', 'public');
|
||||
// 管理者専用のファイル(public の外に置き、管理者の Cookie があるときだけ返す)
|
||||
@@ -114,7 +114,8 @@ app.post('/api/tables', (req, res) => {
|
||||
const bigBlind = b.bigBlind;
|
||||
const blindTimerEnabled = b.blindTimerEnabled === true;
|
||||
const blindIntervalMin = b.blindIntervalMin;
|
||||
const cardsEnabled = b.cardsEnabled === true;
|
||||
const mode = b.mode;
|
||||
const cpuCount = b.cpuCount;
|
||||
const hostToken = cleanToken(b.token);
|
||||
|
||||
if (tables.tables.size >= config.MAX_TABLES) return res.status(429).json({ error: 'テーブル数が上限に達しています' });
|
||||
@@ -124,6 +125,10 @@ app.post('/api/tables', (req, res) => {
|
||||
if (!intIn(smallBlind, 1, startingStack)) return res.status(400).json({ error: 'SBが不正です' });
|
||||
if (!intIn(bigBlind, smallBlind, startingStack)) return res.status(400).json({ error: 'BBはSB以上・開始スタック以下にしてください' });
|
||||
if (blindTimerEnabled && !intIn(blindIntervalMin, 1, 240)) return res.status(400).json({ error: 'インターバルは1〜240分で入力してください' });
|
||||
if (!MODES.includes(mode)) return res.status(400).json({ error: 'テーブルの種類が不正です' });
|
||||
if (mode === 'cpu' && !intIn(cpuCount, 1, config.MAX_SEATS - 1)) {
|
||||
return res.status(400).json({ error: `CPU の人数は1〜${config.MAX_SEATS - 1}人にしてください` });
|
||||
}
|
||||
if (!hostToken) return res.status(400).json({ error: 'プレイヤーIDがありません' });
|
||||
|
||||
const table = tables.create({
|
||||
@@ -133,7 +138,8 @@ app.post('/api/tables', (req, res) => {
|
||||
bigBlind,
|
||||
blindTimerEnabled,
|
||||
blindIntervalMin: blindTimerEnabled ? blindIntervalMin : 10,
|
||||
cardsEnabled,
|
||||
mode,
|
||||
cpuCount: mode === 'cpu' ? cpuCount : 0,
|
||||
hostToken,
|
||||
});
|
||||
broadcastLobby();
|
||||
|
||||
Reference in new issue
Block a user