diff --git a/docs/roadmap.md b/docs/roadmap.md index 7dadff1..5807246 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1,87 +1,98 @@ -# Blackjack Implementierungs-Roadmap +# 🗺️ Blackjack Implementation Roadmap with Method Signatures (Final, Clean Markdown) -Dies ist eine schrittweise Anleitung zur Implementierung des Blackjack-Spiels basierend auf dem bereitgestellten Klassendiagramm. Der Fokus liegt auf der **inkrementellen Entwicklung** und dem Testen jeder Klasse, bevor mit der nächsten begonnen wird. +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: Die Grundlagen – Karten und Stapel +## Phase 1: The Basics – Card and Deck -Das Ziel dieser Phase ist die Erstellung des statischen Materials: der Karten und des Decks. +### 1. `Card` Class -### 1. Card (Karte) +The `Card` class is a **static data container**. -| Fokus | Hinweise | -| :--- | :--- | -| **Attribute** | `rank` (z.B. 'A', 'K', '5'), `suit` (z.B. 'Herz', 'Pik'), `value` (initialer Blackjack-Wert). | -| **Logik** | Definiere die Wertzuordnung: 2-10 sind ihr Nennwert, Bube/Dame/König sind **10**, Ass ist initial **11**. | -| **Methode** | Implementiere `__str__` für eine klare Ausgabe (z.B. "Ass der Pik"). | +| 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 (Kartenstapel) +### 2. `Deck` Class -| Fokus | Hinweise | -| :--- | :--- | -| **Initialisierung** | Erzeuge im Konstruktor **alle 52** `Card`-Objekte (vier Farben $\times$ 13 Ränge) und speichere sie in der internen Liste `cards`. | -| **`shuffle()`** | Verwende eine geeignete Bibliotheksfunktion (z.B. `random.shuffle` in Python) zum Mischen der `cards`-Liste. | -| **`deal_card()`** | Entferne die oberste Karte aus der Liste (z.B. `pop()`) und gib sie zurück. Behandele den Fall, dass das Deck leer ist (optional). | +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: Hände und Wertberechnung +## Phase 2: Core Logic – Hand and Value Calculation -Diese Phase implementiert die Kernlogik von Blackjack: die Verwaltung einer Hand und die flexible Wertberechnung. +### 3. `Hand` Class -### 3. Hand (Spielerhand) +The `Hand` object's role is to ensure the **Blackjack value rules** are always correctly applied, especially the Ace rule. -| Fokus | Hinweise | -| :--- | :--- | -| **`add_card(card)`** | Füge die Karte zur Liste hinzu. Aktualisiere **sofort** den Handwert und zähle die Anzahl der Asse (`aces`). | -| **`calculate_value()`** | Gib die einfache Summe der Werte aller Karten zurück. | -| **`adjust_for_ace()`** | Die **wichtigste Logik** von Blackjack: Rufe diese Methode nach jeder Kartenaufnahme auf. **Schleife:** Solange der Gesamtwert (`value`) **über 21** ist **UND** Asse vorhanden sind (`aces > 0`), **reduziere** den Wert um 10 und verringere `aces` um 1. | - -### 4. Player / Dealer (Basisstruktur) - -| Fokus | Hinweise | -| :--- | :--- | -| **`Player`** | Definiere die Basisattribute (`name`, `chips`, `hand`). | -| **`hit(deck)`** | Ruft `deck.deal_card()` auf und übergibt die Karte an `self.hand.add_card()`. | -| **`Dealer`** | Erbt von `Player`. Benötigt zunächst nur die Vererbung. | +| 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: Spielsteuerung und Rundenablauf +## Phase 3: The Actors and Their Actions -Hier wird das Spielbrett aufgestellt und die grundlegende Interaktion ermöglicht. +### 4. `Player` Class (Base) -### 5. Game-Setup +The `Player` class represents any participant who holds a hand and makes decisions. -| Fokus | Hinweise | -| :--- | :--- | -| **Konstruktor** | Initialisiere die zentralen Komponenten: `Deck` (mischen nicht vergessen!), `Player` und `Dealer`. | -| **`show_cards()`** | Zeige die Karten des Spielers komplett an. Für den Dealer zeige nur die **erste** Karte an, bis die Spielzüge beendet sind. | +| 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. | -### 6. Geber-Logik und Spielzüge +### 5. `Dealer` Class (Inherits from `Player`) -| Fokus | Hinweise | -| :--- | :--- | -| **`Dealer.play(deck)`** | Implementiere die feste Geber-Regel: Der Dealer muss `hit()` aufrufen, solange sein Handwert **kleiner als 17** ist. | -| **Spieler-Zug** | Implementiere eine Schleife in `play_round()`, die den Spieler nach "Hit" oder "Stand" fragt, bis er steht oder überkauft ("Bust", $>21$). | +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: Abschluss, Vergleich und Finanzen +## Phase 4: Game Orchestration and Resolution -Der letzte Schritt kümmert sich um die Auszahlung und den wiederholten Spielbetrieb. +### 6. `Game` Class -### 7. Ergebnis und Chip-Management +The `Game` class is the central coordinator, managing the flow of the entire round, from setup to payout. -| Fokus | Hinweise | -| :--- | :--- | -| **`compare_hands()`** | Diese Methode wird aufgerufen, nachdem sowohl der Spieler als auch der Dealer ihre Züge abgeschlossen haben. | -| **Vergleich** | Berücksichtige alle Fälle in dieser Reihenfolge: **Blackjack** (21 auf 2 Karten), **Bust** (wer hat > 21?), **höherer Wert** gewinnt, **Push** (Gleichstand). | -| **Chips** | Passe die `chips` des Spielers basierend auf dem Ergebnis von `compare_hands()` an (z.B. $\times 1.5$ für Blackjack, $\times 1$ für normalen Gewinn, $0$ für Push, $-\text{Einsatz}$ für Verlust). | - -### 8. Spiel-Loop - -| Fokus | Hinweise | -| :--- | :--- | -| **Hauptfunktion** | Erstelle die Hauptroutine, die wiederholt **Einsatz erfragt**, `deck.shuffle()` aufruft und `play_round()` startet, bis der Spieler keine Chips mehr hat oder beenden möchte. | +| 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. |