I love to code on vacations. I particularly love to code things of no relation to my work, such as card games. And my favorite is FreeCell.
It seems odd to me that all the current excellent apps for this game are larger than 40 megabytes. Surely this can be done more efficiently, and that was my challenge.
Did you know FreeCell has a “literature?” You can visit it here on Wikipedia. I’ve tried to use the lingo it establishes.
(All the code described here is free and open source on GitHub.
A lot has changed since 2001 — HTML 5, CSS3, Unicode 6.0 with a full set of playing cards, so I first started a new version based on those characters here. They are pretty ugly, frankly, and don’t work at all on IOS.
So the current version — take two — creates cards as an array of inline SVG elements, using a smaller set of emoji for the suit signs and faces.
One-click FreeCell is fairly complicated. When you click on a column it needs to:
- Compute the maximum size column of cards you can move together (eg — red 10, black 9, red 8), based on the number of open FreeCells (nopen) and the number of empty cascades (nempty). That number turns out to be 1+nopen+nempty.
- Compute the height of the stack at the end of the cascade that can move together (reduced, if needed, by the maximum computed above).
- Run through the other cascades to see if they can receive the full stack.
- If not, try the stack reduced by one card, until you get down to 1 card.
- If not, try moving the stack to an empty cascade.
- If not, and there is an open FreeCell, move the last card there.
- Finally, see if any cards from the top of each cascade or from the FreeCells can jump to the foundation piles — repeating until none move.
To implement this, I created static HTML divs for the four FreeCells, four foundation piles for each suit and the eight cascades, using CSS Flex to space them evenly across the screen.
To establish the page as a to turn the finished page into a Progress Web App, I drew on the excellent “Hello World” PWA tutorial on Medium by James Johnson. I’m continuing to tinker with it, as the journey to make the code more elegant is the real destination. For instance, as of this writing, I’ve not yet created an “undo” feature which some FreeCell addicts like myself prefer over simply starting over.
Feel free to play the game at this link, and to suggest improvements on GitHub/jcoonrod.