Gin Rummy is a game. Or is it?
So, anyway, here’s how my initial implementation of my Gin Rummy AI turned out.
So my general approach was to do a few things:
- keep in mind that the other AI players will be watching your moves – So, when picking up a card, don’t choose it unless you are quite certain it will be helpful. Secondly, when discard a card, don’t be predictable
- knock as fast as possible
- keep track of which cards are in play
- t r i a n g l e s – triangles are a particular group of three cards that has a high chance of becoming a meld. A triangle is comprised of:
- 1st card: an initial card
- 2nd card: a card which is the same value as the initial card
- 3rd card: a card which is same suit as 1st card and is +1 or -1 in value in comparison to the initial card
- middle cards have the best chance of either being part of a meld or adding to a meld
- summary: only draw a card from the discard pile if it completes a meld, completes a triangle, or is a middle card. Otherwise, draw from the deck
- keep high cards for the first one or two turns, then get rid of them ASAP
- this is the section that needs the most tweaking. I implemented a few different ways to choose the card to discard, but I’m not quite sure when to implement each. Here are the strategies:
- The aforementioned high-card strat: this is only active for the first one or two turns, so I’m not too concerned about this one.
- Possible cards strat: for this strategy, I go through all the cards in my hand and check, for each card, how many partial melds they are a part of (2-card runs and sets), then check to see if the cards needed to complete those incomplete melds are in play. I calculate a score for each and discard the one with the lowest score (the lowest potential, in a sense).
- Next player strat: for this strategy, I keep track of every card that the next player (the player whose turn follows mine) has picked up and discarded. Then, I try to discard the card that will help this opponent the least, since their turn follows mine and they have the opportunity to pick up my discard.
GinAI – This class contains all my logic for discarding a card, drawing a card, keeping track of the next player’s discards and draws, etc. Check out some of the important functions:
- card tracker
- adjustCardStatus(Card card, bool isInPlay) – I have a few maps that I use to keep track of every card in the deck and whether or not it is in play. Obviously I can’t be 100% certain about every card, but I can at least know the status of certain cards: cards buried in the discard pile, cards discarded by players, and cards drawn by players (from the discard pile). Since I’m using maps, all I have to do is call find() on the maps and pass in the card suit (to one of the maps) and the card value (to the other map) and then change a bool.
- drawing/discarding functions
- chooseCardToDiscard() – This implements the discarding logic/”algorithms” I discussed above.
- checkIfCompletesMeld(Card card) – Checks if the passed-in card completes a meld or adds onto an already-existing meld.
- checkIfCompletesTriangle(Card card) – Checks if the passed-in card completes a “triangle” (explained above).
- Checking melds
- getAmountOfSameValue(Hand hand, Card card) – Checks to see if the passed-in card completes or adds onto a set.
- getAmountInRun(Hand hand, Card card) – Checks to see if the passed-in card completes or adds onto a run.
- getSet(Hand hand, Card card) – Returns the largest possible set in your hand (complete or incomplete) containing the passed-in card.
- getRun(Hand hand, Card card) – Returns the longest possible run in your hand (complete or incomplete) containing the passed-in card.
CardCounter – So I set this up when I was trying to see if Blackjack-style card counting would have any merit in Gin Rummy. I’m pretty sure that this style doesn’t work for Gin Rummy, and right now this class is not incorporated into my AI at all. I might resurrect it to try out a different style of card counting, though.
I tested it a few times:
- First test: when discarding, 30% high card strat, 30% possible cards strat, 30% next player strat
- Second test: when discarding, 50% high card strat, 50% possible cards strat
I didn’t test it too thoroughly, but at the moment, the second version gave me the best results: a 33.3% win rate rather than a 15% win rate
I feel like I’ve set up a lot of systems, and now it all comes down to tweaking their usages and adding logic to make the best use of the system. Right now, my AI does decently, but I feel like it could do better. Hopefully I’ll be able to get a better win rate by the time the final submission is due.