Skip to content

Commit

Permalink
Merge #136
Browse files Browse the repository at this point in the history
136: Improve names r=charleskawczynski a=charleskawczynski

This PR:
 - Changes the game `state` to `stage` (for now). We'll want to add a proper game state (#132)
 - Add docs to clarify distinction between the player seat number, index, cyclic index and non-cyclic index. This really helps improve readability and simplicity since sometimes we used `id`, `state` `i_circ` (`circle_index`).

Next, we can apply similar name improvements to the transactions section.

Co-authored-by: Charles Kawczynski <kawczynski.charles@gmail.com>
  • Loading branch information
bors[bot] and charleskawczynski committed Jul 18, 2023
2 parents dce6344 + b18ee2a commit 263c805
Show file tree
Hide file tree
Showing 11 changed files with 185 additions and 168 deletions.
14 changes: 7 additions & 7 deletions src/TexasHoldem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ A no-limit Texas Holdem simulator.
# Terminology
- `game` a single "game", where players are dealt hands,
winner(s) are declared once.
- `state` a point or process in the game, including
- `stage` a point or process in the game, including
`PreFlop`, `Flop`, `Turn`, `River`.
- `round` the process of each player deciding which
actions to take, until no further actions are taking.
Expand All @@ -17,15 +17,15 @@ using PlayingCards
using PokerHandEvaluator
using Printf

export AbstractGameState, PreFlop, Flop, Turn, River
export AbstractGameStage, PreFlop, Flop, Turn, River

include("custom_logger.jl")

abstract type AbstractGameState end
struct PreFlop <: AbstractGameState end
struct Flop <: AbstractGameState end
struct Turn <: AbstractGameState end
struct River <: AbstractGameState end
abstract type AbstractGameStage end
struct PreFlop <: AbstractGameStage end
struct Flop <: AbstractGameStage end
struct Turn <: AbstractGameStage end
struct River <: AbstractGameStage end

include("player_types.jl")
include("players.jl")
Expand Down
48 changes: 24 additions & 24 deletions src/game.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function Game(
players::Players;
deck = PlayingCards.MaskedDeck(),
table = nothing,
dealer_id::Int = default_dealer_id(),
dealer_pidx::Int = default_dealer_pidx(),
blinds::Blinds = Blinds(1,2),
logger = StandardLogger(),
)
Expand All @@ -44,7 +44,7 @@ function Game(
else # nobody has been dealt yet
table = Table(players;
deck=deck,
dealer_id=dealer_id,
dealer_pidx=dealer_pidx,
blinds=blinds,
logger=logger,
)
Expand All @@ -60,15 +60,15 @@ end
players_at_table(game::Game) = players_at_table(game.table)
blinds(game::Game) = blinds(game.table)
any_actions_required(game::Game) = any_actions_required(game.table)
state(game::Game) = state(game.table)
stage(game::Game) = stage(game.table)
move_buttons!(game) = move_buttons!(game.table)

print_game_state(table, state::PreFlop) = @cinfo table.logger "Pre-flop!"
print_game_state(table, state::Flop) = @cinfo table.logger "Flop: $(repeat(" ", 44)) $(table.cards[1:3])"
print_game_state(table, state::Turn) = @cinfo table.logger "Turn: $(repeat(" ", 44)) $(table.cards[4])"
print_game_state(table, state::River) = @cinfo table.logger "River: $(repeat(" ", 43)) $(table.cards[5])"
print_game_stage(table, stage::PreFlop) = @cinfo table.logger "Pre-flop!"
print_game_stage(table, stage::Flop) = @cinfo table.logger "Flop: $(repeat(" ", 44)) $(table.cards[1:3])"
print_game_stage(table, stage::Turn) = @cinfo table.logger "Turn: $(repeat(" ", 44)) $(table.cards[4])"
print_game_stage(table, stage::River) = @cinfo table.logger "River: $(repeat(" ", 43)) $(table.cards[5])"

set_preflop_blind_raise!(table::Table, player, ::AbstractGameState, i::Int) = nothing
set_preflop_blind_raise!(table::Table, player, ::AbstractGameStage, i::Int) = nothing
function set_preflop_blind_raise!(table::Table, player::Player, ::PreFlop, i::Int)
if 1 i length(players_at_table(table))
if is_first_to_act(table, player)
Expand All @@ -78,8 +78,8 @@ function set_preflop_blind_raise!(table::Table, player::Player, ::PreFlop, i::In
end
end
end
reset_round_bank_rolls!(game::Game, state::PreFlop) = nothing # called separately prior to deal
reset_round_bank_rolls!(game::Game, state::AbstractGameState) = reset_round_bank_rolls!(game.table)
reset_round_bank_rolls!(game::Game, stage::PreFlop) = nothing # called separately prior to deal
reset_round_bank_rolls!(game::Game, stage::AbstractGameStage) = reset_round_bank_rolls!(game.table)

# TODO: compactify. Some of these cases/conditions may be redundant
function end_of_actions(table::Table, player)
Expand Down Expand Up @@ -150,22 +150,22 @@ function all_raises_were_called(table::Table)
end, players)
end

end_preflop_actions(table, player, ::AbstractGameState) = false
end_preflop_actions(table, player, ::AbstractGameStage) = false
function end_preflop_actions(table::Table, player::Player, ::PreFlop)
cond1 = is_big_blind(table, player)
cond2 = checked(player)
cond3 = still_playing(player)
return all((cond1, cond2, cond3))
end

function act_generic!(game::Game, state::AbstractGameState)
function act_generic!(game::Game, stage::AbstractGameStage)
table = game.table
players = table.players
logger = table.logger
table.winners.declared && return
set_state!(table, state)
print_game_state(table, state)
reset_round_bank_rolls!(game, state)
set_stage!(table, stage)
print_game_stage(table, stage)
reset_round_bank_rolls!(game, stage)

any_actions_required(game) || return
play_out_game(table) && return
Expand All @@ -176,15 +176,15 @@ function act_generic!(game::Game, state::AbstractGameState)
@cdebug logger " not_playing(player) = $(not_playing(player))"
@cdebug logger " all_in(player) = $(all_in(player))"
not_playing(player) && continue # skip players not playing
set_preflop_blind_raise!(table, player, state, i)
set_preflop_blind_raise!(table, player, stage, i)
if end_of_actions(table, player)
break
end
all_in(player) && continue
@cdebug logger "$(name(player))'s turn to act"
player_option!(game, player)
table.winners.declared && break
end_preflop_actions(table, player, state) && break
end_preflop_actions(table, player, stage) && break
if i > n_max_actions(table)
error("Too many actions have occured, please open an issue.")
end
Expand All @@ -193,8 +193,8 @@ function act_generic!(game::Game, state::AbstractGameState)
@assert all_raises_were_called(table)
end

function act!(game::Game, state::AbstractGameState)
act_generic!(game, state)
function act!(game::Game, stage::AbstractGameStage)
act_generic!(game, stage)
reset_round!(game.table)
end

Expand All @@ -219,7 +219,7 @@ function play!(game::Game)
initial_∑brs = sum(x->bank_roll(x), players)

@cinfo logger "Initial bank roll summary: $(bank_roll.(players))"
did = dealer_id(table)
did = dealer_pidx(table)
sb = seat_number(small_blind(table))
bb = seat_number(big_blind(table))
f2a = seat_number(first_to_act(table))
Expand All @@ -230,9 +230,9 @@ function play!(game::Game)
@assert still_playing(big_blind(table)) "The big blind button must be placed on a non-folded player"
@assert still_playing(first_to_act(table)) "The first-to-act button must be placed on a non-folded player"

@assert dealer_id(table) small_blind_id(table) "The button and small blind cannot coincide"
@assert small_blind_id(table) big_blind_id(table) "The small and big blinds cannot coincide"
@assert big_blind_id(table) first_to_act_id(table) "The big blind and first to act cannot coincide"
@assert dealer_pidx(table) small_blind_pidx(table) "The button and small blind cannot coincide"
@assert small_blind_pidx(table) big_blind_pidx(table) "The small and big blinds cannot coincide"
@assert big_blind_pidx(table) first_to_act_pidx(table) "The big blind and first to act cannot coincide"

table.transactions = TransactionManager(players)

Expand Down Expand Up @@ -289,7 +289,7 @@ function reset_game!(game::Game)
players = players_at_table(table)

game.table = Table(players;
dealer_id=dealer_id(table),
dealer_pidx=dealer_pidx(table),
blinds=table.blinds,
logger=logger,
)
Expand Down
4 changes: 2 additions & 2 deletions src/player_options.jl
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ function player_option!(game::Game, player::Player)
end

# By default, forward to `player_option!` with
# game state:
# game stage:
player_option!(game::Game, player::Player, option) =
player_option!(game, player, state(game.table), option)
player_option!(game, player, stage(game.table), option)

#####
##### Human player options (ask via prompts)
Expand Down
41 changes: 39 additions & 2 deletions src/players.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,47 @@
"""
Players
A collection of players. This collection may
be a Tuple or a vector:
(player[1], player[2], player[3])
[player[1], player[2], player[3]]
These indices correspond to the player index (`pidx`).
Both the player's seat number and index
must be unique, but they need not be equal:
pidx : (player[1], player[2], player[3])
seat_number.(players): ( 6 , 3 , 2 )
Also, the seat number need not be consecutive
when sorted, whereas the player indexes must
be consecutive when sorted.
Since players are allowed to have different
composition, we provide iterators over the
players index, rather than the players
themselves, for type-stability.
"""
struct Players{PS<:Union{Tuple,AbstractArray}}
players::PS
end

"""
cyclic_player_index(::Players, pidx)
cyclic_player_index(n_players, pidx)
A circular index for indexing into `players`.
`pidx = 1` corresponds to `player[1]`.
"""
cyclic_player_index(players::Players, i) =
cyclic_player_index(length(players.players), i)
cyclic_player_index(n_players, i) = mod(i-1, n_players)+1

Base.length(p::Players) = length(p.players)
Base.iterate(players::Players, state = 1) =
Base.iterate(players.players, state)
Base.iterate(players::Players, ncpidx = 1) =
Base.iterate(players.players, ncpidx)
Base.@propagate_inbounds Base.getindex(players::Players, i::Int) =
Base.getindex(players.players, i)
Base.filter(fn, players::Players) = Base.filter(fn, players.players)
Expand Down
Loading

0 comments on commit 263c805

Please sign in to comment.