Files
blackjack/docs/roadmap.md
2025-10-26 11:30:14 +01:00

99 lines
5.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🗺️ Blackjack Implementation Roadmap with Method Signatures (Final, Clean Markdown)
This document provides a detailed, class-by-class breakdown of the Blackjack project, including the expected method signatures and descriptions of class interactions, using only standard Markdown syntax.
---
## Phase 1: The Basics Card and Deck
### 1. `Card` Class
The `Card` class is a **static data container**.
| Component | Signature / Example Value | Purpose |
| :--- | :--- | :--- |
| **Constructor** | `def __init__(self, rank: str, suit: str, value: int)` | Initializes the card with its fixed properties. |
| **Attribute** | `- rank: str` | `'A', 'K', '3'` |
| **Attribute** | `- suit: str` | `'Spades', 'Hearts'` |
| **Attribute** | `- value: int` | **10** (for K, Q, J) or **11** (for A). This is the card's **initial** value. |
| **Method** | `def __str__(self) -> str` | Returns a human-readable string (e.g., `"Queen of Diamonds"`). |
| **Call Example** | `print(my_card)` | Used automatically by the `print()` function. |
### 2. `Deck` Class
The `Deck` manages the card pool, creating and distributing the `Card` objects.
| Component | Signature / Example Call | Purpose |
| :--- | :--- | :--- |
| **Constructor** | `def __init__(self)` | Creates all 52 unique `Card` objects and stores them in `self.cards`. |
| **Attribute** | `- cards: List[Card]` | The internal list holding all 52 `Card` objects. |
| **Method** | `def shuffle(self) -> None` | Randomly **reorders** the elements in the internal `cards` list. |
| **Call Example** | `my_deck.shuffle()` | Called at the start of every new round. |
| **Method** | `def deal_card(self) -> Card` | **Removes and returns** the top card (e.g., using a list's `pop()` method). |
| **Call Example** | `new_card = my_deck.deal_card()` | Called by `Player.hit()` and the `Game` for initial dealing. |
---
## Phase 2: Core Logic Hand and Value Calculation
### 3. `Hand` Class
The `Hand` object's role is to ensure the **Blackjack value rules** are always correctly applied, especially the Ace rule.
| Component | Signature / Example Call | Purpose |
| :--- | :--- | :--- |
| **Constructor** | `def __init__(self)` | Initializes `cards` as empty, `value` to **0**, and `aces` to **0**. |
| **Attribute** | `- value: int` | The current, **dynamically adjusted** sum of the cards. |
| **Attribute** | `- aces: int` | Count of Aces held (used for the 1/11 rule). |
| **Method** | `def add_card(self, card: Card) -> None` | **Updates Hand:** Appends `card`, updates `self.value`, increments `self.aces` if needed, and then calls `self.adjust_for_ace()`. |
| **Call Example** | `player_hand.add_card(new_card)` | Called every time a card is drawn. |
| **Method** | `def adjust_for_ace(self) -> None` | **Ace Rule Logic:** Uses a `while` loop: if `value > 21` AND `aces > 0`, it subtracts **10** from `value` and decrements `aces`. |
| **Call Example** | (Internal call from `add_card`) | Called automatically after every card addition. |
---
## Phase 3: The Actors and Their Actions
### 4. `Player` Class (Base)
The `Player` class represents any participant who holds a hand and makes decisions.
| Component | Signature / Example Call | Purpose |
| :--- | :--- | :--- |
| **Constructor** | `def __init__(self, name: str, chips: int)` | Sets up the player's name, starting chips, and a new `Hand` object. |
| **Attribute** | `- hand: Hand` | The specific `Hand` object associated with this player. |
| **Method** | `def hit(self, deck: Deck) -> None` | **Draws Card:** Retrieves a card from the `Deck` (`deck.deal_card()`) and passes it to the internal hand (`self.hand.add_card(...)`). |
| **Call Example** | `player.hit(my_deck)` | Called when a player chooses to draw a card. |
| **Method** | `def stand(self) -> None` | **Ends Turn:** Sets an internal state (e.g., `$is\_standing = True$`) to signal the end of the player's draw phase. |
| **Call Example** | `player.stand()` | Called when a player is satisfied with their hand. |
### 5. `Dealer` Class (Inherits from `Player`)
The `Dealer` inherits all player functionality but has a specific, automated turn behavior.
| Component | Signature / Example Call | Purpose |
| :--- | :--- | :--- |
| **Method** | `def play(self, deck: Deck) -> None` | **Automated Turn:** Implements the fixed dealer rule: uses a `while` loop to continuously call `self.hit(deck)` as long as `self.hand.value < 17`. |
| **Call Example** | `dealer.play(my_deck)` | Called only after the human player has finished their turn. |
---
## Phase 4: Game Orchestration and Resolution
### 6. `Game` Class
The `Game` class is the central coordinator, managing the flow of the entire round, from setup to payout.
| Component | Signature / Example Call | Purpose |
| :--- | :--- | :--- |
| **Constructor** | `def __init__(self)` | Creates instances of `Deck`, `Player`, and `Dealer`. |
| **Attribute** | `- deck: Deck` | The `Deck` instance used for card distribution. |
| **Attribute** | `- player: Player` | The human `Player` instance. |
| **Attribute** | `- dealer: Dealer` | The `Dealer` instance. |
| **Method** | `def play_round(self) -> None` | **Main Flow Controller:** Manages dealing, player input loops, the dealer's `play()` call, and calling `compare_hands()`. |
| **Call Example** | `my_game.play_round()` | The main function that drives one full round of Blackjack. |
| **Method** | `def show_cards(self, hide_dealer: bool) -> None` | Displays the cards. The boolean determines if the dealer's second card is shown or concealed. |
| **Call Example** | `game.show_cards(hide_dealer=True)` | Called at the beginning of the round. |
| **Method** | `def compare_hands(self, bet: int) -> str` | **Resolution/Payout:** Compares final hand values, checks for Bust, Blackjack, and highest value. **Updates `player.chips`** based on the outcome and the `bet`. Returns the result string (e.g., "Player Wins!"). |
| **Call Example** | `result = game.compare_hands(50)` | Called once both players stand or bust. |