CSC 162 Freecell Project

Spring 2010

Your task in this, the first programming project of the semester, is to complete the implementation of (a minimalist version of) the familiar Freecell game.  The game comes pre-installed on all versions of Microsoft Windows; a quick Internet search will reveal free versions for other platforms as well. 

Summary of the Game

Freecell is a solitaire game (a single-person puzzle) played with a standard deck of European playing cards.  The 52 cards (ace, 2–10, jack, queen, and king of hearts, clubs, diamonds, and spades) are dealt out into eight “piles”—four of seven cards each, four of six cards each, as shown at right in the screensnap of Microsoft’s implementation. 

At the top left of the playing field are four “nooks” that provide temporary storage for one card each.  At the top right are four “homes” on which cards of the various suits can be piled, starting with the ace and proceeding upward in numeric order. 

Play proceeds by moving cards one at a time.  (Standard versions of the game often provide shortcuts for multi-card moves.  You are welcome to implement these for extra credit, but you are not required to do so.)  The goal of the game is to stack all 52 cards in the home positions.  Almost all starting positions are solvable. 

To move a card, click on a pile, highlighting the top-most card (the one at bottom of the screen), or on a nook, highlighting (selecting) the single card there (if any).  Then click on a destination location; the selected card should move there if permitted. 

A card can be moved from a nook or from the top of the pile (bottom-most position).  It cannot be moved from a home.  A card can be moved to

  1. an empty nook
  2. a home, if the card is an ace and the home is currently empty, or if the top-most card already in the home is the next lower value of the same suit
  3. a pile, if the pile is empty, or if the top-most card already there is the next higher value of a suit of the opposite color.  (Hearts and diamonds are red; clubs and spades are black.) 

Details

Picture of provided Freecell graphics

We’re providing you with an initial version of the code that contains a framework for a possible solution.  If you start it up you’ll see a playing field similar to the one at right. 

The framework uses the graphics.py package developed by John Zelle for his Python Programming:  An Introduction to Computer Science, the textbook used last fall in CSC 161.  This package is simple and easy to use, but has some limitations.  In particular, when you are not in the middle of a getMouse() call, the graphics window may not respond correctly to certain normal events.  On my mac, it doesn’t rise in front of other windows when I click on it.  Feel free to switch to a more full-featured package (e.g., turtle or tkinter graphics) for extra credit. 

To run the framework, start IDLE and make sure both graphics.py and freecell.py are somewhere where it can find them (if you don’t know how to do that, read the documentation or ask one of the TAs).  Type execfile("freecell.py") in the console window.  The graphics window will open (closing any previously open instance), and the following five functions will be available to call. 

play()
Starts play.  Resets cards to starting position if any of them has been moved.  Should now accept mouse clicks to initiate moves (but doesn’t—you have to implement this). 
shuffle(s)
Re-shuffles the cards and returns to starting position (but does not start play).  If parameter s is specified, uses this to “seed” the pseudo-random number generator, so you get a particular, repeatable shuffle.  If s is omitted, picks a new random shuffle. 
clear()
Erases all cards from the field. 
deal()
Returns all cards to the starting position (using the current shuffle). 
close()
Closes the graphics window.  To reopen, run execfile again. 

Read the provided framework carefully.  Pay particular attention to the nook, home, and pile classes.  These all provide a set of four methods whose implementations you must complete.  (If you don’t like this way of organizing the game, you’re also free to come up with another structure; this is just a suggestion.) 

pick(self)
Highlights the topmost card in this region, if any, and returns it, providing one would be allowed to move this card according the rules explained above.  Raises the InvalidMove exception if there is no topmost card, or if moving it is not allowed. 
pop(self)
Removes the topmost card; returns nothing.  Should not be called when there is no topmost card, or when moving it is not allowed. 
push(self, c)
Attempts to add card c to the region as the topmost card.  Raises InvalidMove if this move is not allowed. 
clear(self)
Removes all cards from the region.  This is for reinitialization. 
The intent is that the first mouse click of a move should pick a card; the second click should push the card and then pop it from its previous location.  If InvalidMove is raised, the highlighted card, if any, should be deselected, and the move should start over.  The pop is performed last so it happens only after the pick and push have both proven to be successful. 

Finally, you’ll need to flesh out the code for play().  I created the framework by building a complete solution and then removing code.  Each of the omissions is marked with a YOUR CODE HERE comment. 

Reminder

Please read the grading standards web page carefully and follow its instructions.  In particular, note that you will need to create a README.txt or README.pdf file, and you will need to turn your code in using Blackboard. 

Extra Credit Suggestions

For extra credit (counted at the end of the semester; may raise your final grade), you might consider the following possibilities. 

Due Date:  Thurs., Feb. 4 at 12:00 noon; no extensions.


Last Change:  23 April 2011 / Michael Scott's email address