Add complete Texas Hold'em poker gameplay including: - Pure function game engine (deck, dealing, betting, showdown) - Hand evaluator supporting all 10 poker hand ranks - Animated card components with 3D flip transitions - CSS Grid oval poker table layout for up to 9 seats - Player seat components with chip tracking and turn indicators - Bet controls with conditional button visibility - Basic AI opponents with random valid action selection - Turn advancement, all-in auto-advance, and dealer rotation Sync delta specs to main specs: poker-table, card-components, game-engine, player-state.
63 lines
4.1 KiB
Markdown
63 lines
4.1 KiB
Markdown
## Context
|
|
|
|
Fresh SvelteKit 2 + Svelte 5 project with no poker functionality. The proposal defines four capabilities: poker table UI, card components, game engine, and player state management. No external dependencies will be added — everything uses Svelte 5 runes, native CSS, and built-in transition primitives.
|
|
|
|
## Goals / Non-Goals
|
|
|
|
**Goals:**
|
|
- Playable Texas Hold'em game with human player vs AI opponents
|
|
- Smooth card flip/deal animations using Svelte's `flip()` and `transition:` directives
|
|
- Clean component hierarchy with clear separation between UI components and game logic
|
|
- Responsive poker table layout that works on desktop screens
|
|
- State management via Svelte 5 runes (`$state`, `$derived`) — no stores needed
|
|
|
|
**Non-Goals:**
|
|
- Multiplayer networking (local play only)
|
|
- Tournament mode or cash game buy-in flows
|
|
- Educational tools, strategy guidance, or GTO analysis
|
|
- TailwindCSS or any CSS framework — native Svelte styling only
|
|
- Mobile-first responsive design (desktop first)
|
|
|
|
## Decisions
|
|
|
|
### State Management: Runes over Stores
|
|
Using Svelte 5 `$state` and `$derived` runes instead of writable stores. The game state is a single reactive object passed down through component props. This avoids the store subscription overhead and gives us true two-way binding with `$stateful` when needed for form inputs.
|
|
|
|
**Alternatives considered:** Svelte stores (legacy pattern, unnecessary complexity), Zustand or external state library (adds dependency, defeats purpose of using Svelte 5 runes).
|
|
|
|
### Game Engine: Pure Functions over Classes
|
|
The game engine will be a set of pure functions operating on an immutable `GameState` object. Each action (deal, bet, fold, check) returns a new state. This makes the logic testable, predictable, and easy to reason about. The UI layer reads from this state and dispatches actions.
|
|
|
|
**Alternatives considered:** Class-based engine (mutable state, harder to test), finite state machine library (overhead for a single game type).
|
|
|
|
### Card Animations: Svelte `flip()` + CSS 3D Transforms
|
|
Card flip uses CSS `transform: rotateY(180deg)` with `backface-visibility: hidden`. Dealing animations use Svelte's `flip()` spring animation to animate cards from dealer position to their final seat. Hover effects use simple CSS transitions on scoped styles.
|
|
|
|
**Alternatives considered:** Framer Motion or motion library (external dependency), SVG-based cards (unnecessary complexity).
|
|
|
|
### Table Layout: CSS Grid
|
|
The poker table uses a single CSS Grid with named areas for each player seat, community card zone, and pot display. Seat positions are calculated using `grid-column`/`grid-row` based on an oval table shape. The dealer button rotates using grid positioning updates driven by `$derived` state.
|
|
|
|
**Alternatives considered:** Absolute positioning (hard to maintain), Flexbox-only layout (insufficient for radial seating arrangement).
|
|
|
|
### Project Structure
|
|
```
|
|
src/lib/
|
|
types/ # TypeScript interfaces (Card, Hand, Player, GameState)
|
|
game/ # Pure game logic functions (deck, betting, hand evaluation)
|
|
components/ # Svelte UI components (Card, PokerTable, PlayerSeat, BetControls)
|
|
utils/ # Helpers (hand ranker, suit/rank constants)
|
|
```
|
|
|
|
## Risks / Trade-offs
|
|
|
|
- **Hand evaluation algorithm complexity** → Using a simplified scoring approach (rank-based comparison) rather than enumerating all 7-card combinations. May miss edge cases in rare hands but keeps implementation manageable for v1.
|
|
- **No external animation library** → Svelte's `flip()` handles most cases, but complex multi-card deal sequences may require manual spring configuration. Acceptable trade-off for zero dependencies.
|
|
- **Single-page game only** → No route-based navigation; entire game lives on the root page. This simplifies state management but means no browser back-button support mid-game.
|
|
|
|
## Open Questions
|
|
|
|
- How many AI difficulty levels should the initial engine support? (Suggested: one basic level with random valid actions)
|
|
- Should blinds be configurable or fixed for v1? (Suggested: fixed small/big blind, configurable via game state)
|
|
- What chip denomination system to use? (Suggested: simple numeric values, no visual chip denominations needed in v1)
|