Skip to content

Commit

Permalink
Merge #103
Browse files Browse the repository at this point in the history
103: Fix re-raises using initial min raise amt (not 2x) r=charleskawczynski a=charleskawczynski

Closes #102.

Co-authored-by: Charles Kawczynski <[email protected]>
  • Loading branch information
bors[bot] and charleskawczynski authored Sep 24, 2021
2 parents a50dd38 + 34ca221 commit ad2ac85
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 17 deletions.
1 change: 1 addition & 0 deletions src/game.jl
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ function set_preflop_blind_raise!(table::Table, player::Player, ::PreFlop, i::In
if is_first_to_act(table, player)
# everyone must call big blind to see flop:
table.current_raise_amt = blinds(table).big
table.initial_round_raise_amt = blinds(table).big
end
end
end
Expand Down
10 changes: 8 additions & 2 deletions src/player_actions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,15 @@ for a more verbose but simpler implementation.
"""
function valid_raise_bounds(table::Table, player::Player)
cra = current_raise_amt(table)
irra = initial_round_raise_amt(table)
mra = minimum_raise_amt(table)
rbr = round_bank_roll(player)
max_orbr = max_opponent_round_bank_roll(table, player)
@debug "determining valid_raise_bounds"
@debug " rbr = $rbr, max_orbr = $max_orbr"
@debug " cra ≈ 0 = $(cra 0)"
@debug " max_orbr > rbr = $(max_orbr > rbr)"
lim = cra 0 ? blinds(table).big : 2*cra
lim = cra 0 ? mra : (cra+irra)
vrb = custom_clamp(min(max_orbr, rbr), lim)
@assert vrb[2] vrb[1] "Min valid raise bound must be ≤ max valid raise bound."
return vrb
Expand Down Expand Up @@ -238,10 +240,14 @@ function raise_to_valid_raise_amount!(table::Table, player::Player, amt::Real)
table.current_raise_amt = amt

push!(player.action_history, Raise(amt))

players = players_at_table(table)
if all(player -> !player.last_to_raise, players)
table.initial_round_raise_amt = amt
end
player.action_required = false
player.last_to_raise = true
player.checked = false
players = players_at_table(table)
for opponent in players
seat_number(opponent) == seat_number(player) && continue
not_playing(opponent) && continue
Expand Down
6 changes: 6 additions & 0 deletions src/table.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ mutable struct Table
state::AbstractGameState
buttons::Buttons
current_raise_amt::Float64
initial_round_raise_amt::Float64
transactions::TransactionManager
winners::Winners
play_out_game::Bool
Expand Down Expand Up @@ -103,6 +104,7 @@ function Table(;
state = PreFlop(),
dealer_id = default_dealer_id(),
current_raise_amt = Float64(0),
initial_round_raise_amt = blinds.small,
transactions = nothing,
winners = Winners(),
play_out_game = false,
Expand All @@ -121,6 +123,7 @@ function Table(;
state,
buttons,
current_raise_amt,
initial_round_raise_amt,
transactions,
winners,
play_out_game,
Expand Down Expand Up @@ -182,6 +185,8 @@ observed_cards(table::Table, ::Flop) = table.cards[1:3]
observed_cards(table::Table, ::Turn) = table.cards[1:4]
observed_cards(table::Table, ::River) = table.cards
current_raise_amt(table::Table) = table.current_raise_amt
initial_round_raise_amt(table::Table) = table.initial_round_raise_amt
minimum_raise_amt(table::Table) = blinds(table).small

state(table::Table) = table.state

Expand Down Expand Up @@ -328,6 +333,7 @@ function reset_round!(table::Table)
player.last_to_raise = false
player.round_contribution = 0
end
table.initial_round_raise_amt = blinds(table).small
table.current_raise_amt = 0
end

Expand Down
48 changes: 34 additions & 14 deletions test/call_raise_validation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,36 @@ TH = TexasHoldem

function valid_raise_bounds_simple(table::Table, player::Player)
cra = TH.current_raise_amt(table)
irra = TH.initial_round_raise_amt(table)
rbr = TH.round_bank_roll(player)
max_orbr = TH.max_opponent_round_bank_roll(table, player)
if cra 0 # initial raise
bb = TH.blinds(table).big
mr = TH.minimum_raise_amt(table)
if max_orbr > rbr # at least one opponent can cover `player`'s all-in
if bb > rbr
if mr > rbr
vrb, case = (rbr, rbr), 1
else
vrb, case = (bb, rbr), 2
vrb, case = (mr, rbr), 2
end
else # raise limited by opponent's bank roll
if bb > max_orbr
if mr > max_orbr
vrb, case = (max_orbr, max_orbr), 3
else
vrb, case = (bb, max_orbr), 4
vrb, case = (mr, max_orbr), 4
end
end
else # re-raise
if max_orbr > rbr # at least one opponent can cover `player`'s all-in
if 2*cra > rbr
if (cra+irra) > rbr
vrb, case = (rbr, rbr), 5
else
vrb, case = (2*cra, rbr), 6
vrb, case = ((cra+irra), rbr), 6
end
else # raise limited by opponent's bank roll
if 2*cra > max_orbr
if (cra+irra) > max_orbr
vrb, case = (max_orbr, max_orbr), 7
else
vrb, case = (2*cra, max_orbr), 8
vrb, case = ((cra+irra), max_orbr), 8
end
end
end
Expand All @@ -44,7 +45,7 @@ end

@testset "valid_raise_bounds" begin
# Case 1
table = Game((Player(Bot5050(), 1; bank_roll=1), Player(Bot5050(), 2))).table
table = Game((Player(Bot5050(), 1; bank_roll=0.5), Player(Bot5050(), 2))).table
players = TH.players_at_table(table)
table.current_raise_amt = 0
@test valid_raise_bounds_simple(table, players[1]) == (TH.valid_raise_bounds(table, players[1]), 1)
Expand Down Expand Up @@ -95,33 +96,52 @@ end
@testset "is_valid_raise_amount" begin
players = (Player(Human(), 1), Player(Bot5050(), 2))
table = Game(players).table
@test TH.is_valid_raise_amount(table, players[1], 0) == (false, "Cannot raise 0. Raise must be between [\$2, \$200.0]")
@test TH.is_valid_raise_amount(table, players[1], TH.bank_roll(players[1])+1) == (false, "Insufficient funds (\$200.0) to raise \$201.0. Raise must be between [\$2, \$200.0]")
@test TH.is_valid_raise_amount(table, players[1], -1) == (false, "Raise must be between [\$2, \$200.0]")
mra = TH.minimum_raise_amt(table)
@assert mra == TH.blinds(table).small
@test TH.is_valid_raise_amount(table, players[1], 0) == (false, "Cannot raise 0. Raise must be between [\$$mra, \$200.0]")
@test TH.is_valid_raise_amount(table, players[1], TH.bank_roll(players[1])+1) == (false, "Insufficient funds (\$200.0) to raise \$201.0. Raise must be between [\$$mra, \$200.0]")
@test TH.is_valid_raise_amount(table, players[1], -1) == (false, "Raise must be between [\$$mra, \$200.0]")

@test TH.is_valid_raise_amount(table, players[1], TH.bank_roll(players[1])-1) == (true, "")
@test TH.is_valid_raise_amount(table, players[1], TH.blinds(table).small) == (false, "Raise must be between [\$2, \$200.0]")
@test TH.is_valid_raise_amount(table, players[1], TH.blinds(table).small) == (true, "")
@test TH.is_valid_raise_amount(table, players[1], TH.blinds(table).big) == (true, "")
@test TH.is_valid_raise_amount(table, players[1], TH.bank_roll(players[1])) == (true, "")

players = (Player(Human(), 1), Player(Bot5050(), 2))
table = Game(players).table
table.initial_round_raise_amt = 20.0
table.current_raise_amt = 20.0
players[1].round_contribution = 200
players[1].round_bank_roll = 500 # oops
@test TH.is_valid_raise_amount(table, players[1], 200) == (false, "Cannot contribute \$0.0 to the pot.")

players = (Player(Human(), 1), Player(Bot5050(), 2))
table = Game(players).table
table.initial_round_raise_amt = 10.0
table.current_raise_amt = 10.0
players[1].round_bank_roll = 20
@test TH.is_valid_raise_amount(table, players[1], 10) == (false, "Only allowable raise is \$20.0 (all-in)")

players = (Player(Human(), 1), Player(Bot5050(), 2))
table = Game(players).table
table.initial_round_raise_amt = 10.0
table.current_raise_amt = 10.0
players[1].round_bank_roll = 20
@test TH.is_valid_raise_amount(table, players[1], 20) == (true, "")

players = (Player(Human(), 1), Player(Bot5050(), 2))
table = Game(players).table
table.initial_round_raise_amt = 5.0
table.current_raise_amt = 20.0
players[1].round_bank_roll = 30
@test TH.is_valid_raise_amount(table, players[1], 25) == (true, "")

players = (Player(Human(), 1), Player(Bot5050(), 2))
table = Game(players).table
table.initial_round_raise_amt = 5.0
table.current_raise_amt = 20.0
players[1].round_bank_roll = 30
@test TH.is_valid_raise_amount(table, players[1], 22) == (false, "Raise must be between [\$25.0, \$30.0]")
end

@testset "call_amount" begin
Expand Down
2 changes: 1 addition & 1 deletion test/play.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ end

@testset "Game: Play (BotBetSB) - breaks lowest allowable bet" begin
game = Game((Player(BotBetSB(),1), Player(BotCheckCall(),2)))
# Cannot raise small blind on pre-flop, must raise at least big-blind
# Cannot raise small blind on pre-flop! The big blind is the raise min raise, so we must raise at least big-blind
@test_throws AssertionError("Raise must be between [\$4.0, \$200.0]") play!(game)
end

Expand Down

2 comments on commit ad2ac85

@charleskawczynski
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/45535

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.1.0 -m "<description of version>" ad2ac853b9b5ab9ecc2186e8931149661b0e4af3
git push origin v0.1.0

Please sign in to comment.