UNPKG

@idealic/poker-engine

Version:

Poker game engine and hand evaluator

314 lines (275 loc) 8.54 kB
import { describe, expect, it } from 'vitest'; import { compareHands } from '../../game/showdown'; describe('compareHands', () => { it('compares high card hands correctly', () => { // 7 distinct ranks, no pairs, no straights, no flushes // Higher card wins expect( compareHands( // Highest card = King ['Kh', 'Qd', '9s', '7c', '5h', '3d', '2s'], // Highest card = Queen ['Qh', 'Jd', '9s', '7c', '5h', '3d', '2s'] ) ).toBeGreaterThan(0); expect( compareHands( // Reverse order ['Qh', 'Jd', '9s', '7c', '5h', '3d', '2s'], ['Kh', 'Qd', '9s', '7c', '5h', '3d', '2s'] ) ).toBeLessThan(0); // Same high card, second-highest card decides expect( compareHands( // Highest cards = K, Q ['Kh', 'Qd', '9s', '7c', '5h', '3d', '2s'], // Highest cards = K, J (lower second card) ['Kh', 'Jd', '9s', '7c', '5h', '3d', '2s'] ) ).toBeGreaterThan(0); expect( compareHands( // Reverse ['Kh', 'Jd', '9s', '7c', '5h', '3d', '2s'], ['Kh', 'Qd', '9s', '7c', '5h', '3d', '2s'] ) ).toBeLessThan(0); // Exact same cards = tie expect( compareHands( ['Kh', 'Qd', '9s', '7c', '5h', '3d', '2s'], ['Kh', 'Qd', '9s', '7c', '5h', '3d', '2s'] ) ).toBe(0); }); it('compares pair hands correctly', () => { // Make sure we only have exactly one pair in each hand // Higher pair wins expect( compareHands( // Pair of 8s ['8h', '8d', 'Qh', 'Js', '9c', '5d', '2s'], // Pair of 7s ['7h', '7d', 'Qh', 'Js', '9c', '5d', '2s'] ) ).toBeGreaterThan(0); expect( compareHands( // Reverse ['7h', '7d', 'Qh', 'Js', '9c', '5d', '2s'], ['8h', '8d', 'Qh', 'Js', '9c', '5d', '2s'] ) ).toBeLessThan(0); // Same pair, kicker decides expect( compareHands( // Pair of 8s, highest kicker = Queen ['8h', '8d', 'Qh', 'Js', '9c', '6d', '2s'], // Pair of 8s, highest kicker = Jack ['8h', '8d', 'Jh', 'Ts', '9c', '6d', '2s'] ) ).toBeGreaterThan(0); // Same pair and same kickers = tie expect( compareHands( // Pair of 8s, exact same other cards ['8h', '8d', 'Qh', 'Js', '9c', '6d', '2s'], ['8h', '8d', 'Qh', 'Js', '9c', '6d', '2s'] ) ).toBe(0); }); it('compares two pair hands correctly', () => { // Exactly two distinct pairs per hand // Higher top pair wins expect( compareHands( // Two pairs: 8s and 7s ['8h', '8d', '7h', '7d', 'Qc', 'Js', '2s'], // Two pairs: 7s and 6s ['7h', '7d', '6h', '6d', 'Qc', 'Js', '2s'] ) ).toBeGreaterThan(0); // Same top pair, higher second pair wins expect( compareHands( // Top pair of 8s, second pair of 7s ['8h', '8d', '7h', '7d', 'Qc', 'Js', '2s'], // Top pair of 8s, second pair of 6s ['8h', '8d', '6h', '6d', 'Qc', 'Js', '2s'] ) ).toBeGreaterThan(0); // Same two pairs, kicker decides expect( compareHands( // 8s and 7s, kicker = Q ['8h', '8d', '7h', '7d', 'Qc', 'Js', '2s'], // 8s and 7s, kicker = J ['8h', '8d', '7h', '7d', 'Jc', 'Ts', '2s'] ) ).toBeGreaterThan(0); // Same two pairs and same kicker = tie expect( compareHands( ['8h', '8d', '7h', '7d', 'Qc', 'Js', '2s'], ['8h', '8d', '7h', '7d', 'Qc', 'Js', '2s'] ) ).toBe(0); }); it('compares three of a kind hands correctly', () => { // Exactly three of a kind, ensure no extra pairs // Higher three of a kind wins expect( compareHands( // Three 8s ['8h', '8d', '8c', 'Qh', 'Js', '5d', '2s'], // Three 7s ['7h', '7d', '7c', 'Qh', 'Js', '5d', '2s'] ) ).toBeGreaterThan(0); // Same three of a kind, higher kicker wins expect( compareHands( // Three 8s, top kicker Q ['8h', '8d', '8c', 'Qh', 'Js', '5d', '2s'], // Three 8s, top kicker J ['8h', '8d', '8c', 'Jh', 'Ts', '5d', '2s'] ) ).toBeGreaterThan(0); // Same three of a kind and same kickers = tie expect( compareHands( ['8h', '8d', '8c', 'Qh', 'Js', '5d', '2s'], ['8h', '8d', '8c', 'Qh', 'Js', '5d', '2s'] ) ).toBe(0); }); it('compares straight and flush hands correctly', () => { // Make sure the "straight" sets are actual straights, and flushes are actual flushes // Straight beats high card expect( compareHands( // Straight: 5-6-7-8-9 ['9h', '8d', '7s', '6h', '5c', '2d', '3s'], // High card (no pair, no straight) ['Kh', 'Jd', '9s', '7c', '5h', '3d', '2s'] ) ).toBeGreaterThan(0); // Higher straight wins (9-high straight vs 8-high straight) expect( compareHands( // 5-6-7-8-9 ['9h', '8d', '7s', '6h', '5c', '2d', '3s'], // 4-5-6-7-8 ['8h', '7d', '6s', '5h', '4c', '2d', '3s'] ) ).toBeGreaterThan(0); // Flush beats straight expect( compareHands( // Flush: 5 hearts (9h, 8h, 7h, 6h, 4h) ['9h', '8h', '7h', '6h', '4h', '2d', '3s'], // Straight but not a flush ['9s', '8d', '7c', '6h', '5c', '2d', '3s'] ) ).toBeGreaterThan(0); // Higher flush wins (9-high flush vs 8-high flush) expect( compareHands( // 9-high flush ['9h', '8h', '7h', '6h', '4h', '2d', '3s'], // 8-high flush ['8h', '7h', '6h', '5h', '3h', '2d', '3s'] ) ).toBeGreaterThan(0); }); it('compares full house and four of a kind hands correctly', () => { // Full house vs flush, etc. // Full house beats flush expect( compareHands( // Full house: 8-8-8 + 7-7 ['8h', '8d', '8c', '7h', '7d', '2s', '3c'], // Flush: 5 hearts ['9h', '8h', '7h', '6h', '4h', '2d', '3s'] ) ).toBeGreaterThan(0); // Higher three in full house wins (8s vs 7s) expect( compareHands( ['8h', '8d', '8c', '7h', '7d', '2s', '3c'], ['7h', '7d', '7c', '8h', '8d', '2s', '3c'] ) ).toBeGreaterThan(0); // Same three, higher pair in full house expect( compareHands( // 8-8-8 + 7-7 ['8h', '8d', '8c', '7h', '7d', '2s', '3c'], // 8-8-8 + 6-6 ['8h', '8d', '8c', '6h', '6d', '2s', '3c'] ) ).toBeGreaterThan(0); // Four of a kind beats full house expect( compareHands( // Four 8s ['8h', '8d', '8c', '8s', '7d', '2c', '3h'], // Full house (7-7-7 + 8-8) ['7h', '7d', '7c', '8h', '8d', '2s', '3c'] ) ).toBeGreaterThan(0); // Higher four of a kind wins (8s vs 7s) expect( compareHands( ['8h', '8d', '8c', '8s', '2d', '3c', '4h'], ['7h', '7d', '7c', '7s', '8d', '2s', '3c'] ) ).toBeGreaterThan(0); }); it('compares straight flush and royal flush hands correctly', () => { // Straight flush, royal flush, etc. // Straight flush beats four of a kind expect( compareHands( // Royal flush in hearts (A-K-Q-J-10 all hearts) ['Ah', 'Kh', 'Qh', 'Jh', 'Th', '2h', '3h'], // Four of a kind ['8s', '8d', '8c', '8h', '7d', '2c', '3s'] ) ).toBeGreaterThan(0); // Higher straight flush wins (A-high vs K-high) expect( compareHands( // A-K-Q-J-10 hearts ['Ah', 'Kh', 'Qh', 'Jh', 'Th', '2h', '3h'], // K-Q-J-10-9 hearts ['Kh', 'Qh', 'Jh', 'Th', '9h', '2h', '3h'] ) ).toBeGreaterThan(0); // Royal flush ties with royal flush (different suits) expect( compareHands( ['Ah', 'Kh', 'Qh', 'Jh', 'Th', '2h', '3h'], ['Ad', 'Kd', 'Qd', 'Jd', 'Td', '2d', '3d'] ) ).toBe(0); }); it('handles edge cases correctly', () => { // Ace can be low in a straight (A-2-3-4-5) // A-2-3-4-5 (Ace is low) vs 2-3-4-5-6 (higher straight) expect( compareHands( ['Ah', '2d', '3s', '4h', '5c', '7d', '8s'], // Actually a 5-high straight ['6h', '5d', '4s', '3h', '2c', '7d', '8s'] // 6-high straight ) ).toBeLessThan(0); // Identical 7-card hands expect( compareHands( ['8h', '7d', '6s', '5h', '4c', '2d', '3s'], ['8h', '7d', '6s', '5h', '4c', '2d', '3s'] ) ).toBe(0); }); });