@idealic/poker-engine
Version:
Professional poker game engine and hand evaluator with built-in iterator utilities
215 lines • 9.68 kB
JavaScript
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