Deck and Card Management
Relevant source files
The following files were used as context for generating this wiki page:
The Deck and Card Management system is a fundamental module responsible for the creation, shuffling, distribution, and UI representation of playing cards. It ensures a fair and consistent source of cards for all game logic. The system is primarily composed of the DeckManager singleton, which handles the state of the deck, and the Card React component, which handles the visual rendering of individual cards.
This system is consumed by the Poker Engine to drive the game forward by dealing cards to players and the community board at appropriate phases. The visual representation is used across various UI components, including the main game table and informational dashboards.
Core Data Structures
The foundation of the card system is built on a few key TypeScript types that define the properties of a standard playing card.
Sources: types/poker.ts:1-8
| Type | Definition | Description |
|---|---|---|
Suit | "hearts" | "diamonds" | "clubs" | "spades" | Defines the four possible suits for a card. |
Rank | "2" | ... | "K" | "A" | Defines the thirteen possible ranks for a card. |
Card | interface { suit: Suit; rank: Rank; } | Represents a single playing card with a suit and rank. |
DeckManager
The DeckManager is a singleton class that manages the state of the 52-card deck throughout the game. It is responsible for initializing, shuffling, drawing, and discarding cards. Using a singleton pattern ensures that there is only one instance of the deck, preventing inconsistencies in the game state.
Sources: lib/deck-manager.ts
Architecture
The DeckManager class maintains a private deck array and a discardPile array. When the deck runs out of cards, it automatically reshuffles the discard pile back into the main deck to ensure cards are always available.
The following class diagram illustrates the structure of the DeckManager singleton.
Sources: lib/deck-manager.ts:3-13
Key Methods
| Method | Description |
|---|---|
getInstance() | Static method to access the singleton instance of the DeckManager. |
reset() | Re-initializes the deck with 52 cards, clears the discard pile, and shuffles the deck. This is called at the start of each new hand. |
shuffle() | Shuffles the deck array using the Fisher-Yates algorithm. |
draw(count) | Removes and returns a specified number of cards from the top of the deck. |
drawOne() | A convenience method to draw a single card. Returns null if no cards are available after attempting a reshuffle. |
discard(cards) | Adds an array of cards to the discardPile. Used for burn cards. |
getRemainingCards() | Returns the number of cards currently in the deck. |
Sources: lib/deck-manager.ts:10-70
Hand Initialization Flow
At the start of every hand, the poker-engine calls deckManager.reset() to ensure a fresh, shuffled deck is ready.
The following flowchart shows the process within the reset method.
Sources: lib/deck-manager.ts:61-65
Card Dealing and Usage
The poker-engine is the primary consumer of the DeckManager. It orchestrates the dealing of cards to players and the community board according to the game rules and phase.
Sources: lib/poker-engine.ts
Dealing Sequence
The dealCards and dealCommunityCards functions in the poker engine are responsible for drawing cards from the DeckManager and distributing them.
createDeck(): This function in the poker engine callsdeckManager.reset()to prepare a new shuffled deck.dealCards(): This function draws the appropriate number of hole cards for each player (2 for Texas Hold'em, 4 for Omaha) by repeatedly callingdeckManager.drawOne().dealCommunityCards(): For the flop, turn, and river, this function first burns a card by callingdeckManager.drawOne()and placing it in the discard pile viadeckManager.discard(). It then draws the required community cards (3 for the flop, 1 for turn/river) usingdeckManager.draw()ordeckManager.drawOne().
The sequence diagram below shows the interaction for dealing the flop.
Sources: lib/poker-engine.ts:81-105
Card Rendering
Cards are rendered on the front end using the Card component and utility functions for styling.
Card Component
The Card component (components/card.tsx) is a reusable UI element that displays a single playing card. It can show the card's face or back and supports different sizes and animations.
Sources: components/card.tsx
Component Props
| Prop | Type | Default | Description |
|---|---|---|---|
card | CardType | - | The card data object ({ suit, rank }) to display. |
faceDown | boolean | false | If true, shows the back of the card. |
animate | boolean | false | If true, plays a dealing and revealing animation. |
delay | number | 0 | Delay in milliseconds for the animation. |
size | sm|md|lg | md | Sets the size of the card. |
Sources: components/card.tsx:10-18
Card Utilities
The Card component relies on helper functions to determine the correct color and symbol for a given suit. These functions are also used in other parts of the UI, such as the StatsDashboard.
Sources: components/card.tsx:5-6, components/stats-dashboard.tsx:71-84
getCardColor(suit: Suit): Returns a color string (e.g.,"text-red-500") based on the suit. Hearts and Diamonds are red, while Clubs and Spades are black.getSuitSymbol(suit: Suit): Returns the Unicode character for the suit (e.g., "♥", "♦", "♣", "♠").
The StatsDashboard component uses these utilities to display a player's "Best Poker Hand".
// From components/stats-dashboard.tsx
const getSuitSymbol = (suit: string) => {
switch (suit) {
case "hearts": return "♥";
case "diamonds": return "♦";
case "clubs": return "♣";
case "spades": return "♠";
default: return "";
}
};
const getSuitColor = (suit: string) => {
return suit === "hearts" || suit === "diamonds" ? "text-red-500" : "text-gray-900";
};
Sources: components/stats-dashboard.tsx:71-84
Summary
The Deck and Card Management system is a well-defined and decoupled module. The DeckManager singleton provides a reliable, centralized authority for the state of the deck, which is consumed by the poker-engine to drive gameplay. On the frontend, the Card component and its associated utilities offer a flexible and consistent way to render cards across the application, from the active game table to static informational displays. This separation of concerns ensures that game logic remains independent of its visual representation.