poker-extval 3.1.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/evaluator.js +90 -2
- package/package.json +1 -1
package/evaluator.js
CHANGED
|
@@ -39,10 +39,11 @@ class HandEvaluator {
|
|
|
39
39
|
* // Non-strict mode - all applicable hands marked
|
|
40
40
|
* const nonStrictEvaluator = new HandEvaluator(['As', 'Ah', 'Kd', 'Kc', 'Qs'], false);
|
|
41
41
|
*/
|
|
42
|
-
constructor(cards, strict = true) {
|
|
42
|
+
constructor(cards, strict = true, originalCards = null) {
|
|
43
43
|
this.#validateCards(cards);
|
|
44
44
|
this.cards = cards;
|
|
45
45
|
this.strict = strict;
|
|
46
|
+
this.originalCards = originalCards || (cards.length > 5 ? cards : null);
|
|
46
47
|
this.evaluation = this.#evaluateAllCombinations();
|
|
47
48
|
}
|
|
48
49
|
|
|
@@ -198,6 +199,8 @@ class HandEvaluator {
|
|
|
198
199
|
this.#isOpenEndedStraightDraw();
|
|
199
200
|
this.#isInsideStraightDraw();
|
|
200
201
|
this.#isStraightDraw();
|
|
202
|
+
this.#isComboDraw();
|
|
203
|
+
this.#isUnderPair();
|
|
201
204
|
this.#isHighCard();
|
|
202
205
|
|
|
203
206
|
// Add keyCards and kickerCards before restoring original evaluation
|
|
@@ -415,7 +418,7 @@ class HandEvaluator {
|
|
|
415
418
|
const result = {};
|
|
416
419
|
for (const combination of combinations) {
|
|
417
420
|
const key = this.#formatHandKey(combination);
|
|
418
|
-
const tempEvaluator = new HandEvaluator(combination, this.strict);
|
|
421
|
+
const tempEvaluator = new HandEvaluator(combination, this.strict, this.originalCards);
|
|
419
422
|
const evaluationKey = Object.keys(tempEvaluator.evaluation)[0];
|
|
420
423
|
result[key] = tempEvaluator.evaluation[evaluationKey];
|
|
421
424
|
}
|
|
@@ -1430,6 +1433,33 @@ class HandEvaluator {
|
|
|
1430
1433
|
return this.#getStraightDrawCards();
|
|
1431
1434
|
}
|
|
1432
1435
|
|
|
1436
|
+
/**
|
|
1437
|
+
* Gets key cards for combo draw (flush draw + straight draw).
|
|
1438
|
+
* Returns the union of flush draw and straight draw cards.
|
|
1439
|
+
*
|
|
1440
|
+
* @private
|
|
1441
|
+
* @returns {string[]} Array of cards forming the combo draw, empty array otherwise
|
|
1442
|
+
*/
|
|
1443
|
+
#getKeyCardsForComboDraw() {
|
|
1444
|
+
if (!this.evaluation.isComboDraw) return [];
|
|
1445
|
+
const flushCards = this.#getKeyCardsForFlushDraw();
|
|
1446
|
+
const straightCards = this.#getKeyCardsForStraightDraw();
|
|
1447
|
+
const allCards = [...flushCards, ...straightCards];
|
|
1448
|
+
const uniqueCards = [...new Set(allCards)];
|
|
1449
|
+
return uniqueCards.sort((a, b) => this.#getRankValue(b) - this.#getRankValue(a));
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
/**
|
|
1453
|
+
* Gets key cards for under pair (the two cards forming the pair).
|
|
1454
|
+
*
|
|
1455
|
+
* @private
|
|
1456
|
+
* @returns {string[]} Array of 2 cards if under pair, empty array otherwise
|
|
1457
|
+
*/
|
|
1458
|
+
#getKeyCardsForUnderPair() {
|
|
1459
|
+
if (!this.evaluation.isUnderPair) return [];
|
|
1460
|
+
return this.#getKeyCardsForPair();
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1433
1463
|
/**
|
|
1434
1464
|
* Gets key cards for wheel straight (5 cards forming wheel).
|
|
1435
1465
|
*
|
|
@@ -1507,6 +1537,8 @@ class HandEvaluator {
|
|
|
1507
1537
|
isStraightWheel: this.#getKeyCardsForStraightWheel(),
|
|
1508
1538
|
isOpenEndedStraightDrawWheel: this.#getKeyCardsForOpenEndedStraightDrawWheel(),
|
|
1509
1539
|
isInsideStraightDrawWheel: this.#getKeyCardsForInsideStraightDrawWheel(),
|
|
1540
|
+
isComboDraw: this.#getKeyCardsForComboDraw(),
|
|
1541
|
+
isUnderPair: this.#getKeyCardsForUnderPair(),
|
|
1510
1542
|
isHighCard: this.#getKeyCardsForHighCard()
|
|
1511
1543
|
};
|
|
1512
1544
|
}
|
|
@@ -1579,6 +1611,62 @@ class HandEvaluator {
|
|
|
1579
1611
|
|
|
1580
1612
|
// ==================== HIGH CARD ====================
|
|
1581
1613
|
|
|
1614
|
+
/**
|
|
1615
|
+
* Determines if the hand has both a flush draw and a straight draw simultaneously.
|
|
1616
|
+
* Requires both isFlushDraw (not backdoor) and isStraightDraw to be true.
|
|
1617
|
+
*
|
|
1618
|
+
* @returns {boolean} True if the hand is a combo draw, false otherwise
|
|
1619
|
+
* @example
|
|
1620
|
+
* const evaluator = new HandEvaluator(['9s', '8s', '7s', '6s', 'Kh']);
|
|
1621
|
+
* evaluator.isComboDraw(); // Returns true (flush draw + straight draw)
|
|
1622
|
+
*/
|
|
1623
|
+
#isComboDraw() {
|
|
1624
|
+
if (this.evaluation.isComboDraw !== undefined) return this.evaluation.isComboDraw;
|
|
1625
|
+
if (this.evaluation.isFlushDraw === undefined) this.#isFlushDraw();
|
|
1626
|
+
if (this.evaluation.isStraightDraw === undefined) this.#isStraightDraw();
|
|
1627
|
+
if (this.evaluation.isBackdoorFlushDraw === undefined) this.#isBackdoorFlushDraw();
|
|
1628
|
+
return this.evaluation.isComboDraw = this.evaluation.isFlushDraw &&
|
|
1629
|
+
this.evaluation.isStraightDraw &&
|
|
1630
|
+
!this.evaluation.isBackdoorFlushDraw;
|
|
1631
|
+
}
|
|
1632
|
+
|
|
1633
|
+
/**
|
|
1634
|
+
* Determines if the hand contains an under pair (pocket pair smaller than all board cards).
|
|
1635
|
+
* Only applicable when evaluating 6+ cards where the pair rank is smaller than all other cards.
|
|
1636
|
+
*
|
|
1637
|
+
* @returns {boolean} True if the hand is an under pair, false otherwise
|
|
1638
|
+
* @example
|
|
1639
|
+
* // Board: K♠ Q♠ J♠ 8♠, Hand: 77
|
|
1640
|
+
* const evaluator = new HandEvaluator(['Ks', 'Qh', 'Jd', '8c', '7c', '7h']);
|
|
1641
|
+
* evaluator.isUnderPair(); // Returns true (pair of 7s is smaller than all board cards)
|
|
1642
|
+
*/
|
|
1643
|
+
#isUnderPair() {
|
|
1644
|
+
if (this.evaluation.isUnderPair !== undefined) return this.evaluation.isUnderPair;
|
|
1645
|
+
if (this.evaluation.isPair === undefined) this.#isPair();
|
|
1646
|
+
if (!this.evaluation.isPair || !this.originalCards || this.originalCards.length < 6) {
|
|
1647
|
+
return this.evaluation.isUnderPair = false;
|
|
1648
|
+
}
|
|
1649
|
+
const pairRank = this.#getPairRank();
|
|
1650
|
+
if (!pairRank) return this.evaluation.isUnderPair = false;
|
|
1651
|
+
const otherCards = this.originalCards.filter(c => c.slice(0, -1) !== pairRank);
|
|
1652
|
+
const minOtherRank = Math.min(...otherCards.map(c => this.#getRankValue(c)));
|
|
1653
|
+
return this.evaluation.isUnderPair = this.#getRankValue(pairRank + 's') < minOtherRank;
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
/**
|
|
1657
|
+
* Gets the rank of the pair in the current hand.
|
|
1658
|
+
*
|
|
1659
|
+
* @private
|
|
1660
|
+
* @returns {string|null} The rank of the pair, or null if no pair exists
|
|
1661
|
+
*/
|
|
1662
|
+
#getPairRank() {
|
|
1663
|
+
const rankCounts = this.#getRankCounts();
|
|
1664
|
+
for (const [rank, count] of Object.entries(rankCounts)) {
|
|
1665
|
+
if (count === 2) return rank;
|
|
1666
|
+
}
|
|
1667
|
+
return null;
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1582
1670
|
/**
|
|
1583
1671
|
* Determines if the hand is high card only (no pairs, two pair, three of a kind, full house,
|
|
1584
1672
|
* four of a kind, flush, or straight).
|