Simple Solitaire Game
Four Seasons
source: Katrin Becker, 2002
- CONTENTS of THIS PAGE...
- Goals, Skills & Concepts, Introduction & Background, Description, Specifications, Approach + Hints + HELP, Display, Minimal Requirements, ('C' version), ('B' version), ('A' Version), Testing and Marking, Bonuses, Challenge
-
- Goals, Skills and Concepts:
- implementation of simple stacks
- menu-driven interactive programs
- more introduction to games
- problem decomposition
- Introduction to OO Design
- Program Testing
- Introduction and Background:
- There are 100's of variations on Solitaire. The basic goals of all are the same: Solitaire is a single player card game using one or more decks of standard playing cards. The player is to lay out and play cards according to the rules of the variation given with the goal of getting all the cards played to the foundations. Cards can be moved from play to the foundations in various orders but by far the most common is to have one foundation for each suit and to have cards placed there in consecutive (increasing) order by rank.
- Our Job: Write a program that will allow you to play solitaire. Since we are not yet ready to deal with animation or fancy graphics the "display" will be entirely text based and each play will require that the "screen" be re-drawn (i.e. output will scroll).
-
-
- Description:
- Four Seasons:
- played with one deck
- 4 foundations (places where we are trying to place cards according to specified order)
- 5 + 1 wastepiles (places where cards can be placed until they are ready to be used)
- 1 handpile (source of cards not yet played - usually placed face-down)
Typical layout:
|
|
|
|
Foundation
|
|
|
|
|
Waste Pile
|
Waste Pile
|
|
|
Foundation
|
|
Foundation
|
-
Rules: http://www.solitairecentral.com/rules/fs_rules.html
To Play: The deck is shuffled and then cards are dealt out to the blue waste piles (forrming a cross - one card to each pile). The next card is dealt to the upper left red foundation and whatever rank it is will be the starting card of all suits. All cards placed on the same foundation must have the same suit. Rank will increase by one (i.e. 3 goes on 2; Queen goes on Jack, etc.). Ace is to be placed on top of the King as necessary. The remainder of the deck is placed, face down on the hand pile.
Cards are dealt from the hand one at a time. Each time a card is dealt, it is first turned over onto the hand pile and then moved to another pile (the default is to move it to the purple waste pile).
At any point in the game, cards may be moved from any waste pile or from the hand to any other wastepile; as long as the card is the next lower in rank. On the wastepiles, suit doesn't matter and Kings cannot be placed on Aces.
As cards are dealt they may be placed on any of the 4 wastepiles or a foundation if appropriate. Once placed on a wastepile, they can not be moved except to other wastepiles or the foundations.
- The following is a series of snapshots of a typical game. It shows what the game looks like at the beginning, how cards can be placed on the wastepiles, and how cards can be moved to the foundations, either directly from the hand or from the wastepiles. This particular game ends with the played "blocked" (no more cards to deal and no more legal moves). As usual, the game wins.
-
 |
 |
After the cards are shuffled and dealt the top left corner cards indicates that all foundations will start with 10 for this game. The other 5 cards are moveable. One happens to be another 10 so we can put it on a new foundation. I also put the 5[hearts] on the 6[clubs] to make room for other plays.
|
 |
 |
| I turn up a Queen and move it onto my 'tableau' because I'm guessing I'll be able to use it soon. I leave the Queen[clubs] for the moment and move the 7[spades] into the middle, move the 6[diamonds] on top of it. Now I have a space for the queen[clubs] and the next card I turn up is a 5[spades] which gets moved to the middle. I can't do anything with the 6[spades] but the next card is another foundation card. |
 |
 |
Now I finally have the last foundation, I can move it and then start moving the Clubs I have collected: the Jack, the Queen under it; the King; the Ace; etc.
|
 |
 |
|
Now I finally have the last foundation, I can move it and then start moving the Clubs I have collected: the Jack, the Queen under it; the King; the Ace; etc.
|
 |
At this point the game is blocked and I can make no further moves.
|
- Specifications:
- Need to be able to detect and represent an empty stack.
- Only one card at a time may be moved.
- The Wastepile are also stacks (every pile is a stack).
- The piles must be represented internally but only the 'top' card must displayed. - we can't look ahead in the piles anyway.
- The Hand can only be used for dealing (always 1 card at a time).
- Wastepiles can serve as both sources and destinations.
- The Hand Pile may only be a source.
- Foundations may only be destinations.
- Approach & Hints + HELP:
Classes you can use: Debug.java, MyRand.java, Card.java, Deck.java, Documentation
- Cards may be represented as follows:
-
- C = Clubs; S = Spades; D = Diamonds; H = Hearts
- A = Ace; 2-9 as themselves; T= 10; J = Jack; Q = Queen; K = King
-
- This way every card can be represented in 2 characters. The most straight-forward way to represent a deck internally is using the integers 0-51. Each number can easily be mapped onto a suit { C, S, D, H } and a rank { A, 2, 3, 4, 5, 6, 7, 8, 9, T, J, Q, K }. Each Pile of cards is to be implemented as a proper stack.
-
- There is a working version of this Solitaire Game in the course directory (~becker/Courses/233/A3). You are free to play with it. It is called Play.class.
-
- A minimal acceptable solution will NOT check whether requests or requested moves are legal.
-
- The variation of Solitaire you are to implement is a relatively simple one using one deck of cards and allowing only one card to move at a time.
-
- A possible plan of attack:
- Create the data structures (stacks) for cards and decide on how to represent cards both internally and externally (these 2 forms of representation need not be the same)
- Create the stack functions [as a separate module - feel free to use myStack]
- Fill the deck [in sorted order]
- Create the main module and Game Driver
- remember to implement 'quit' function now
- TEST - using "stubs" for functions not yet implemented (stubs are functions with no statement part yet)
- Create the "deal" function
- TEST
- Create the "move" function
- TEST
- Create the "shuffle" function
- TEST
- Write the "play" function
- TEST
- Display:
- Our version will look much like this:
gromit% java Play
Welcome.... we're playing Four Seasons today.
Choices:
p === Play
m <s> <s#> <d> <d#> === Move
d === Deal
h === Help
q === Quit
|----------------|
| Four Seasons |
|----------------|
| f1 +1 f2 |
| H W +2 +3 +4 |
| f3 +5 f4 |
|----------------|
| Start: Q |
|----------------|
| |
| SQ H9 -- |
| |
| ST -- H3 D6 DQ |
| |
| -- D4 -- |
| |
|----------------|
=>
|
- User Options:
- Play (i.e. start again); command: p
- Move a card from source to destination; command: m <s> < s#> <d> <d#>
- Deal (deal the next card; command: d
- Help (display the rules); command: h
- Quit (end game); command: q
-
- Note: <s> means one of the source piles: Hand Pile [H], Wastepiles [W]
- If the source is W, then it must be followed by a number <s#> from 1-4 identifying which wastepile
- <d> means one of the destinations: Wastepiles, or Foundations, which must also be followed by a number <d#> 1-4 identifying which one you mean.
-
- Requirements & Grading:
- Notes on Marking:
- We will be looking for the usual good, clean design; documentation, etc. as always.
- In order to pass it must work. (Some marks will be given to all *reasonable* attempts, working or not)
- Specifics we will be looking for when marking:
- - menu-driven (like sample solution; format may be different)
- - external documentation not necessary but must have "Help" option in menu
- - uses pre-determined hand as well as a random one
- - test wrap-around on the Foundations (so a lower rank card can be placed on higher rank card as appropriate)
- - uses Stacks for Foundations, Waste, and Hand
- - detects (and denies) attempt to take a card off an empty stack
- - shuffles deck in a reasonable manner
- - use of globals for stacks, score is OK
- - if you are asked to submit on paper, make sure the testing is well-annotated
-
- Sample Run: (this goes through an entire game)
-
- 'C' Version:
- A minimal acceptable solution will NOT check whether requests or requested moves are legal.
- readable output
- shuffles the deck correctly // GIVEN
- handles requests in upper/lower case, with/without blanks
- handles a deal ('d' option)
- allows moving cards (when VALID moves are tested ONLY - no promises about invalid or illegal moves)
- implements test deck ( 'z' option )
- 'B' Version:
- check for and deny requests for invalid moves (invalid source/destination, such as a move to the Hand deck)
- OK (doesn't quit or blow up) on reference to "bad piles" (i.e. <s> or <d> other than H W F)
- detects win
- allows a re-start ('p' option, continued), even in the middle of a game - which abandons the current game and begins a new game
- 'A' Version:
- check for and deny requests for illegal moves (trying to move the wrong card to an empty foundation, trying to place a 10 on a 6 on the tableaus, etc.)
- detects game over ("pseudo-blocked", i.e. 0 or 1 card left in Hand and none of the available cards can be moved onto a foundation - note: this does not always mean the game is over)
-
- Testing:
- The Test Deck:
- Most configurations of cards result in games that can't be won. This one of the reasons people find these games challenging and entertaining. The likelihood of winning increases with practice and skill, but there remains an element of chance. this is another reason people like playing.
- Both of these attributes of Solitaire however make it difficult (not to mention time consuming) to properly test a computer program to play the game. Various aspects of the program can be tested on any "deal":
- initial game laid out correctly
- general game play
- game allows only one card to be moved at a time
- game allows only "legal" moves
- moves from wastepiles allowed only to foundations
- game tolerates references to non-existent piles (i.e allows user to try again)
- playing a losing game to completion
But testing is not complete until a winning hand has been played. Rather than wait until a winning hand has actually been dealt (and playing all the games in between) what we will do is create a "stacked deck". Under normal circumstances the deck will be shuffled randomly. We will create a new, hidden game option called "test" (z) that will fill the deck with a pre-determined winning hand.
This is a common approach to program testing. Many games include special options that cause the game to proceed in predictable ways. The developers include them so they can properly test all aspects of the game. [aside: professionally produced games are amongst the most thoroughly tested software products available; space (as in NASA) stuff too] Often, these options are left in the game when it goes into production. Game players know these as "cheat codes".
This technique is also used in many other kinds of programs to test them. Data is "cooked" and supplied to the program (sometimes the program is "force-fed" like in our Solitaire game). This way the tester can predict what the output should be and what the program should do and then verify whether or not it actually did what it was supposed to.
- BONUSES:
- [up to 4 points] check for and deny invalid requests (request typed wrong: eg. S T1 T2 when it should be S 1 2)
- [up to 4 points] keep score
- Challenges:
- [ up to 10 points] add a graphical display
- [ up to 6 points ] tolerates all input without blowing up
- [ up to 10 points ] detects blocked state correctly (i.e. there is no longer any way to win this game). Warning: this one's tough for this game. Verifying this is no picnic either.