186 lines
6.6 KiB
Markdown
186 lines
6.6 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
King's Eunuch is a poker training tool designed to help users calibrate hand strength and learn poker game theory. The project is built in Rust and is designed to eventually support poker bot functionality. It's aimed at beginners and focuses on teaching through situational environments.
|
|
|
|
## Learning Project - Tutoring Approach
|
|
|
|
**This is a Rust learning project.** The developer is using this codebase to learn Rust programming.
|
|
|
|
When working with this code, Claude should act as a **tutor** rather than just completing tasks:
|
|
- **Explain concepts** - When suggesting code changes, explain the Rust concepts being used
|
|
- **Guide rather than solve** - Ask clarifying questions and suggest approaches rather than immediately writing full solutions
|
|
- **Teach patterns** - Point out idiomatic Rust patterns and explain why they're preferred
|
|
- **Encourage exploration** - Suggest areas to investigate and documentation to read
|
|
- **Build on existing knowledge** - Leverage concepts the developer already knows
|
|
|
|
### Current Rust Knowledge
|
|
|
|
The developer is comfortable with:
|
|
- Enums and structs
|
|
- `Option<T>` and `Result<T, E>` error handling
|
|
- Generics (the `<>` brackets)
|
|
- Pattern matching with `match`
|
|
- Borrowing and references (`&`)
|
|
- Methods and `impl` blocks
|
|
- Traits (Ord, PartialOrd, Eq, PartialEq, Hash, Copy, Clone, Debug)
|
|
- Standard collections (`HashMap`, `HashSet`, `Vec`)
|
|
- Iterators and iterator methods (`.map()`, `.filter()`, `.collect()`)
|
|
- Basic testing with `#[test]`
|
|
|
|
### Next Rust Concepts to Explore
|
|
|
|
Topics the developer is working toward:
|
|
- Lifetimes and lifetime annotations
|
|
- More advanced trait usage (trait bounds, where clauses)
|
|
- Error handling patterns (custom error types, `?` operator best practices)
|
|
- Ownership patterns in complex scenarios
|
|
- Module system and visibility
|
|
- Performance optimization techniques
|
|
- Advanced iterator adapters and functional patterns
|
|
|
|
## Build and Test Commands
|
|
|
|
```bash
|
|
# Build the project
|
|
cargo build
|
|
|
|
# Run the main demo
|
|
cargo run
|
|
|
|
# Run all tests
|
|
cargo test
|
|
|
|
# Run specific test suites
|
|
cargo test flush # Flush detection tests
|
|
cargo test straight # Straight detection tests
|
|
cargo test pair # Pair-related tests
|
|
cargo test straight_flush # Straight flush tests
|
|
cargo test high_card # High card tests
|
|
cargo test hand_comparison # Hand comparison logic tests
|
|
|
|
# Build in release mode
|
|
cargo build --release
|
|
|
|
# Check code without building
|
|
cargo check
|
|
```
|
|
|
|
## Architecture
|
|
|
|
The codebase follows a layered architecture with separation of concerns:
|
|
|
|
### Core Modules
|
|
|
|
**`hand_building/`** - Foundation layer for card and hand representation
|
|
- `card.rs` - Defines `Card`, `Suit`, and `Rank` types with parsing logic
|
|
- `Rank` uses reverse discriminants (Ace=1, King=2...Two=13) for simpler comparison
|
|
- String parsing format: rank char + suit char (e.g., "Ah" = Ace of hearts)
|
|
- Rank chars: 2-9, T, J, Q, K, A
|
|
- Suit chars: s (spades), h (hearts), d (diamonds), c (clubs)
|
|
- `detection.rs` - Hand detection functions that identify poker hands from cards
|
|
- Each detector returns `Option<Vec<Card>>` with exactly 5 cards sorted by rank
|
|
- Functions: `find_flush`, `find_straight`, `find_pair`, `find_two_pair`, `find_trips`, `find_quads`, `find_full_house`, `find_straight_flush`, `find_high_card`
|
|
- Handles special cases like ace-low straights (A-2-3-4-5)
|
|
- `hand.rs` - `Hand` struct with `HandRank` enum and comparison logic
|
|
- `Hand::from_cards()` evaluates cards and returns the best possible hand
|
|
- Implements `Ord` trait for hand comparison (accounts for both rank and kickers)
|
|
- `HandRank` discriminants are reversed (StraightFlush=1...HighCard=9) for easier comparison
|
|
- Universal comparison via `compare_same_rank()` method
|
|
|
|
**`evaluation/`** - Placeholder for future hand evaluation enhancements
|
|
|
|
**`game_engine/`** - Placeholder for future game state management
|
|
|
|
### Design Principles
|
|
|
|
1. **Separation of Concerns** - Game rules separate from probability calculations separate from AI/training logic
|
|
2. **Extensibility** - Designed for both training scenarios AND bot decision-making
|
|
3. **Testability** - Each component is independently testable with comprehensive test coverage
|
|
4. **Clarity over Cleverness** - Code prioritizes readability and educational value
|
|
|
|
### Card Representation Details
|
|
|
|
The `Rank` enum uses reverse discriminants where lower numbers = better cards. This simplifies comparison logic since Rust's default `Ord` implementation works correctly:
|
|
- Ace = 1 (best)
|
|
- King = 2
|
|
- ...
|
|
- Two = 13 (worst)
|
|
|
|
This means you can directly compare ranks without custom comparison logic.
|
|
|
|
### Hand Detection Pattern
|
|
|
|
All hand detectors follow a consistent pattern:
|
|
1. Check minimum card requirements
|
|
2. Build frequency maps using `HashMap`
|
|
3. Identify the hand pattern
|
|
4. Extract the best cards for that hand
|
|
5. Add kickers sorted by rank (best first) up to 5 cards total
|
|
6. Return `Some(Vec<Card>)` or `None`
|
|
|
|
### Future Layers (from ARCHITECTURE.md)
|
|
|
|
**Layer 3: Game State** - Model poker game state (hole cards, community cards, stage, pot)
|
|
|
|
**Layer 4: Probability Engine** - Monte Carlo simulation for equity calculations
|
|
|
|
**Layer 5: Training System** - Scenario generator and quiz mechanics for user training
|
|
|
|
**Layer 6: Bot/AI** - Decision engine with GTO solver and exploit strategies
|
|
|
|
## Common Patterns
|
|
|
|
### Creating Cards from Strings
|
|
|
|
```rust
|
|
use kings_eunuch::hand_building::Card;
|
|
|
|
let card = Card::str_to_card("Ah").unwrap(); // Ace of hearts
|
|
let cards = cards_from_str("Ah Kh Qh Jh Th")?; // Multiple cards
|
|
```
|
|
|
|
### Evaluating Hands
|
|
|
|
```rust
|
|
use kings_eunuch::hand_building::Hand;
|
|
|
|
let cards = cards_from_str("Ah Kh Qh Jh Th")?;
|
|
let hand = Hand::from_cards(&cards).unwrap();
|
|
// hand.rank will be HandRank::StraightFlush
|
|
// hand.cards will contain the 5 best cards
|
|
```
|
|
|
|
### Comparing Hands
|
|
|
|
```rust
|
|
use std::cmp::Ordering;
|
|
|
|
let hand1 = Hand::from_cards(&cards1).unwrap();
|
|
let hand2 = Hand::from_cards(&cards2).unwrap();
|
|
|
|
match hand1.cmp(&hand2) {
|
|
Ordering::Greater => println!("hand1 wins"),
|
|
Ordering::Less => println!("hand2 wins"),
|
|
Ordering::Equal => println!("tie"),
|
|
}
|
|
```
|
|
|
|
## Current Status
|
|
|
|
The project is in Phase 1 (Foundation):
|
|
- ✓ Card representation complete
|
|
- ✓ Hand struct complete
|
|
- ✓ All hand detection functions implemented
|
|
- ✓ Hand comparison logic with kicker support
|
|
- ✓ Comprehensive test coverage
|
|
|
|
Next steps involve implementing game state management (deck, dealing, game stages).
|
|
|
|
## Known Issue
|
|
|
|
There is currently a syntax error in `hand.rs:83` - an unclosed delimiter. This must be fixed before the code will compile.
|