# How DD Poker Handles Showdown and Pot Distribution: A Complete Code Walkthrough

> Explore DD Poker's code to understand how it handles showdown and pot distribution. Learn about winner determination, chip splitting, and remainder distribution in this code walkthrough.

- Repository: [Doug Donohoe/ddpoker](https://github.com/dougdonohoe/ddpoker)
- Tags: deep-dive
- Published: 2026-02-28

---

**DD Poker executes showdown through a tightly coupled sequence where the `Showdown` class locks the UI into a "no-fold" mode, then `HoldemHand.resolve()` iterates over all pots to determine winners by `HandInfo` scores, split chips evenly, and distribute remainder chips from the dealer button outward.**

DD Poker is an open-source Texas Hold'em engine written in Java by Doug Donohoe. Understanding how the codebase handles **showdown and pot distribution** reveals a clean architectural separation between UI presentation and core game logic, implemented across the `Showdown` and `HoldemHand` classes.

## Entering the Showdown Phase

When a hand reaches its conclusion, the game engine invokes the `Showdown` phase located in [`code/poker/src/main/java/com/donohoedigital/games/poker/Showdown.java`](https://github.com/dougdonohoe/ddpoker/blob/main/code/poker/src/main/java/com/donohoedigital/games/poker/Showdown.java). The `process()` method (lines 64‑78) performs three critical safety checks before allowing resolution:

- Stores a reference to the current `TournamentDirector` to maintain game state context.
- Forces the "no-fold" key to prevent player actions during resolution.
- Switches the input mode to a safe "quit-save" state, ensuring no further betting actions can occur while the pot is being distributed.

This initialization guarantees that once showdown begins, the hand state is immutable from the player's perspective.

## Displaying the Showdown Board

After locking the input state, `Showdown.displayShowdown()` (lines 99‑115) constructs the visual representation of the hand outcome. This method iterates over every seat at the table to render card visibility based on **cheat options** such as `OPTION_CHEAT_RABBITHUNT` (show river) or `OPTION_CHEAT_SHOWWINNINGHAND`. It also posts relevant chat messages to the game log to document the showdown progression.

## Resolving Pots and Determining Winners

The core resolution logic resides in [`code/poker/src/main/java/com/donohoedigital/games/poker/HoldemHand.java`](https://github.com/dougdonohoe/ddpoker/blob/main/code/poker/src/main/java/com/donohoedigital/games/poker/HoldemHand.java). The `resolve()` method (lines 42‑53) serves as the entry point for all pot distribution:

```java
// Assume `hand` is a populated HoldemHand instance that has completed betting rounds.
hand.setAllInShowdown(true);   // force an all‑in showdown if desired
hand.resolve();                // runs the full pot‑distribution logic

```

This method iterates over **all** pots for the hand—including the main pot and any side pots created by all-in situations—and invokes `resolvePot()` for each one.

### Winner Detection and Hand Scoring

Inside `resolvePot()` (lines 19‑30), the engine performs a multi-pass analysis:

1. **Collect Hand Scores** – For each player still eligible for the pot, the method reads the `HandInfo` score. The highest score becomes `nHighScore`.
2. **Expose Cards** – If a player's score matches `nHighScore`, the card-exposure flag is set (unless the hand is uncontested and the player has not opted to show). During all-in showdowns, cards are exposed according to standard visibility rules.
3. **Build Winner List** – A second pass constructs an ordered `List<PokerPlayer>` of winners based on button position, preserving the natural showdown order starting from the small blind.
4. **Store Results** – The pot object persists the winner list via `pot.setWinners(winners)` (lines 65‑68).

### Inspecting Winners Programmatically

After resolution, you can inspect the results through the pot objects:

```java
int potIndex = 0;                       // main pot
Pot pot = hand.getPot(potIndex);
List<PokerPlayer> winners = pot.getWinners();  // populated by resolvePot()
for (PokerPlayer p : winners) {
    System.out.println(p.getName() + " won " + p.getPendingWin() + " chips");
}

```

## Chip Distribution and the Odd-Chip Rule

Once winners are identified, `resolvePot()` calculates chip distribution in two phases.

### Calculating Equal Shares

The pot's total chip count (`nPot`) is divided evenly among all winners. The per-player share is rounded down to the table's **minimum chip denomination** (`nMinChip`) as shown in lines 68‑76. Any remainder that is not a multiple of the minimum chip is logged as a warning for audit purposes.

### Distributing Remainder Chips

Following standard Texas Hold'em rules, remainder chips are handed out one-by-one to the winners closest to the dealer button (lines 88‑95). This ensures the "odd-chip" is awarded to the earliest eligible position. During this phase, winners receive a temporary **pending win** amount recorded in their player state, which is later converted into a concrete win record.

## Awarding Chips and Final Verification

The final distribution loop (lines 98‑110) walks all players in showdown order:

- **For winners**: Calls `player.wins(amount, potNumber)` for standard pots, or `player.overbet(...)` for over-bet scenarios.
- **For non-winners**: Calls `player.lose(potNumber)` to record their participation in the lost pot.
- **Cleanup**: Clears the pending win field after crediting the player.

### Sanity Checking Pot Integrity

After all winners have been paid, the method executes a verification step (lines 124‑132) comparing the total chips awarded (`nTotalCheck`) against the original pot size. A warning is logged if any discrepancy exists, preventing chip inflation or loss due to rounding errors.

## Housekeeping and Event Firing

Following successful distribution, `resolve()` (lines 53‑71) performs end-of-hand housekeeping:

- Records comprehensive hand statistics for tracking and analysis.
- Fires an `END_HAND` table event via `PokerTableEvent`, signaling UI components to refresh.
- Persists the hand history to the database (unless running in pure-computer simulation mode).

### Configuring Cheat Options for Testing

You can override default visibility settings to force the river to display during showdown:

```java
PokerContext ctx = game.getContext();
PokerUtils.setCheatOption(ctx, PokerConstants.OPTION_CHEAT_RABBITHUNT, true);

```

This option is referenced in `Showdown.displayShowdown()` (lines 9‑11) to determine whether to reveal community cards early.

## Summary

- **Showdown initialization** locks the UI via `Showdown.process()` to prevent player interference during resolution.
- **Winner determination** occurs in `HoldemHand.resolvePot()`, which compares `HandInfo` scores and handles card exposure for both contested and uncontested pots.
- **Chip calculation** divides pots evenly among winners, rounding to the table's minimum chip value (`nMinChip`).
- **Odd-chip distribution** awards remainders starting from the dealer button position outward.
- **Integrity verification** ensures the total chips awarded exactly match the pot size before firing the `END_HAND` event.

## Frequently Asked Questions

### How does DD Poker handle multiple side pots during showdown?

The `HoldemHand.resolve()` method iterates over every pot object associated with the hand (main pot plus any side pots created by all-in players) and calls `resolvePot()` individually for each. Each pot maintains its own independent winner list, allowing complex all-in scenarios to resolve correctly according to the `HandInfo` scores eligible for each specific pot.

### What happens when pot chips cannot be divided evenly among winners?

The engine first calculates an equal share rounded down to the table's minimum chip denomination (`nMinChip`). Any remaining odd chips are then distributed one at a time to winners in position order starting from the dealer button, as implemented in [`HoldemHand.java`](https://github.com/dougdonohoe/ddpoker/blob/main/HoldemHand.java) lines 88‑95. This adheres to standard Texas Hold'em odd-chip rules.

### How can developers test showdown logic without running a full hand simulation?

You can force a hand into showdown mode programmatically by calling `setAllInShowdown(true)` on a populated `HoldemHand` instance, followed by `resolve()`. This bypasses normal betting rounds and immediately executes the pot distribution logic, useful for unit testing winner detection and chip calculation algorithms.

### Where is the showdown winner data stored after resolution?

After `resolvePot()` executes, the winner list is stored directly on the `Pot` object via `pot.setWinners(winners)`. You can retrieve this data after resolution by calling `pot.getWinners()`, which returns an ordered list of `PokerPlayer` objects representing the winning hands for that specific pot.