'use strict'; // CPU の思考で共通に使う道具。どの思考も相手の手札は見ない(自分の手札と場札、公開されているベット状況だけを使う) // 手番の状況。手番でなければ null function situation(hand, seat) { const o = hand.options(seat); if (!o) return null; const p = hand.players.get(seat); const pot = hand.potTotal; return { o, p, cards: p.cards, board: hand.board, stack: hand.seats[seat].stack, bb: hand.bb, preflop: hand.board.length === 0, opponents: hand.live().length - 1, pot, potOdds: o.toCall / (pot + o.toCall), raises: hand.raises || 0, }; } const CHECK = { type: 'check' }; const CALL = { type: 'call' }; const FOLD = { type: 'fold' }; // チェックできればチェック、できなければフォールド const passive = (o) => (o.canCheck ? CHECK : FOLD); // チェックできればチェック、できなければコール const keepGoing = (o) => (o.canCheck ? CHECK : CALL); const allIn = (o) => ({ type: 'raise', amount: o.maxRaiseTo }); // 合計 amount までのレイズ。最低額〜オールインに収め、SB 単位に丸め、残りがわずかになるならオールイン function raiseToAmount(hand, seat, amount) { const o = hand.options(seat); const p = hand.players.get(seat); const unit = Math.max(1, hand.sb); let to = Math.round(amount / unit) * unit; to = Math.min(o.maxRaiseTo, Math.max(o.minRaiseTo, to)); if (to - p.bet >= hand.seats[seat].stack * 0.7) to = o.maxRaiseTo; return { type: 'raise', amount: to }; } // ポット(コールした後)の fraction 倍のレイズ function raisePot(hand, seat, fraction) { const o = hand.options(seat); return raiseToAmount(hand, seat, hand.currentBet + fraction * (hand.potTotal + o.toCall)); } // 思考の結果を、その場で必ず受け付けられるアクションに直す function legalize(hand, seat, d) { const o = hand.options(seat); if (!o) return null; const type = d && d.type; if (type === 'raise' && o.canRaise && Number.isFinite(d.amount)) { const amount = Math.min(o.maxRaiseTo, Math.max(o.minRaiseTo, Math.round(d.amount))); return { type: 'raise', amount }; } if (type === 'raise' || type === 'call') return keepGoing(o); if (type === 'check') return passive(o); // ただで見られるのに降りることはしない return passive(o); } // 0 以上 2^31 未満の整数のシード(ネイティブのシミュレーション用) const seedFrom = (rng) => Math.floor(rng() * 2147483647); // 範囲内の一様乱数 const between = (rng, min, max) => min + rng() * (max - min); module.exports = { situation, CHECK, CALL, FOLD, passive, keepGoing, allIn, raiseToAmount, raisePot, legalize, seedFrom, between, };