Gin Rummy Post Mortem

Gin rummy was an interesting project. The original plan was extremely complicated and would be difficult to be made. After working on it for a while I realized that I made it over complicated. Upon this realization I found it could be simplified to checking scores. All that I really needed to do was discard the card that will leave you with the best score. The draw step would be based off if the discard would lower the overall score or not. Assuming it did you would draw it and then there was a fail safe to ensure you wouldn’t discard the card again.

Going from complicated to simple I realized how easy it is to overplan. It isn’t easy to be fully aware of everything you need before you start working, or even that you don’t need all you planned. I’m glad I discovered a simpler way, even if it didn’t change a lot of the code we were given. Before I found it I spent a lot of time making things to control the set up of the game, which my discovery made virtually pointless. It was still a good experience to have. After this assignment I realized it will be better to think of the simplest solutions first. It will be hard, but that will be a skill worth developing.

There isn’t much to say overall about the process. Compared to minesweeper the general idea flowed easier for me and it makes the next project seem exciting. As of now it is clear I have to be prepared for anything when it comes to an AI. The next project can only improve things as we move forward in this class.

Gin Rummy Code Review

Starting off with my code I tried a very complicated set up of checking for runs or sets and keeping them all in vectors. The code started off fairly simply, but escalated fast. By the time the DLL was tested in class all it would do is check for definite things and only that.

A lot of the code required for loops and sorting the hand early on, then sorting it differently and adding it to another. The core function being the populateHand function. In this function you were taking the hand putting it into two vectors, one for sets and sorted by value and the other for runs sorted by suit and value.

populate-hand
Create Your Own Hand to use throughout

The runCount and setCount functions are checking through to see if there are sets and runs in the current hand. It will check the full hand each where runCount has a a slightly more involved aspect to it than setCount.

The runCount function starts by retrieving the suit then as it continues checking if the next card value minus the current card value is equal to one (excluding the starting card) assuming it is it will keep track of the positions. Once it is finished checking the hand for that suit it will add the run to the run vector, IF there is three or more. Pictures of these functions can be seen at the end of the post.

The setCount function worked relatively similarly, but focused only on the values being the same. After setCount ran checkOverlap would remove anything in the run from the sets, along with the rest of the set members if there was less than three after one removal. After that draw would be decided by whether the discard could be added to a run or set, if not it chose to draw from the deck.

 

After a bit of testing I realized an easier way to achieve a similar idea.

draw
Draw from Deck or Discard Decision

Changing draw to factor in if the score went down did exactly as I needed with less work, although I left the checks there to be safe should the score not go down for some reason. After implementing this I realized discard could be simplified as well.

discard
Pick Discard

This way it removes the card that will leave the score lowest. Although these methods are simple it is a solid way to have an AI play this game. At the end you can simplify the DLL aspect to needing solely a function to draw and discard focused on just score changes. Improvements could be made, but for now this works strangely well and can win at a massive difference between this score focused AI and one with more detail.

 

runcount
RunCount Function
setcount
Set Count Function
overlap
Check Overlap between Runs and Sets (Favoring runs)

Gin Rummy Planning Post

In terms of thinking out this game the planning process is much easier. The biggest issue will be tracking the sets and runs during gameplay. The best plan will be to have sets of lists or arrays that hold the entire hand. Three will work best because you can hold the set and runs together and keep track of the cards that may lead to a set or run should  a card be drawn.

The most time consuming aspect will be taking the value of the available card on the discard pile and checking it with what you have. It shouldn’t be an incredibly difficult thing to decide, but it will take time. This AI just seems to work within my mind better making the planning process much smoother. The code will need to have a class for control of the player’s hand and from there all the information needed in the decision making should be relatively easy to make accessible.