feat: tournament rake, percentage-based prizes, and finish position fixes

- Add tournament_rake_percentage field to GameConfig (house share of entry fees)
- Convert prize structure from absolute amounts to percentages of prize pool
- Fix finish position calculation for tournament eliminations (was inverted)
- Add batch bustout processing for multi-table tournaments (shared positions)
- Add max_rebuys field and rebuy_count tracking on Seat
- Add PrizeStructure::with_rake() and rake_amount field
- Accumulate stats across tournament series (hands, rake, profit)
- Add best_finish and prize_won fields to PlayerStats
- Replace floating-point prize math with integer arithmetic (chip conservation)
- Add comprehensive tests for prize distribution and finish positions
- Update config examples to use percentage-based prizes with rake
- Add ARCHITECTURE_TOURNAMENT_RAKE.md documentation
This commit is contained in:
Jan-Peter von Hunnius 2026-05-22 14:32:24 +02:00
parent c041cde3fe
commit 7c79ae4966
10 changed files with 1506 additions and 140 deletions

View file

@ -15,9 +15,12 @@ num_hands = 10000
# reset_bankroll_each_hand = false
# bankroll_refill_threshold = 1000 # Refill when stack <= 1000
# Auto-rebuy: when enabled, players whose stack drops below half the
# Auto-rebuy: when enabled, players whose stack drops below 25% of the
# starting_chips are automatically topped back up to starting_chips.
# Configure the threshold via rebuy_threshold_percentage (default: 25).
# max_rebuys limits how many times a player can rebuy (0 = unlimited).
auto_rebuy = true
max_rebuys = 0 # 0 = unlimited rebuys
# Randomize seat assignments before each hand (optional, defaults to false).
randomize_seats = true

View file

@ -7,7 +7,8 @@
# (last player standing wins).
#
# 100 tournaments are run with aggregate statistics tracked by player name.
# Entry fee: 5 per tournament. Final table prizes: 200, 100, 50, 30, 20, 10, 10, 10, 10, 10.
# Entry fee: 5 per tournament. House keeps 5% rake.
# Prizes are percentages of the remaining prize pool.
[game]
game_type = "MultiTableTournament"
@ -22,15 +23,20 @@ num_blind_levels = 20
randomize_seats = true
num_tournaments = 100
# Tournament rake: house keeps 5% of entry fees.
# With 100 players: total_entry_fees = 500, house_rake = 25, prize_pool = 475
tournament_rake_percentage = 5
# ---------------------------------------------------------------------------
# Prize structure as percentages of prize pool (100 players × $5 = $500 total,
# minus 5% rake = $475 prize pool)
# ---------------------------------------------------------------------------
prizes = [40, 20, 10, 6, 4, 4, 4, 4, 4, 4]
[game.bet_limit]
type = "no_limit"
min_raise = 20
# ---------------------------------------------------------------------------
# Prize structure (100 players × $5 buy-in = $500 prize pool, top 10 paid)
# ---------------------------------------------------------------------------
prizes = [200, 100, 50, 30, 20, 10, 10, 10, 10, 10]
# ---------------------------------------------------------------------------
# Blind levels (extended to 12 levels)
# ---------------------------------------------------------------------------

View file

@ -6,7 +6,11 @@ buy_in = 11
randomize_seats = true
num_tournaments = 100
# Custom prize structure in chip amounts: 1st=5, 2nd=3, 3rd=2
# Tournament rake: house keeps 10% of entry fees.
# With 10 players: total_entry_fees = 110, house_rake = 11, prize_pool = 99
tournament_rake_percentage = 10
# Custom prize structure as percentages of prize pool: 1st=50%, 2nd=30%, 3rd=20%
prizes = [50, 30, 20]
[game.bet_limit]