CPSC 312 Project: Texas Hold'em

From UBC Wiki


Eric Xie, Youssef Farag, Xiaojie Li

What is the problem?

Texas hold’em is a classic gambling game, a variation of the card game of poker. Our goal is to implement a user versus computer version of this game using Haskell, taking advantage of the simplicity of functional programming. Most other implementations of Texas Hold'em found online involve a large number of for-loops and complex algorithms for identifying the best possible hand (https://codereview.stackexchange.com/questions/1382/texas-holdem-in-java and https://github.com/omarshammas/pyPoker-Texas-HoldEm/blob/master/holdem.py). We believe Haskell's strong typing and convenient list comprehensions would handle such cases quite well.

What is the something extra?

We made a basic but challenging AI against the player, which reacts based on the strength of its hand. Although generating computer actions were discussed in class, we found that this AI did not require very sophisticated reactions to become a worthy opponent. Since poker is stochastic rather than deterministic, developing an AI to win everytime is quite difficult; however we have shown that it is feasible to design an AI that will challenge the player, and believe this can be improved upon easily to produce an AI that can match the skill of experienced poker players, without having to "cheat" (ie see player hand).

What did we learn from doing this?

We learned to develop a large world program from scratch, navigating Haskell's IO type and learning to use it effectively. We designed our own implementation of the game based on our understanding of it, creating types like BigState and SmallState to represent a game and a round respectively, in addition to a whole host of other defined types. We used these types (Card, Suit, Combo, etc.) to design a simply implemented game, and implemented short and sweet functions for these types. Although Haskell's strong typing was difficult to use at times (we found error messages to be difficult to parse), adhering to its requirements allowed our code to be clearer and better structured, if a little more difficult to read. We also learned to use Haskell's built-in list functions and list comprehension to replace for-loops and manual iterating over short lists. This all taught us the value of functional programming, forcing us to tackle problems using pattern-matching, recursion and built-in functions rather than for-loops and multi-line definitions.