Continued…
In the last post, I introduced my command line poker game. With the poker logic completed, I could set my sights on the more interesting aspects of my command line poker game. The seconds half of development will include improving gameplay and graphics.
But First…
With the codebase growing to over 800 lines of code, not including any of the graphics or gameplay, it was time to reorganize. This being my first C project, I decided to try out a relatively standard C development pipeline.
Makefile
The first aspect of a C project is the make file. The make file allows us to easily compile all of the C files by just typing “make”. This allows me to rapidly test without lengthy compile flags for things like include directories.
Header Files
I had decided to split my code into 4 modules: Deck, Logic, Rendering, and Game. the Deck, Logic, and Render modules will have header files, I also made a smaller header for all my pre-process commands. This decision made finding bugs and doing refactors much easier. When I wanted to change the render tooling, I only had to edit the render file and the implementation in the game file instead of scrolling through one giant intermingled heap of code.
With those two changes this is the final code structure:

(Note: The compile_flags.txt is for my neovim lsp to recognize the header files)
Successes
Like in the first half of the project I will outline the good and the bad of my progress.
Graphics
I was inspired by this video to create command line graphics for my poker game using ASCII escape sequences. After some initial testing I was able to get cards on the screen very fast.

I was even able to set up face down cards that are revealed at the end of the hand. While there are no fancy symbols for suit, The face cards are labeled as such and the card frame is pretty nice if I do say so myself.
Betting
You might have noticed in the screenshot above, there’s a new gameplay element… Betting! Poker wouldn’t be as fun without stakes. The fist element of betting is a persistent balance for all players. This was easy to implement as a int attribute in the player struct. Next is placing bets. I made a function that asks for a bet and then checks if the player has enough money. The player is stuck in a while loop until they enter a valid amount.
The hard part is the computers bet. For the sake of simplicity the computer is the dealer so the player always bets first. The computer generates a random number weighed by the bet the player placed. This is the threshold. Then the computer calculates how good it’s cards are. The first round is just based on the high cards. Every round after that checks for special hands. if the calculated value is higher than the random threshold, the computer matches. If it is 25% higher than the threshold, the computer raises 25%. If it is below the threshold, the computer folds.
If the computer decides to raise, the player has an opportunity to match the new bet or fold.

Failures
Also Graphics
While I love the way this game looks, there is one major design flaw. The display is not scalable. It will only take a certain amount of columns and rows. I tried to implement support for different window sizes, but I decided I’d rather just make the cards as small as possible to fit the majority of windows.
The Entire Game Module
The game module contains all the functions that interface with the player and the play_hand function. The play hand function is looped until the player says they don’t want to play anymore. The play_hand function contains shuffling, dealing, betting, evaluating. It is a Frankenstein(‘s monster) of all the different functions and modules throughout the project. It doesn’t read very well and there is some repeated code.
The Final Product
I am really happy with the way the game came out. Most of my quibbles stem from a code maintainability perspective. The gameplay is solid. With no non-standard libraries the code is super portable and fast. I learned so much about C from this project. My memory management and development environment configuration feel 10x stronger. If I were to restart I would think through the way I break down code a lot more. I could probably get rid of 200 lines of code with some optimization.

Leave a comment