@pairjacks/poker-cards
TypeScript icon, indicating that this package has built-in type declarations

0.5.0 • Public • Published

@pairjacks/poker-cards

CI status

Base Constants & Types

enum Face {
	Two = "Two",
	Three = "Three",
	Four = "Four",
	Five = "Five",
	Six = "Six",
	Seven = "Seven",
	Eight = "Eight",
	Nine = "Nine",
	Ten = "Ten",
	Jack = "Jack",
	Queen = "Queen",
	King = "King",
	Ace = "Ace",
}

enum Suit {
	Diamonds = "Diamonds",
	Clubs = "Clubs",
	Hearts = "Heart",
	Spades = "Spades",
}

type Card = readonly [Face, Suit];

// Convenience type expressing a readonly array of readonly cards
type Cards = readonly Card[];

// Represents a collection of cards that can be used to create a 5 card hand
type HandCandidate = {
	readonly pocketCards: Cards;
	readonly communityCards: Cards;
};

// A hand derived from a HandCandidate
type Hand = {
	// Straight, TwoPair etc
	readonly rank: HandRank;
	// Cards included in the ranking combination
	readonly rankCards: Cards;
	// Cards included in the hand but not in the ranking combination
	readonly kickerCards: Cards;
};

Api

Cards

isSameCard

Determines if two cards are identical

import { isSameCard, Face, Suit } from "@pairjacks/poker-cards";

isSameCard([Face.Two, Suit.Clubs], [Face.Two, Suit.Clubs]); // true
isSameCard([Face.Three, Suit.Clubs], [Face.Two, Suit.Clubs]); // false

Deck

createDeck

Creates a 52 card deck without Jokers. Accepts an optional parameter object

  • { order: "ndo" } new deck order (default value)
  • { order: "value" } sorted by suite (Diamonds to Spades) and face (Two to Ace).
import { createDeck } from "@pairjacks/poker-cards";

createDeck();
// [[Ace, Hearts], [Two, Hearts] ... [Two, Spades], [Ace, Spades]]

createDeck({ order: "ndo" });
// [[Ace, Hearts], [Two, Hearts] ... [Two, Spades], [Ace, Spades]] (default)

createDeck({ order: "value" });
// [[Ace, Diamonds], [Two, Diamonds] ... [Queen, Spades], [King, Spades]]

drawCardsFromDeck

Draws n cards from deck without mutating the deck. Returned card order tries to represent drawing cards one-by-one, as opposed to cutting off a chunk of cards from the top of the deck, where index 0 represents the top of the deck. e.g. when drawing 3:

initial deck: [a, b, c, d]
draw first card: [b, c, d] => [a]
then second: [c, d] => [b, a]
then third: [b] => [c, b, a]
import { drawCardsFromDeck } from "@pairjacks/poker-cards";

drawCardsFromDeck(deck, 4);
// { cards: [...4 cards], deck: [...deck without 4 cards] }

Shuffling a deck

Shuffle functions are async to allow for async random number generators.

shuffleDeckNaive

A default shuffle deck function is provided which uses Math.random to drive a fisher-yates shuffle.

import { shuffleDeckNaive } from "@pairjacks/poker-cards";

const shuffled = await shuffleDeckNaive(deck);

createDeckShuffler

You might want to use a more robust random int generator, like that provided by (random-number-csprng)[https://www.npmjs.com/package/random-number-csprng] which asynchronously returns a crypto-secure random int.

import {
	createDeckShuffler,
	createFisherYatesStackShuffle,
} from "@pairjacks/poker-cards";
import randomNumberCsprng from "random-number-csprng";

// (min: number, max: number) => Promise<number>;
const randomInt = randomNumberCsprng;

// <T>(arr: T[]) => Promise<T[]>);
const shuffleFunction = createFisherYatesStackShuffle(randomInt);
const shuffle = createDeckShuffler(shuffleFunction);
const shuffled = await shuffle(deck);

As another example, the following produces shuffleDeckNaive described above

import {
	createDeckShuffler,
	createFisherYatesStackShuffle,
	randomIntNaive,
} from "@pairjacks/poker-cards";

const shuffleDeckNaive = createDeckShuffler(
	createFisherYatesStackShuffle(randomIntNaive),
);
const shuffled = await shuffle(deck);

Hand

extractHand

Extracts the highest possible hand from a candidate hand

import { extractHand } from "@pairjacks/poker-cards";

const hand = extractHand({
	pocketCards: [
		[Face.Two, Suit.Clubs],
		[Face.Six, Suit.Clubs],
	],
	communityCards: [
		[Face.Four, Suit.Clubs],
		[Face.Three, Suit.Clubs],
		[Face.Eight, Suit.Spades],
		[Face.Five, Suit.Clubs],
		[Face.Six, Suit.Spades],
	],
});
/*
hand: Hand = {
  rank: HandRank.StraightFlush,
  rankCards: [
    [Face.Six, Suit.Clubs],
    [Face.Five, Suit.Clubs],
    [Face.Four, Suit.Clubs],
    [Face.Three, Suit.Clubs],
    [Face.Two, Suit.Clubs],
  ],
  kickerCards: [],
}
*/

findHighestHands

Returns an array of highest hands from a list of candidates. Multiple entries indicates a draw.

import { findHighestHands } from '@pairjacks/poker-cards';

const twoPair: HandCandidate = {...}
const straightTenHighDiamonds: HandCandidate = {...}
const straightTenHighSpades: HandCandidate = {...}

const winners = findHighestHands([twoPair, straightTenHighDiamonds, straightTenHighSpades]);
/*
winners: HandComparisonResult[] = [
  {
    candidate: straightTenHighDiamonds,
    candidateIndex: 1,
    hand: Hand
  },
  {
    candidate: straightTenHighSpades,
    candidateIndex: 2,
    hand: Hand
  },
]
*/

describePocketCards

Describes pocket cards in words

import { describePocketCards, Face, Suit } from "@pairjacks/poker-cards";

describePocketCards([
	[Face.Ace, Suit.Hearts],
	[Face.Ace, Suit.Spades],
]);
// Pocket Aces

describeHand

Describes a hand in words

import { extractHand, describeHand, Face, Suit } from '@pairjacks/poker-cards';

describeHand(extractHand({
  pocketCards: [
    [Face.Five, Suit.Hearts],
    [Face.Three, Suit.Diamonds],
  ],
  communityCards: [
    [Face.Two, Suit.Hearts],
    [Face.Five, Suit.Diamonds],
    [Face.Two, Suit.Diamonds],
    [Face.Seven, Suit.Clubs],
  ],
});
// { rank: 'Two pair, Fives over Twos', kickers: 'Seven kicker' }

Readme

Keywords

none

Package Sidebar

Install

npm i @pairjacks/poker-cards

Weekly Downloads

2

Version

0.5.0

License

MIT

Unpacked Size

138 kB

Total Files

8

Last publish

Collaborators

  • kavsingh
  • desmondmcnamee