UNPKG

@alexjamesmalcolm/poker-odds-machine

Version:
204 lines 8.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Calculator = void 0; const types_1 = require("./types"); const util_1 = require("./util"); const evaluate_1 = require("./evaluate"); class Player { constructor(name) { this.dealt = new types_1.CardGroup(); this.name = name; } evaluate(board) { const totalCardGroup = new types_1.CardGroup(this.dealt.cards.concat(board.cards)); this.bestHand = evaluate_1.evaluate(totalCardGroup); return this.bestHand; } compare(p) { if (!p.bestHand || !this.bestHand) return 0; if (p.bestHand.handRank === this.bestHand.handRank) { for (let i = 0; i < this.bestHand.hand.cards.length; i++) { if (p.bestHand.hand.cards[i].rank !== this.bestHand.hand.cards[i].rank) { return p.bestHand.hand.cards[i].rank > this.bestHand.hand.cards[i].rank ? 1 : -1; } } return 0; } return p.bestHand.handRank > this.bestHand.handRank ? 1 : -1; } } class Game { constructor(input) { this.players = []; this.input = input; this.deck = new types_1.Deck(this.input.numDecks); this.deck.shuffle(); this.board = new types_1.CardGroup(this.input.board); this.board.cards.forEach((c) => this.deck.removeCard(c)); this.dealKnownCards(); this.buildRestOfBoard(); this.dealRestOfCards(); } static getNpcName(i) { return `NPC ${i}`; } play() { for (const p of this.players) { p.evaluate(this.board); } // shuffle player order. allows bias when compare() return 0 as ties util_1.shuffle(this.players); // compare hands this.players.sort((a, b) => a.compare(b)); const winners = [this.players[0]]; for (let i = 1; i < this.players.length; i++) { const res = this.players[i - 1].compare(this.players[i]); if (res === 0) { winners.push(this.players[i]); } else { break; } } return winners; } buildRestOfBoard() { const currentBoardSize = this.board.cards.length; for (let i = 0; i < this.input.boardSize - currentBoardSize; i++) { this.board.addCards(this.deck.pop()); } } dealKnownCards() { for (const s of this.input.hands) { const dealtCards = new types_1.CardGroup(s); dealtCards.cards.forEach((c) => this.deck.removeCard(c)); const p = new Player(dealtCards.toString()); p.dealt.addCardGroup(dealtCards); this.players.push(p); } } dealRestOfCards() { // complete any incomplete players for (const p of this.players) { for (let i = 0; i < this.input.handSize - p.dealt.cards.length; i++) { p.dealt.addCards(this.deck.pop()); } } for (let i = 0; i < this.input.numPlayers - this.input.hands.length; i++) { const dealtCards = new types_1.CardGroup(); for (let j = 0; j < this.input.handSize; j++) { dealtCards.addCards(this.deck.pop()); } const p = new Player(Game.getNpcName(i + 1)); p.dealt.addCardGroup(dealtCards); this.players.push(p); } } } class Calculator { constructor(input) { this.stats = {}; util_1.validateInput(input); this.input = util_1.cleanInput(input); for (const e of this.input.hands) { this.setupStatsObj(e); } for (let i = 0; i < this.input.numPlayers - this.input.hands.length; i++) { this.setupStatsObj(Game.getNpcName(i + 1)); } } simulate() { for (let i = 0; i < this.input.iterations; i++) { const g = new Game(this.input); const winners = g.play(); this.addToCount(winners); } this.calculateStats(); return this.stats; } getStatsOfPlayer(player) { if (player in this.stats) { return this.stats[player]; } return { tieCount: 0, winCount: 0, }; } addToCount(winners) { var _a, _b; const isTie = winners.length > 1; for (const winner of winners) { const statsOfWinner = this.getStatsOfPlayer(winner.name); if (isTie) { statsOfWinner.tieCount++; if (this.input.returnTieHandStats && ((_a = winner.bestHand) === null || _a === void 0 ? void 0 : _a.handRank) !== undefined) { const statsOfWinnerWithTieHandStats = types_1.makeStatsTieHandStatsIfItIsNotAlready(statsOfWinner); statsOfWinnerWithTieHandStats.tieHandStats[types_1.HandRanks[winner.bestHand.handRank]].count++; } } else { statsOfWinner.winCount++; if (this.input.returnHandStats && ((_b = winner.bestHand) === null || _b === void 0 ? void 0 : _b.handRank) !== undefined) { const statsOfWinnerWithHandStats = types_1.makeStatsHandStatsIfItIsNotAlready(statsOfWinner); statsOfWinnerWithHandStats.handStats[types_1.HandRanks[winner.bestHand.handRank]].count++; } } } } calculateStats() { for (const name in this.stats) { const statsOfPlayer = this.stats[name]; // winner percent statsOfPlayer.winPercent = this.calculatePercent(statsOfPlayer.winCount); statsOfPlayer.tiePercent = this.calculatePercent(statsOfPlayer.tieCount); // hand percent if (this.input.returnHandStats) { const statsOfWinnerWithHandStats = types_1.makeStatsHandStatsIfItIsNotAlready(statsOfPlayer); for (const rank in statsOfWinnerWithHandStats.handStats) { statsOfWinnerWithHandStats.handStats[rank].percent = this.calculatePercent(statsOfWinnerWithHandStats.handStats[rank].count); } } if (this.input.returnTieHandStats) { const statsOfWinnerWithTieHandStats = types_1.makeStatsTieHandStatsIfItIsNotAlready(statsOfPlayer); for (const rank in statsOfWinnerWithTieHandStats.tieHandStats) { statsOfWinnerWithTieHandStats.tieHandStats[rank].percent = this.calculatePercent(statsOfWinnerWithTieHandStats.tieHandStats[rank] .count); } } } } setupStatsObj(name) { this.stats[name] = { winCount: 0, tieCount: 0 }; if (this.input.returnHandStats) types_1.makeStatsHandStatsIfItIsNotAlready(this.stats[name]); if (this.input.returnTieHandStats) types_1.makeStatsTieHandStatsIfItIsNotAlready(this.stats[name]); for (const r in types_1.HandRanks) { if (typeof types_1.HandRanks[r] !== 'number') continue; if (this.input.returnHandStats) { const statsWithHandStats = types_1.makeStatsHandStatsIfItIsNotAlready(this.stats[name]); statsWithHandStats.handStats[r] = { count: 0 }; } if (this.input.returnTieHandStats) { const statsWithTieHandStats = types_1.makeStatsTieHandStatsIfItIsNotAlready(this.stats[name]); statsWithTieHandStats.tieHandStats[r] = { count: 0 }; } } } calculatePercent(count) { return +((count / this.input.iterations) * 100).toFixed(4); } } exports.Calculator = Calculator; //# sourceMappingURL=Game.js.map