In my last post, I introduced some new art assets into the game related to the stock card, and I added a visual effect for when you hover a card over a foundation when playing with the `outline` option checked on.
The game is definitely starting to look a lot more like the original Solitaire. However, there is still some polish needed on the UI, and of course, some missing features such as the right-click `autoplay` feature, and the grand finale feature for when the player wins the game. I'm so looking forward to that feature.
For the past 3-4 weeks, apart from some architectural adjustments to the code base, I worked on the undo feature. The undo feature lets you undo the last move that was played in the game, and of course, the score that was associated with the move. Performing an undo also has a cost associated with it, so your score will take a small hit of two points.
Originally, I had overlooked how the `Draw Three` game mode worked behind the scenes. Initially, each card was on it's own layer similar to how the `Draw One` game mode works, however, this implementation caused a bunch of edge case issues that I was not willing to hack, so I took a step back and I re-designed the Draw Three feature from the ground up to work properly this time.
Furthermore, whenever you click on the stock, I did not realize that the three cards currently shown would then be positioned in an overlapping fashion, I thought and had implemented it so that those cards would be hidden, and when you had no more cards left to drag, you would show the three cards `behind` your hand. This implementation was wrong, so I corrected it.
This correction required me to associate each set of three cards with their own unique layer and position. Since JLayeredPane natively supports these two concepts, it wasn't as difficult to adapt my code to work like this. A few areas of the code that are difficult to do are things like knowing which position within the layer the card is in so that you can apply the correct x-axis offset. Being able to distinguish between the last card in a set of three cards being dragged out, and knowing that if there is no collision, that it needs to be played back on its own layer, not on the layer `now` being shown.
Suffice to say, the undo now works very well, with a few bugs encountered here and there that have been logged.
Here is the list of possible undoable actions.
1. Clicking on the stock can now be undone. This will revert the cards being shown to the previous set of cards, depending on the game mode (Draw One vs. Draw Three).
2. Moving a card from the Talon can now be properly undone.
3. Moving a card from the Foundation can now be properly undone.
4. Moving a card from the tableau can now be properly undone.
5. Performing an undo will also remove the score that was associated with that move. Furthermore, performing an Undo will result in a loss of two points.
6. You can only undo your last valid move.
7. Clicking on a card that has its back shown cannot be undone, so you will lose the ability to undo for the previous move prior to that.
Apart from the undo feature, there were some lingering bugs that I wanted to solve. Here is the list of bugs that were fixed.
1. Fixed an issue related to the deck images being imported into a low-res fashion.
2. Fixed an issue where the foundation view would highlight when there was already a card on that foundation, and another card was being dragged over it.
3. Fixed an issue where dragging a card from the talon to the foundation would cause the dragged card to not be shown properly
4. Fixed an issue where dragging a king along with other cards onto an empty pile would cause the cards to not be properly displayed.
5. Fixed a bug where restarting the stock deck would cause previous cards to still be shown and not properly aligned when playing in `Draw Three` game mode.
6. Fixed an issue where dragging a card from the talon in `Draw Three` would not position the card back in the right place on the talon if there was no valid collision detected.
The next feature that I am implementing is the `auto-complete` feature where you right click on the board and all available valid moves are automatically performed for you. Once this is done
I will work on churning out all the bugs and the remaining UI changes that have to be done.
Once the game is stable, I will implement the final task, the `game win` animation that we all absolutely loved to watch when we were kids (and still today) when the game was won.
You can always follow my progress by following the game located at https://github.com/danielricci/solitaire and if you have any questions I will do my best to answer them.
Take care, until my next blog post.