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