2025-10-23 15:00:58 +02:00
|
|
|
|
# Blackjack Game Design Document
|
2025-10-23 15:00:34 +02:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
## 1. Flowchart (Spielablauf)
|
2025-10-26 22:00:41 +01:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
```mermaid
|
|
|
|
|
|
flowchart TD
|
|
|
|
|
|
A([Start]) --> B[Deck erstellen und mischen]
|
|
|
|
|
|
B --> C[Spieler und Dealer erhalten je 2 Karten]
|
|
|
|
|
|
C --> D{Blackjack?}
|
|
|
|
|
|
D -->|Ja| E[Gewinner sofort ermitteln]
|
|
|
|
|
|
D -->|Nein| F[Spielerzug: Hit oder Stand]
|
|
|
|
|
|
F --> G{Bust?}
|
|
|
|
|
|
G -->|Ja| H[Dealer gewinnt]
|
|
|
|
|
|
G -->|Nein| F
|
|
|
|
|
|
F --> I[Spieler steht]
|
|
|
|
|
|
I --> J[Dealer zieht bis >= 17]
|
|
|
|
|
|
J --> K{Bust?}
|
|
|
|
|
|
K -->|Ja| L[Spieler gewinnt]
|
|
|
|
|
|
K -->|Nein| M[Vergleich der Punkte]
|
|
|
|
|
|
M --> N{Wer näher an 21?}
|
|
|
|
|
|
N -->|Spieler| O[Spieler gewinnt]
|
|
|
|
|
|
N -->|Dealer| P[Dealer gewinnt]
|
|
|
|
|
|
N -->|Gleichstand| Q[Push]
|
|
|
|
|
|
O --> R[Ergebnis anzeigen]
|
|
|
|
|
|
P --> R
|
|
|
|
|
|
Q --> R
|
|
|
|
|
|
R --> S{Neues Spiel?}
|
|
|
|
|
|
S -->|Ja| B
|
|
|
|
|
|
S -->|Nein| T([Ende])
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 2. UML-Klassendiagramm
|
2025-10-26 22:00:41 +01:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
```mermaid
|
|
|
|
|
|
classDiagram
|
|
|
|
|
|
class Card {
|
|
|
|
|
|
- rank: str
|
|
|
|
|
|
- suit: str
|
|
|
|
|
|
- value: int
|
|
|
|
|
|
+ __str__(): str
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class Deck {
|
|
|
|
|
|
- cards: List[Card]
|
|
|
|
|
|
+ shuffle(): void
|
|
|
|
|
|
+ deal_card(): Card
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class Hand {
|
|
|
|
|
|
- cards: List[Card]
|
|
|
|
|
|
- value: int
|
|
|
|
|
|
- aces: int
|
|
|
|
|
|
+ add_card(card: Card): void
|
|
|
|
|
|
+ calculate_value(): int
|
|
|
|
|
|
+ adjust_for_ace(): void
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class Player {
|
|
|
|
|
|
- name: str
|
|
|
|
|
|
- chips: int
|
|
|
|
|
|
- hand: Hand
|
|
|
|
|
|
+ hit(deck: Deck): void
|
|
|
|
|
|
+ stand(): void
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class Dealer {
|
|
|
|
|
|
+ play(deck: Deck): void
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class Game {
|
|
|
|
|
|
- deck: Deck
|
|
|
|
|
|
- player: Player
|
|
|
|
|
|
- dealer: Dealer
|
|
|
|
|
|
+ play_round(): void
|
|
|
|
|
|
+ compare_hands(): str
|
|
|
|
|
|
+ show_cards(): void
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Player <|-- Dealer
|
|
|
|
|
|
Game --> Player
|
|
|
|
|
|
Game --> Dealer
|
|
|
|
|
|
Game --> Deck
|
|
|
|
|
|
Player --> Hand
|
|
|
|
|
|
Hand --> Card
|
|
|
|
|
|
Deck --> Card
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 3. Implementierungs-Roadmap mit Tests
|
|
|
|
|
|
|
|
|
|
|
|
### Phase 1: Grundstruktur
|
2025-10-26 22:00:41 +01:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
- **Ziel:** Klassen anlegen, ohne Logik.
|
|
|
|
|
|
- Dateien: `card.py`, `deck.py`, `hand.py`, `player.py`, `dealer.py`, `game.py`, `main.py`.
|
|
|
|
|
|
- Methoden-Signaturen definieren.
|
|
|
|
|
|
|
|
|
|
|
|
**Test:** Importiere alle Klassen in `main.py` und prüfe, ob keine Fehler auftreten.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### Phase 2: Card
|
2025-10-26 22:00:41 +01:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
- `__init__`: Speichert Rang, Farbe, Wert.
|
|
|
|
|
|
- `__str__`: Gibt z. B. "K♠" zurück.
|
|
|
|
|
|
|
|
|
|
|
|
**Test:**
|
2025-10-26 22:00:41 +01:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
```python
|
|
|
|
|
|
card = Card("A", "♠")
|
|
|
|
|
|
print(card) # Erwartet: A♠
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### Phase 3: Deck
|
2025-10-26 22:00:41 +01:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
- `__init__`: Erzeugt 52 Karten.
|
|
|
|
|
|
- `shuffle()`: Mischt die Karten.
|
|
|
|
|
|
- `deal_card()`: Gibt eine Karte zurück und entfernt sie.
|
|
|
|
|
|
|
|
|
|
|
|
**Test:**
|
2025-10-26 22:00:41 +01:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
- Prüfe, ob `len(deck.cards) == 52` nach Erstellung.
|
|
|
|
|
|
- Nach `deal_card()`: Länge = 51.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### Phase 4: Hand
|
2025-10-26 22:00:41 +01:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
- `add_card(card)`: Fügt Karte hinzu.
|
|
|
|
|
|
- `calculate_value()`: Summiert Werte.
|
|
|
|
|
|
- `adjust_for_ace()`: Reduziert Ass von 11 auf 1, wenn nötig.
|
|
|
|
|
|
|
|
|
|
|
|
**Test:**
|
2025-10-26 22:00:41 +01:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
- Hand mit Ass + 9 → Wert = 20.
|
|
|
|
|
|
- Hand mit Ass + 9 + 5 → Wert = 15.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### Phase 5: Player & Dealer
|
2025-10-26 22:00:41 +01:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
- `Player.hit(deck)`: Karte ziehen.
|
|
|
|
|
|
- `Dealer.play(deck)`: Zieht bis Wert ≥ 17.
|
|
|
|
|
|
|
|
|
|
|
|
**Test:**
|
2025-10-26 22:00:41 +01:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
- Spieler zieht Karte → Handgröße +1.
|
|
|
|
|
|
- Dealer zieht automatisch bis ≥ 17.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### Phase 6: Game
|
2025-10-26 22:00:41 +01:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
- `play_round()`: Ablauf wie im Flowchart.
|
|
|
|
|
|
- `compare_hands()`: Gewinner bestimmen.
|
|
|
|
|
|
- `show_cards()`: Karten anzeigen.
|
|
|
|
|
|
|
|
|
|
|
|
**Test:**
|
2025-10-26 22:00:41 +01:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
- Simuliere eine Runde:
|
|
|
|
|
|
- Spieler steht sofort.
|
|
|
|
|
|
- Dealer spielt.
|
|
|
|
|
|
- Ergebnis wird angezeigt.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### Phase 7: Erweiterungen
|
2025-10-26 22:00:41 +01:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
- Chips & Einsätze.
|
|
|
|
|
|
- Mehrere Spieler.
|
|
|
|
|
|
- Features wie Split, Double Down.
|
|
|
|
|
|
|
|
|
|
|
|
**Test:**
|
2025-10-26 22:00:41 +01:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
- Chips reduzieren sich nach Einsatz.
|
|
|
|
|
|
- Gewinn/Verlust korrekt berechnet.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### Teststrategie
|
2025-10-26 22:00:41 +01:00
|
|
|
|
|
2025-10-23 15:00:58 +02:00
|
|
|
|
- **Unit-Tests** für jede Klasse (z. B. mit `pytest`).
|
|
|
|
|
|
- **Integrationstest**: Komplette Runde simulieren.
|
|
|
|
|
|
- **Edge Cases**:
|
|
|
|
|
|
- Mehrere Asse.
|
|
|
|
|
|
- Spieler oder Dealer hat Blackjack.
|
|
|
|
|
|
- Beide haben denselben Wert.
|
2025-10-23 15:04:18 +02:00
|
|
|
|
|
|
|
|
|
|
### Projektstruktur für OOP-Blackjack
|
|
|
|
|
|
|
|
|
|
|
|
```plaintext
|
|
|
|
|
|
blackjack/
|
|
|
|
|
|
│
|
|
|
|
|
|
├── main.py # Einstiegspunkt des Programms
|
|
|
|
|
|
├── requirements.txt # (optional) Abhängigkeiten
|
|
|
|
|
|
├── README.md # Projektbeschreibung
|
|
|
|
|
|
│
|
|
|
|
|
|
├── blackjack/ # Hauptpaket
|
|
|
|
|
|
│ ├── __init__.py
|
|
|
|
|
|
│ ├── card.py # Card-Klasse
|
|
|
|
|
|
│ ├── deck.py # Deck-Klasse
|
|
|
|
|
|
│ ├── hand.py # Hand-Klasse
|
|
|
|
|
|
│ ├── player.py # Player-Klasse
|
|
|
|
|
|
│ ├── dealer.py # Dealer-Klasse
|
|
|
|
|
|
│ └── game.py # Game-Klasse (Spiellogik)
|
|
|
|
|
|
│
|
|
|
|
|
|
├── tests/ # Unit-Tests
|
|
|
|
|
|
│ ├── __init__.py
|
|
|
|
|
|
│ ├── test_card.py
|
|
|
|
|
|
│ ├── test_deck.py
|
|
|
|
|
|
│ ├── test_hand.py
|
|
|
|
|
|
│ ├── test_player.py
|
|
|
|
|
|
│ ├── test_dealer.py
|
|
|
|
|
|
│ └── test_game.py
|
|
|
|
|
|
│
|
|
|
|
|
|
└── docs/ # Dokumentation
|
|
|
|
|
|
└── blackjack_design.md # Design-Dokument mit UML & Flowchart
|