University of Calgary

Solitaire: Double or Quits

Solitaire: Double or Quits
source: Katrin Becker, 2000



Assignment Links:

SAMPLE GAME (visual)
Sample Run: (typescript)

Classes you can use:



Goals, Skills and Concepts:
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:
Double or Quits:

Typical layout:
Tableau
(blue)
Tableau
(blue)
Tableau
(blue)
Hand
Pile
(green)
Waste
Pile
(purple)
Tableau
(blue)
Tableau
(blue)
Tableau
(blue)
Foundation
(red)
Tableau
(blue)
Rules: Double or Quits

To Play: The deck is shuffled and then cards are dealt out to the blue waste piles (just one card to each pile). The next card is dealt to the red foundation and whatever it is will be the starting card for the game. Suit is unimportant for this game and cards are to be laid down in the following order: A, 2, 4, 8, 3, 6, Q, J, 9, 5, 10, 7, A, etc. 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 blue wastepiles can only hold one card at a time and when the card is moved from one of these waste piles it is replaced with the next available card from the top of the purple waste pile. If that is also empty, the next card is taken from the hand.

As cards are dealt they may be placed on any of the 7 tavbleaus, the wastepile, or the foundation if appropriate. Once placed on a wastepile, they can not be moved except to the foundation.

The following shows the typical layout of a game.


Specifications:
    1. Need to be able to detect and represent an empty stack.
    2. Only one card at a time may be moved.
    3. The Hand, Foundation, and Wastepile must be stacks. The tableaus need not be.
    4. The piles must be represented internally but only the 'top' card must displayed. - we can't look ahead in the piles anyway.
    5. The Hand can only be used for dealing (always 1 card at a time).
    6. Wastepiles can serve as both sources and destinations.
    7. The Hand Pile may only be a source.
    8. 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 PlayDQ.
 
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:
    1. 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)
    2. Create the stack functions [as a separate module - feel free to use the Deck class or myStack]
    3. Fill the deck [in sorted order]
    4. Create the main module and Game Driver
      1. remember to implement 'quit' function now
    5. TEST - using "stubs" for functions not yet implemented (stubs are functions with no statement part yet)
    6. Create the "deal" function
    7. TEST
    8. Create the "move" function
    9. TEST
    10. Create the "shuffle" function
    11. TEST
    12. Write the "play" function
    13. TEST

Display:
Our version will look much like this:
gromit% PlayDQ
Welcome.... we're playing Double or Quit today.

       Choices:
 p                   === Play 
 m <s> <s#> <d> <d#> === Move
 d                   === Deal
 h                   === Help
 q                   === Quit
     |----------------|
     | Double or Quit |
     |----------------|
     |       t1 t2 t3 |
     | H  W  t4    t5 |
     |       t6  F t7 |
     |----------------|
     | A24836QJ95T7A. |
     |----------------|
     |                |
     |       SQ H9 HA |
     |                |
     | ST -- H3    DQ |
     |                |
     |       D6 D4 C4 |
     |                |
     |----------------|

=> 
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], Wastepile [W], Tableaus [T#]
If the source is T, then it must be followed by a number <s#> from 1-7 identifying which wastepile
<d> means one of the destinations: Wastepiles, or Foundations, which must also be followed by a number <d#> 1-7 identifying which one you mean if it is a tableau.
 
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
- use a simple arithmetic formula to "calculate" the next legal card rather than looking it up in a list [after all, the game is called Double or Quit]
- 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 in Deck Class
  • 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 or a move to a tableau that's not empty)
  • OK (doesn't quit or blow up) on reference to "bad piles" (i.e. <s> or <d> other than H W T F)
  • permits 3 rounds (three ONLY times through the cards in the hand)
  • 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 foundation, etc.)
  • detects game over ( i.e. Round 3; 0 or 1 card left in Hand and none of the available cards can be moved onto the foundation)
 
Testing:
The Test Deck:
At least half of the 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":
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:
    1. [up to 4 points] check for and deny invalid requests (request typed wrong: eg. S T1 T2 when it should be S 1 2)
    2. [up to 4 points] keep score
Challenges:
    1. [ up to 10 points] add a graphical display
    2. [ up to 6 points ] tolerates all input without blowing up
    3. [ up to 10 points ] detects blocked state correctly (i.e. there is no longer any way to win this game). Warning: this one's a bit tough for this game. Verifying this is no picnic either.



Updated: August 9, 2005 05:18 PM