Open Side Menu Go to the Top
Register
State Machines: Poker Time Machine State Machines: Poker Time Machine

09-01-2018 , 10:18 PM
I want to talk about hierarchical state machines, but taking the long way around by introducing a toy problem.

Scenario: A time machine has transported you back 20 years to Sept 1, 1998. Unfortunately the process has wiped your memory about future events so you can't get rich in the obvious ways. The one memory you have retained is there is an online poker boom coming and the way to get rich is to be the house.

You are a software engineer so the problem is design the server side for a poker table. Client apps will send you actions, you send things like cards & prompts. A hand history shows what your class should produce. The rules should be like PokerStars rules when Americans could play. Roughly what will you have?

Ignore the details of how communication occurs. You get events in and your output is a hand history. Somebody else worries about things like networking, security, how to deal with 10000 railbirds.

Starting with just limit holdem, 9 seats, cash. Although more is obviously coming.
State Machines: Poker Time Machine Quote
09-01-2018 , 11:28 PM
I'm not actually sure what your question is
State Machines: Poker Time Machine Quote
09-02-2018 , 12:10 PM
The question is make a class for a poker table. I start by thinking a table has a name, stakes, game type, and some seats.

class Table {
Table(string name, currency stakes, int game, int seat_count);
void OnEvent(Client player, EventType action, params...); // what the player wants to do
void Broadcast(string action); // another line in hand history for everybody watching
void SendPrivateMessage(Client player, string message); // send to one player
// lots more stuff
};

A poker table has a lot of state. It'll need to remember
hand number,
button location,
community cards[5],
current street,
seat action is on,
action deadline,

Lots of state to track per seat:
occupied? reserved?
name
chips
cards[]
cards visible?
disconnected?
time bank

and a deck of cards is needed which can be some other object / service


My question is how to organize the code to manage the state and events. The protocol of a hand is pretty complicated with lots of corner cases. You could try to make it linear like

PlayOneHand()
{
// get a hand number from db
// move button
// prompt for blinds
DealHoleCards()
BettingRound(preflop)
if (live_players.count() >= 2) {
DealFlop()
BettingRound(flop)
if (live_players.count() >= 2) {
DealTurn()
BettingRound(turn)
if (live_players.count() >= 2) {
DealRiver()
BettingRound(river)
}}}
Showdown()
AwardPots()
// record hand in db
}
State Machines: Poker Time Machine Quote
09-02-2018 , 01:15 PM
Ah, I see. Well, I've done it several times, but not object-oriented. Or maybe, semi-OOP. Like I think I had objects for "player" and "deck" and "table" but not like PokerGame - I just composed the little classes into a function based system.

I have always played a lot of different games, so from the get-go I built a system that would support nearly any arbitrary poker game. I did this by making sort of a meta-language that described how poker games were played, i.e. supporting draws and discards and betting rounds, etc. Then I made a system for essentially producing the next event from the current state and the game description. It's been a reallllly long time since I've looked at it but this is basically how it worked.

My system was for simulation, but it has the same basic requirements as writing a poker server, because I was interested in simulating strategies, so I would basically pit strategies against each other and simulate hand after hand. I was frustrated that most poker stats were based on all in equity, usually against a random range (this was pre-pokerstove or maybe about the same time). So I wanted to see how hand equities held up against players who were tight and passive, etc.

Here's a link to what my game description file looks like. It's probably relatively self-explanatory. The actual code to deal hands is probably messy as ****, it's been like 15 years since I wrote it, and I was interested in results more than perfection. It's written in a hybrid of C++ and tcl/tk (a scripting language, like perl or python)

https://gist.github.com/rustybrooks/...9eab6f5c0af2e4
State Machines: Poker Time Machine Quote
09-02-2018 , 01:16 PM
Even if you just make a holdem thing, it's better to make general stuff like "deal N cards to the board" or "deal K cards to players" than it is to make a dealflop/dealturn/dealriver (imo)
State Machines: Poker Time Machine Quote
09-05-2018 , 02:50 PM
I don't know if I would even use a state machine (let alone a hierarchical one) for such a task. (in my current job I have implemented both types but I don't see what you'd accomplish by using them in this context...model the system state between "working" and "error occured"...maybe? )

What's wrong with plain old OOP programming?
State Machines: Poker Time Machine Quote
09-06-2018 , 07:58 AM
Quote:
Originally Posted by RustyBrooks
I'm not actually sure what your question is
I don't think the OP is a question, more the thread is an introduction / tutorial to hierarchical state machines.

Which is very interesting!
State Machines: Poker Time Machine Quote
09-06-2018 , 02:10 PM
Yeah I'm still interested in this but I haven't had the brain space to try to work through the toy problem in any satisfying way
State Machines: Poker Time Machine Quote
09-07-2018 , 02:37 PM
one of my first object oriented exercises was to model a deck of cards. it was not intuitive but quite worthwhile to understanding oop principles and implementation. ofc, now I never use oop and its all functional but whatever.
State Machines: Poker Time Machine Quote
09-07-2018 , 03:10 PM
OOP just becomes a habit after a while. You look at a problem and break it into parts (different people will come up with different parts - there is no one 'perfect' breakdown for a problem)

- table
- seat
- player
- stack
- dealer
- pot(s)
- deck
- hole cards
- community cards
- 5 card hand
- hand comparer
- game
- streets
- ...

1) define what describe each one -> object data (a seat may have a number, a player has a stack object, etc.)
2) define the things each one can do by themselves -> methods (e.g. a player may have a 'timeout' method)
3) define the ways in which each one can interact with one of the others -> interfaces (the pot may have an interface that can be called by the player to put chips from his stack into the pot)

The advantage of the above is: I can now take all these objects and reuse them to model Badugi or PLO or Stud or whatever I want without having to write much in the way of additional code.
State Machines: Poker Time Machine Quote

      
m