In my last journal, I talked about setting up the scoring system. I put that separate from the actual Hand because I don’t necessarily think it needs to be in there. I want to keep everything in the Hand that absolutely must be there.
I found that when this happens to me, it really helps to write things down on paper with pens like a savage.
For some reason, typing things out on my computer does not have the same cognitive resolution as physically writing things out and sketching them. I can use different colors for different things. It’s not super organized, but when I am trying to organize my thoughts, there is nothing better.
At first I was trying to figure out what properties I needed in my class. Then I realized that I was approaching things wrong. I had to think about what this class has to do rather than figuring out what I need first. If you want to cook, you figure out your recipe before you buy your ingredients.
The Hand class is basically a game loop. It plays out a hand of this game. It has to shuffle the cards and deal them to the players. It has to keep track of the current player and run a turn. If that turn does not end the game, it has to move to the next player and keep doing this until the hand ends.
This logic in pseudocode would look something like this:
// Deal Cards/Initialize // Game Loop: /* Continue: Bool isWin: Bool Reset Players While continue is true and deck > 0. Return an optional player. 1. Player plays a card 2. Card from the stack gets played 3. Computer checks for a match and distributes cards 4. Computer checks for a win 4a. If there is a win, the computer checks if someone else has called stop. If no, the computer asks the player if they want to go or stop. If yes, the loop ends. 5a. If the player calls stop, the loop ends 5b. If the player calls go, the computer moves to the next player and the game continues */
The loop needs to know if it continues or not. This is complicated by the game mechanic of the player being able to keep playing once they accumulate enough points to win. If a second player accumulates enough points to win after a first player has already called Go, the second player does not have the option to continue the game. This variable does not need to persist outside of the loop function, so I can make its scope confined to the loop.
The same is true with the isWin variable. We don’t care if someone has called Go after the hand is over.
It’s possible for no one to win the hand. If a player calls Go and accumulates no more points but the game plays to the end, then there could be no winner. The Game class that is going to create instances of this Hand class in its own game loop needs to know if there was a winner, and if so, who. The Player class (now) has a property that tracks how many points the player has. So when the hand is over if someone is a winner, that player gets passed back to the Game class that can check the property on the winner to distribute the chips. If a new hand is played, then these properties are reset and the game continues. This may not be the best way to organize things, so it may be refactored later.
Now that I know what the loop looks like, I can create my pseudocode of the methods that will be called by this loop:
// Game Logic // Play a card (pass in an array) // Check for Match // Distribute cards // Check for win // Reset Players
I need to figure out what gets passed into these functions and what are mutable properties of the Hand class. However, this was far easier to figure out after I wrote out all the steps that the game loop needs to implement on each given turn.
Since I have a better understanding of what this class will do, figuring out what properties I need is simple:
// Properties /* 1. Players 2. Current Player 3. Shuffled Deck 4. Cards on Board 5. Draw Pile */
I know this doesn’t look super exciting. I haven’t written any “real” code, but I have made things a lot easier for myself whenever I pick this back up again. I can noodle around with this for 15 minutes every now and then and fill in all of these methods. I have broken this complicated piece of programming logic down into manageable tasks.
I might pull those methods called by the game loop out into functions like I did with the scoring to make it easier to test them. I can create non-random arrays to use for test data without having to create a whole instance of a Hand class where that property will always change.
Anyway, it always feels good to get anything done on this. An application is just an incredibly long series of small tasks. Doing a little every day results in progress. I’ll take it.