Veit F. a07117efaf fix: implement correct Texas Hold'em betting rules and game flow
Rewrite core game logic to fix 10 critical bugs violating poker rules:

- Add betMatched flag to separate chip tracking from bet-matching state
- Implement last-aggressor tracking for proper betting round completion
- Rewrite all action functions with validation enforcement
- Add side pot support for multi-level all-in scenarios
- Replace nested setTimeout AI turns with async promise chain
- Add aiActing guard to prevent race conditions during AI play
- Fix currentTurn advancement to always land on active players
2026-05-17 18:46:08 +02:00

71 lines
4.0 KiB
Markdown

## 1. Type system updates
- [x] 1.1 Add `betMatched: boolean` field to `PlayerSeat` interface in `src/lib/types/player.ts`
- [x] 1.2 Add `lastAggressorIndex: number` field to `GameState` interface in `src/lib/types/game-state.ts`
- [x] 1.3 Define `SidePot` interface with `amount` and `eligiblePlayerIds` fields
- [x] 1.4 Add `sidePots: SidePot[]` field to `GameState` interface
## 2. State initialization & reset
- [x] 2.1 Update `createInitialState` to initialize new fields (`betMatched`, `lastAggressorIndex`, `sidePots`)
- [x] 2.2 Update `startNewHand` to reset all per-round fields including new fields
- [x] 2.3 Update `postBlinds` to set `betMatched` correctly for SB and BB players
## 3. Action function rewrites
- [x] 3.1 Rewrite `applyCheck` to set `betMatched = true` without modifying `currentBet` or chips
- [x] 3.2 Rewrite `applyCall` to use `state.currentBet - player.currentBet` for call amount with correct chip deduction
- [x] 3.3 Rewrite `applyRaise` to update `lastAggressorIndex`, reset other players' `betMatched`, and enforce minimum raise
- [x] 3.4 Rewrite `applyFold` to correctly mark player as folded and advance turn
- [x] 3.5 Rewrite `applyAllIn` to handle partial all-in raises and update `lastAggressorIndex` if applicable
- [x] 3.6 Add `validateAction` call at the start of each action function with early return on invalid actions
## 4. Validation fixes
- [x] 4.1 Fix fold validation to always permit folding (remove pre-flop restriction)
- [x] 4.2 Fix raise validation to correctly calculate minimum raise based on `lastRaiseAmount`
- [x] 4.3 Add validation for all-in actions that don't constitute a full raise
## 5. Betting round completion rewrite
- [x] 5.1 Implement `isRoundComplete` function with last-aggressor tracking logic
- [x] 5.2 Rewrite `completeBettingRound` to use `betMatched` flag and exclude all-in players from match check
- [x] 5.3 Implement BB option: allow BB to check pre-flop when no raises occurred
- [x] 5.4 Ensure `currentTurn` advances correctly after round completion
## 6. Side pot implementation
- [x] 6.1 Implement `calculatePots` function to compute main pot and side pots from player bets
- [x] 6.2 Integrate side pot calculation into all-in action handling
- [x] 6.3 Update `awardPot` to distribute main pot and all side pots correctly
- [x] 6.4 Fix remainder chip distribution (award leftover chips to first winner)
- [x] 6.5 Update showdown logic to determine winners for each pot based on eligibility
## 7. Turn advancement fixes
- [x] 7.1 Rewrite `advanceTurn` to skip folded and all-in players correctly
- [x] 7.2 Ensure turn advancement respects dealer position and betting round start position
- [x] 7.3 Handle edge case where no active players remain for turn advancement
## 8. Game loop rewrite (+page.svelte)
- [x] 8.1 Add `aiActing: boolean` state flag to disable controls during AI turns
- [x] 8.2 Replace `processGame` with unified `processTurn` state machine function
- [x] 8.3 Ensure all state transitions apply returned state atomically (no discarding)
- [x] 8.4 Convert AI turn timing from nested setTimeout to sequential promise chain
- [x] 8.5 Add guard clause in `handleAction` to reject actions when `aiActing` is true
- [x] 8.6 Update BetControls component to accept and respond to `disabled` prop
## 9. Bug fixes discovered during playtesting
- [x] 9.1 Fix deadlock: `completeBettingRound` sets `currentTurn` to first active player instead of hardcoded `dealerPosition + 1`
- [x] 9.2 Simplify `processTurn` to use corrected `currentTurn` directly after round completion
## 10. Testing & verification
- [ ] 10.1 Test pre-flop betting round with all action combinations (check, call, raise, fold)
- [ ] 10.2 Test single all-in scenario verifies correct main pot and side pot creation
- [ ] 10.3 Test multiple all-ins at different levels verifies correct multi-side pot distribution
- [ ] 10.4 Test BB option pre-flop (BB checks when no raises)
- [ ] 10.5 Test full hand flow from deal through showdown with no state corruption
- [ ] 10.6 Test race condition prevention (rapid human clicks during AI turn are rejected)