So, it is time for the next project for my Artificial Opponents class. This time, the game is Gin Rummy. Time to make a plan, I guess.
First off, Gin Rummy is a card game. In other words, it is a “game” you play with “cards.” Like many a card game, you cannot see the opponent’s hand. More importantly, the hand size (10 cards) is quite large – I’ll explain why this is important a bit later.
So I started doing some research to get some ideas of where to go with a card game AI. That led me to a few different places:
- Heuristics – One way to play is to assume that other players will attempt to make the most optimal choices, and then try to gain information and make choices based on this fact. For example, in Gin Rummy, you are trying to minimize your deadwood. So, if a player discards a card (and they are playing optimally), then one could theorize that this might be one of their higher cards. Ultimately, this is a strategy that can be combined with others, as I’ll talk about later on.
- Monte Carlo methods – In the context of game AI, Monte Carlo methods usually refer to using a tree search combined with simulating a bunch of possible games (and their outcomes) to pick the optimal move in a game. I’m not sure how useful that would be here, since (as I’ll mention further on) Gin Rummy is a game where the players have a lot of incomplete information, as opposed to a game like chess or tic-tac-toe (where both players have complete information about the board and each other).
- Minimax – Minimax is a method to choose the option that will minimize the loss of the player in a worst-case scenario. I initially counted this one out at first, since (like the Monte Carlo methods) it seems like you would need more information than Gin Rummy provides to the players. However, I then stumbled across this Stack Overflow post, which seems to suggest that, in a card game with incomplete information, you can build up and gather knowledge as the game progresses and then start using minimax.
As I previously mentioned, what we’re working with is incomplete information. In most multiplayer board games (such as chess, checkers, etc.), both players know everything about the board and position of each other’s pieces. In most multiplayer card games, however, there is at least some hidden information. For example, in blackjack, the dealer’s hand – as well as the cards that have not been played – are unknown.
But, while we may not know the other player’s hand, we do have a few tools at our disposal to gain knowledge:
- Likelihood of opponent knocking – While we do not know what is in our opponent(s) initial hand, we do know what cards they remove from their hand, as well as whatever cards they add to their hand from the face-up discard pile. So, at the very least, we can try to keep a running total of their deadwood. If we see them pick up several cards of the same rank, then perhaps they have just created a set, and we can subtract the total of those cards from our approximation of their deadwood. This could be useful if you want to make sure you will not be undercut by your opponent.
- Opponent’s choice of card to pick up – Every turn, a player must pick up a card, either from the discard pile or from the face-down pile of remaining cards (the “stock”). Since the discard pile is face-up, if the opponent does not choose from the discard pile but rather from the stock, then we can make a safe bet that their hand does not contain anything relevant to the card on top of the discard pile. This allows us to (potentially) grow our knowledge of the opponent’s hand as the game progresses.
- Card counting – This is probably the strategy I will make the most use of in this project. Since human memory isn’t holding us back, it will be very easy to count cards. Starting off, we already know our hand, so right off the bat that’s 10 cards that we know will not appear in the “stock” (the face-down pile of remaining cards next to the discard pile). Next, we know every card that both us and our opponent(s) discard, so as the game goes on, our knowledge of what could possibly be in the “stock” (or the opponent’s hand) improves. I think that this will be a very effective tool, and I’ll be testing out a few different card-counting methods to see which one will work best in the context of this AI.
So, those are a few strategies I’ll be attempting to incorporate. It seems like I’ll be doing a lot of trying to gather information about the remaining cards and the opponent’s hand. At the end of the day, knocking early seems to be the best strategy (unless your opponent can undercut you), but I’ll have to test that, I guess.
– “David Hartman”