'use strict'; // CPU プレイヤーの思考。性格ごとに別の公開ライブラリを使った思考を持たせる(どれを使っているかは画面に出さない)。 // montecarlo: バランス型。@pokertools/evaluator でモンテカルロ法の勝率を見積もる // calculator: 計算型。poker-calculations の decideAction(勝率・ポットオッズ・期待値) // range : 理論型(タイト)。poker-utils のハンドの順位とレンジに対する勝率・ブラフの理論値 // madehand : 直感型(ルーズ)。pokersolver で、いまできている役だけを見て打つ // どの思考も相手の手札は見ない(自分の手札と場札、公開されているベット状況だけを使う)。 const crypto = require('crypto'); const { legalize } = require('./bots/common'); const montecarlo = require('./bots/montecarlo'); const BRAINS = { montecarlo, calculator: require('./bots/calculator'), range: require('./bots/range'), madehand: require('./bots/madehand'), }; // この環境で使える思考(ネイティブアドオンが読み込めないなどで使えないものを除く) function availableBrains() { return Object.keys(BRAINS).filter((name) => !BRAINS[name].available || BRAINS[name].available()); } const randomIndex = (rng, n) => Math.floor(rng() * n); // CPU ごとの性格。brain を省くとランダムに選ぶ function randomStyle(rng = Math.random, brain) { const names = availableBrains(); const name = names.includes(brain) ? brain : names[randomIndex(rng, names.length)]; return { brain: name, ...BRAINS[name].randomStyle(rng) }; } // n 人分の性格。同じテーブルになるべく違う思考が並ぶようにする function makeStyles(n, rng = () => crypto.randomInt(2 ** 32) / 2 ** 32) { const names = availableBrains(); for (let i = names.length - 1; i > 0; i--) { const j = randomIndex(rng, i + 1); [names[i], names[j]] = [names[j], names[i]]; } return Array.from({ length: n }, (_, k) => randomStyle(rng, names[k % names.length])); } // 手番の CPU の行動を決める。{ type, amount } を返す(hand.act にそのまま受け付けられる形に直してある) // 思考がエラーになったり何も返さなかったりしたら、バランス型で決め直す function decide(hand, seat, { style = montecarlo.DEFAULT_STYLE, rng = Math.random, iterations = 500 } = {}) { if (!hand.options(seat)) return null; const brain = BRAINS[style.brain] || montecarlo; let d = null; try { d = brain.decide(hand, seat, { style, rng, iterations }); } catch { d = null; } if (!d && brain !== montecarlo) { try { d = montecarlo.decide(hand, seat, { rng, iterations }); } catch { d = null; } } return legalize(hand, seat, d); } module.exports = { decide, randomStyle, makeStyles, availableBrains, equity: montecarlo.equity, BRAINS };