UNPKG

@idealic/poker-engine

Version:

Professional poker game engine and hand evaluator with built-in iterator utilities

86 lines 3.43 kB
/** * Game analytics extension demonstrating module augmentation pattern. * This file shows how to extend the Game namespace with additional functionality. */ /** * Calculate the approximate win probability for a player based on game state. * This is a simplified implementation for demonstration purposes. * * @param game - Current game state * @param playerId - Name of the player to calculate win probability for * @returns Win probability as a decimal between 0 and 1 */ export function getWinProbability(game, playerId) { // Find the player in the game const player = game.players.find(p => p.name === playerId); if (!player || player.hasFolded) { return 0; } // Simple heuristic based on relative stack size and pot odds const totalActiveStacks = game.players .filter(p => !p.hasFolded && !p.isInactive) .reduce((sum, p) => sum + p.stack, 0); if (totalActiveStacks === 0) return 0.5; // Neutral probability if no stacks const playerStackRatio = player.stack / totalActiveStacks; const potOdds = game.bet > 0 ? game.bet / (game.pot + game.bet) : 0.5; // Combine stack strength with pot odds for a rough win probability return Math.min(0.95, Math.max(0.05, (playerStackRatio * 0.7) + (potOdds * 0.3))); } /** * Calculate the current pot odds for the next player to act. * * @param game - Current game state * @returns Pot odds as a decimal (amount to call / total pot after call) */ export function getPotOdds(game) { if (game.bet === 0) { return 0; // No bet to call } const totalPotAfterCall = game.pot + game.bet; return game.bet / totalPotAfterCall; } /** * Calculate expected value for a call based on win probability and pot odds. * * @param game - Current game state * @param playerId - Name of the player considering the call * @returns Expected value as a positive or negative number */ export function getCallExpectedValue(game, playerId) { const winProbability = getWinProbability(game, playerId); const potOdds = getPotOdds(game); if (game.bet === 0) return 0; // No call needed const potSizeAfterCall = game.pot + game.bet; const expectedWin = winProbability * potSizeAfterCall; const costToCall = game.bet; return expectedWin - costToCall; } /** * Get game phase analysis including aggression factors and betting patterns. * * @param game - Current game state * @returns Analysis object with various game metrics */ export function getGameAnalysis(game) { const activePlayers = game.players.filter(p => !p.hasFolded && !p.isInactive); const totalActiveStacks = activePlayers.reduce((sum, p) => sum + p.stack, 0); const averageStack = activePlayers.length > 0 ? totalActiveStacks / activePlayers.length : 0; // Simple aggression factor based on pot size relative to blinds const bigBlind = game.minBet; const aggressionFactor = game.pot / (bigBlind * 2); // Pot size in big blinds const potToStackRatio = averageStack > 0 ? game.pot / averageStack : 0; return { phase: game.street, aggressionFactor, averageStack, potToStackRatio, activePlayers: activePlayers.length }; } Game.getWinProbability = getWinProbability; Game.getPotOdds = getPotOdds; Game.getCallExpectedValue = getCallExpectedValue; Game.getGameAnalysis = getGameAnalysis; //# sourceMappingURL=analytics.js.map