UNPKG

@idealic/poker-engine

Version:

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

111 lines 3.3 kB
import * as tables from '../tables/index'; import { ranks, suits } from '../types'; const rank = Object.fromEntries(ranks.map((r, i) => [r, i])); const reverseRank = Object.fromEntries(ranks.map((r, i) => [`${i}`, r])); const suit = Object.fromEntries(suits.map((r, i) => [r, i])); const reverseSuit = Object.fromEntries(suits.map((r, i) => [`${i}`, r])); export const numberOfCards = ranks.length * suits.length; export const cardToId = (card) => rank[card[0]] * 4 + suit[card[1]]; export const idToCard = (id) => { if (id < 0 || id > numberOfCards - 1) { throw new Error(`Id(${id}) is not a card id`); } return `${reverseRank[`${Math.floor(id / 4)}`]}${reverseSuit[`${id % 4}`]}`; }; export const parse = (str) => { if (str.length === 2) { const [r, s] = str.split('').map(c => c.toUpperCase()); console.log('r,s', r, s); if (rank[r] !== undefined && suit[s] !== undefined) { return `${r}${s}`; } } console.log('str', str); throw new Error('Unexpected Card input'); }; export const equalsCard = (a, b) => a == b; export const quinaryHash = (q, numCards) => { const length = q.length; let sum = 0; let k = numCards; for (const [i, v] of q.entries()) { sum += tables.dp[v][length - i - 1][k]; k -= v; if (k <= 0) { break; } } return sum; }; export const stringify = (card) => `${card}`; export const getRankCategory = (rank) => { // 1277 high card if (rank > 6185) { return 'High Card'; } // 2860 one pair if (rank > 3325) { return 'One Pair'; } // 858 two pair if (rank > 2467) { return 'Two Pair'; } // 858 three-kind if (rank > 1609) { return 'Three of a Kind'; } // 10 straights if (rank > 1599) { return 'Straight'; } // 1277 flushes if (rank > 322) { return 'Flush'; } // 156 full house if (rank > 166) { return 'Full House'; } // 156 four-kind if (rank > 10) { return 'Four of a Kind'; } // 10 straight-flushes return 'Straight Flush'; }; const minCards = 5; const maxCards = 7; const noFlushes = { 5: tables.noFlush5, 6: tables.noFlush6, 7: tables.noFlush7, }; export const calculateHandCodesStrength = (ids) => { const size = ids.length; const noFlush = noFlushes[size]; if (size < minCards || size > maxCards || !noFlush) { throw new Error(`The number of cards must be between ${minCards} and ${maxCards}.`); } let suitHash = 0; for (const card of ids) { suitHash += tables.suitbitById[card]; } const flushSuit = tables.suits[suitHash]; if (flushSuit) { const suitBinary = [0, 0, 0, 0]; for (const card of ids) { suitBinary[card & 0x03] |= tables.binariesById[card]; } return tables.flush[suitBinary[flushSuit - 1]]; } const quinary = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; for (const card of ids) { quinary[card >> 2]++; } return noFlush[quinaryHash(quinary, size)]; }; export const calculateHandStrength = (cards) => { return calculateHandCodesStrength(cards.map(c => cardToId(c))); }; //# sourceMappingURL=hand-strength.js.map