University of Calgary

solitaire calculation

Simple Solitaire Game: Calculation
source: Katrin Becker, 1999
[HELP]
CONTENTS of THIS PAGE...
Goals, Skills & Concepts
Introduction & Background
Description, Specifications, Approach + Hints, Display, Minimal Requirements
('C' version), ('B' version), ('A' Version), Testing and Marking, Bonuses, Challenge
 
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.
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.
 
Web-Based Calculation Game(s):
This one is reasonably fast but the display is turned 90 degrees from the pictures shown below.
http://www.idiotsdelight.neet/calculation.html
This one has a reasonable display but requires a million cookies (sheesh! 8-P):
http://games.demo.ru/Cards/Calculation.exe

Description:
Calculation:
To Play: The deck is shuffled and when found during the shuffle, the following cards are placed on the foundations in the following order: Ace, 2, 3, 4. Suit is irrelevant in this game. The remainder of the deck is placed, face down on the hand pile.

Cards are dealt from the hand one at a time and MUST be played onto a wastepile or foundation before the next card can be dealt.

The goal is to build up cards on the foundations in the following sequence: [Suit is irrelevant.]

    1. Ace 2 3 4 5 6 7 8 9 10 J Q K [note card 'value' increases by 1 each time]
    2. 2 4 6 8 10 Q Ace 3 5 7 9 J K [note card 'value' increases by 2 each time]
    3. 3 6 9 Q 2 5 8 J Ace 4 7 10 K [note card 'value' increases by 3 each time]
    4. 4 8 Q 3 7 J 2 6 10 Ace 5 9 K [note card 'value' increases by 4 each time]
The first card in in each of the above sequences gets dealt from the hand before play begins.

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 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.


Note that at this point we can place the following cards: [w4] D2 on F3; [w4] C5 on F3; [W2] H8 in F3; [W1] DJ on F3; [w4] H3 on F4; [w4] C7 on F4; [w3] HJ on F4. The following picture shows the 'state' after these moves have been made and the next card is dealt from the hand. It gets place on W2, then a DQ and S3 turn up as well as another 9 and a Jack. They all get placed on various wastepiles and when the C4 turns up, it is placed directly onto F2; at which point we can move the 6 from W2 to F2. And so on...



Specifications:
    1. Need to be able to detect an empty stack.
    2. Only one card at a time may be moved.
    3. The Wastepile are also stacks.
    4. The Hand must be represented internally but only the 'top' card must displayed. - we can't look ahead in the hand pile 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:
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 (/home/233/Solitaire). You are free to play with it. It is called calculation.
 
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]
    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:
csb% ./calculation
Foundation 1: Ace 2 3 4 5 6 7 8 9 10 J Q K
Foundation 2: 2 4 6 8 10 Q Ace 3 5 7 9 J K
Foundation 3: 3 6 9 Q 2 5 8 J Ace 4 7 10 K
Foundation 4: 4 8 Q 3 7 J 2 6 10 Ace 5 9 K
SCORE: 4     
Hand : DJ      1  2  3  4
              -- -- -- --
              DA H2 C3 D4  :: FOUNDATIONS
                           :: WASTEPILES
              DQ C8 D3 ST
Options:
P: play new game
M: move <s> <s#> <d> <d#>
D: deal
H: help
Q: quit
Request: t
 
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
  • handles the first deal ('d' option)
  • allows moving cards (valid moves only)
  • implements test deck ( 'z' option)
'B' Version:
  • check for and deny requests for invalid moves (invalid source/destination)
  • 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-deal ('d' option, continued)
'A' Version:
  • check for and deny requests for illegal moves (trying to move from a Foundation, to the Hand, etc.)
  • detects game over ("blocked", i.e. 0 or 1 card left in Hand and none of the available cards can be played)
 
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":
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. check for and deny invalid requests (request typed wrong: eg. S T1 T2 when it should be S 1 2)
    2. use classes for stacks, cards, decks
Challenges:
    1. add a graphical display
    2. tolerates all input without blowing up



Updated: August 9, 2005 06:57 PM