UNPKG

@idealic/poker-engine

Version:

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

215 lines 9.68 kB
import { emptyStat } from './stats'; export const emptyMetric = { ...emptyStat, gameIds: new Set(['12345']), gameCount: 0, limpFrequency: 0, limpSuccesses: 0, limpSuccessFrequency: 0, aggressionFactor: 0, aggressionFrequency: 0, cbetFrequency: 0, cbetFoldFrequency: 0, cbetDefenseFrequency: 0, cbetSuccesses: 0, cbetSuccessFrequency: 0, threeBetFrequency: 0, threeBetFoldFrequency: 0, threeBetDefenseFrequency: 0, threeBetSuccesses: 0, threeBetSuccessFrequency: 0, fourBetFrequency: 0, fourBetFoldFrequency: 0, fourBetDefenseFrequency: 0, fourBetSuccesses: 0, fourBetSuccessFrequency: 0, stealFrequency: 0, stealFoldFrequency: 0, stealDefenseFrequency: 0, stealSuccesses: 0, stealSuccessFrequency: 0, donkBetFrequency: 0, donkBetFoldFrequency: 0, donkBetDefenseFrequency: 0, donkBetSuccesses: 0, donkBetSuccessFrequency: 0, checkRaiseFrequency: 0, checkRaiseFoldFrequency: 0, checkRaiseDefenseFrequency: 0, checkRaiseSuccesses: 0, checkRaiseSuccessFrequency: 0, openShoveFrequency: 0, openShoveFoldFrequency: 0, openShoveDefenseFrequency: 0, openShoveSuccesses: 0, openShoveSuccessFrequency: 0, wentToShowdownFrequency: 0, wonAtShowdownFrequency: 0, wonWithoutShowdownFrequency: 0, winningsAverage: 0, investmentsAverage: 0, profitAverage: 0, lossesAverage: 0, bb100: 0, returnOnInvestmentFactor: 0, stackToPotFactor: 0, decisionDurationAverage: 0, profitFactor: 0, }; function getOrCreateMetric(obj, key) { if (!obj[key]) { obj[key] = { ...emptyMetric, gameIds: new Set() }; } return obj[key]; } export function getPokerMetrics(stats, groups = ['playerId', 'street'], withTotals = true) { const result = {}; // Process each stat for (const stat of stats) { let current = result; // Process each group level for (let i = 0; i < groups.length; i++) { const group = groups[i]; const value = String(stat[group]); if (i == groups.length - 1) { updateMetric(getOrCreateMetric(current, value), stat); } // Update total for current level if (withTotals) { updateMetric(getOrCreateMetric(current, 'total'), stat); } const key = value; if (!current[key]) current[key] = {}; current = current[key]; } } // Calculate derived metrics for all levels function updateDerivedMetrics(obj) { for (const key in obj) { const value = obj[key]; if (value && typeof value === 'object') { if ('raises' in value) { aggregateMetricsProperties(value); } else { updateDerivedMetrics(value); } } } } updateDerivedMetrics(result); return result; } export function aggregateMetricsProperties(metric) { metric.limpFrequency = metric.limps / (metric.limpOpportunities || 1); metric.limpSuccessFrequency = metric.limpSuccesses / (metric.limps || 1); metric.aggressionFactor = (metric.bets + metric.raises) / (metric.calls || 1); metric.aggressionFrequency = (metric.bets + metric.raises) / (metric.bets + metric.raises + metric.calls + metric.folds || 1); metric.cbetFrequency = metric.cbet / (metric.cbetOpportunities || 1); metric.cbetSuccessFrequency = metric.cbetSuccesses / (metric.cbet || 1); metric.cbetFoldFrequency = metric.cbetFolds / (metric.cbetChallenges || 1); metric.cbetDefenseFrequency = metric.cbetDefenses / (metric.cbetChallenges || 1); metric.threeBetFrequency = metric.threeBets / (metric.threeBetOpportunities || 1); metric.threeBetSuccessFrequency = metric.threeBetSuccesses / (metric.threeBets || 1); metric.threeBetFoldFrequency = metric.threeBetFolds / (metric.threeBetChallenges || 1); metric.threeBetDefenseFrequency = metric.threeBetDefenses / (metric.threeBetChallenges || 1); metric.fourBetFrequency = metric.fourBets / (metric.fourBetOpportunities || 1); metric.fourBetSuccessFrequency = metric.fourBetSuccesses / (metric.fourBets || 1); metric.fourBetFoldFrequency = metric.fourBetFolds / (metric.fourBetChallenges || 1); metric.fourBetDefenseFrequency = metric.fourBetDefenses / (metric.fourBetChallenges || 1); metric.stealFrequency = metric.steals / (metric.stealOpportunities || 1); metric.stealSuccessFrequency = metric.stealSuccesses / (metric.steals || 1); metric.stealFoldFrequency = metric.stealFolds / (metric.stealChallenges || 1); metric.stealDefenseFrequency = metric.stealDefenses / (metric.stealChallenges || 1); metric.donkBetFrequency = metric.donkBets / (metric.donkBetOpportunities || 1); metric.donkBetSuccessFrequency = metric.donkBetSuccesses / (metric.donkBets || 1); metric.donkBetFoldFrequency = metric.donkBetFolds / (metric.donkBetChallenges || 1); metric.donkBetDefenseFrequency = metric.donkBetDefenses / (metric.donkBetChallenges || 1); metric.checkRaiseFrequency = metric.checkRaises / (metric.checkRaiseOpportunities || 1); metric.checkRaiseSuccessFrequency = metric.checkRaiseSuccesses / (metric.checkRaises || 1); metric.checkRaiseFoldFrequency = metric.checkRaiseFolds / (metric.checkRaiseChallenges || 1); metric.checkRaiseDefenseFrequency = metric.checkRaiseDefenses / (metric.checkRaiseChallenges || 1); metric.openShoveFrequency = metric.openShoves / (metric.openShoveOpportunities || 1); metric.openShoveSuccessFrequency = metric.openShoveSuccesses / (metric.openShoves || 1); metric.openShoveFoldFrequency = metric.openShoveFolds / (metric.openShoveChallenges || 1); metric.openShoveDefenseFrequency = metric.openShoveDefenses / (metric.openShoveChallenges || 1); return metric; } // Helper function to update metrics function updateMetric(metric, stat) { // Aggregate basic stats metric.raises += stat.raises; metric.bets += stat.bets; metric.calls += stat.calls; metric.checks += stat.checks; metric.folds += stat.folds; metric.allIns += stat.allIns; metric.aggressions += stat.aggressions; metric.passivities += stat.passivities; metric.decisions += stat.decisions; metric.decisionDuration += stat.decisionDuration; metric.decisionDurationAverage = metric.decisionDuration / (metric.decisions || 1); metric.limps += stat.limps; metric.limpOpportunities += stat.limpOpportunities; metric.limpSuccesses += stat.success * stat.limps; metric.threeBets += stat.threeBets; metric.threeBetOpportunities += stat.threeBetOpportunities; metric.threeBetFolds += stat.threeBetFolds; metric.threeBetChallenges += stat.threeBetChallenges; metric.threeBetSuccesses += stat.success * stat.threeBets; metric.threeBetDefenses += stat.success * stat.threeBetChallenges; metric.fourBets += stat.fourBets; metric.fourBetOpportunities += stat.fourBetOpportunities; metric.fourBetFolds += stat.fourBetFolds; metric.fourBetChallenges += stat.fourBetChallenges; metric.fourBetSuccesses += stat.success * stat.fourBets; metric.fourBetDefenses += stat.success * stat.fourBetChallenges; metric.cbet += stat.cbet; metric.cbetOpportunities += stat.cbetOpportunities; metric.cbetFolds += stat.cbetFolds; metric.cbetChallenges += stat.cbetChallenges; metric.cbetSuccesses += stat.success * stat.cbet; metric.cbetDefenses += stat.success * stat.cbetChallenges; metric.donkBets += stat.donkBets; metric.donkBetOpportunities += stat.donkBetOpportunities; metric.donkBetFolds += stat.donkBetFolds; metric.donkBetChallenges += stat.donkBetChallenges; metric.donkBetSuccesses += stat.success * stat.donkBets; metric.donkBetDefenses += stat.success * stat.donkBetChallenges; metric.checkRaises += stat.checkRaises; metric.checkRaiseOpportunities += stat.checkRaiseOpportunities; metric.checkRaiseFolds += stat.checkRaiseFolds; metric.checkRaiseChallenges += stat.checkRaiseChallenges; metric.checkRaiseSuccesses += stat.success * stat.checkRaises; metric.checkRaiseDefenses += stat.success * stat.checkRaiseChallenges; metric.steals += stat.steals; metric.stealOpportunities += stat.stealOpportunities; metric.stealFolds += stat.stealFolds; metric.stealChallenges += stat.stealChallenges; metric.stealSuccesses += stat.success * stat.steals; metric.stealDefenses += stat.success * stat.stealChallenges; metric.openShoves += stat.openShoves; metric.openShoveOpportunities += stat.openShoveOpportunities; metric.openShoveFolds += stat.openShoveFolds; metric.openShoveChallenges += stat.openShoveChallenges; metric.openShoveSuccesses += stat.success * stat.openShoves; metric.openShoveDefenses += stat.success * stat.openShoveChallenges; metric.wonAtShowdown += stat.wonAtShowdown; metric.wonWithoutShowdown += stat.wonWithoutShowdown; metric.voluntaryPutMoneyInPotTimes += stat.voluntaryPutMoneyInPotTimes; metric.balance += stat.winnings - stat.losses; metric.profits += Math.max(0, stat.winnings - stat.losses); metric.winnings += stat.winnings; metric.losses += stat.losses; metric.rake += stat.rake; metric.investments += stat.investments; metric.won += stat.won; metric.lost += stat.lost; metric.gameIds.add(stat.gameId); metric.gameCount = metric.gameIds.size; } //# sourceMappingURL=metrics.js.map