CS 107 (Spring '11)
[Schedule] [Programs] [Notes & Reference] [Examples][Syllabus] [Lab & TA] [Tests] [Grades]

Program #4: Mystery 21

Prof. Reed, CS 107, Spring 2011
Due Monday 3/14 at 12:00 noon

Description and points breakdown added 3/9 and is shown in blue below.

Write a Java application to implement a card trick using 21 randomly selected cards. The interface looks like the following, where the "card" selected by the user is r9 (which stands for red 9), and user input is shown in bold:

Author: Dale Reed 
Program #4: Mystery 21 
February 7, 2011

Welcome to the 21 card mystery... 

Choose a card at random and remember it. 
Then follow the instructions on the screen. 

The deck is: 
 r1  r2  r3  r4  r5  r6  r7  r8  r9 r10 r11 r12 r13 
 b1  b2  b3  b4  b5  b6  b7  b8  b9 b10 b11 b12 b13 
 g1  g2  g3  g4  g5  g6  g7  g8  g9 g10 g11 g12 g13 
 y1  y2  y3  y4  y5  y6  y7  y8  y9 y10 y11 y12 y13 
After shuffling, the deck is: 
 r4  r5  r8  r2 b12  g6  y4  y7  r9  g2  y6 g13  y2 
y11  r3  g1  b2 r10  b4  b7  g8 r11 g11  y3 r12  g4 
b13  r7  g3  b6 y13  g7  b9  r1  g9  b3 g10 g12  y8 
 y1  b1  g5 y10  y5 r13  r6 b10  y9 b11  b8  b5 y12 

Selecting the first 21 cards in the deck: 

Shuffled cards are: 
 r4  r5  r8  r2 b12  g6  y4 
 y7  r9  g2  y6 g13  y2 y11 
 r3  g1  b2 r10  b4  b7  g8 

Think of one of the cards and remember it.  Press enter when you're ready.

To make it harder for me I'm going to reshuffle the cards, but first
I need a little help, since my mind-reading powers are limited.
In the table above, which row (1, 2, or 3) is your card in? 2

Shuffled cards are: 
 r3 r10  g8  g2  y2  r5 b12 
 g1  b4  y7  y6 y11  r8  g6 
 b2  b7  r9 g13  r4  r2  y4 

Your mind is starting to become a bit clearer. Let me try to find the color.
In the table above, which row (1, 2, or 3) is your card in now? 3

Shuffled cards are: 
 g1  y6  g6  r9  r2 r10  y2 
 b4 y11  b2 g13  y4  g8  r5 
 y7  r8  b7  r4  r3  g2 b12 

I think I know now, but just to be sure, one last time. 
Center your thoughts on your card. 
Which row (1, 2, or 3) is your card in now? 1

Shuffled cards are: 
 b4 g13  r5  g6 r10  r8  r3 
y11  y4  g1  r9  y2  b7  g2 
 b2  g8  y6  r2  y7  r4 b12 

Aha! Got it. I placed your card in the center of the board.  Your card is:  r9
Press enter to exit the game...

So what's the trick? On each step where the user identifies the row of cards containing the selected card the program must put that row in between the other two rows as the cards are "picked up." Then, the cards are re-dealt into 3 new rows, where the top card becomes the first card in the first row, the second card becomes the first card in the second row, the third card becomes the first card in the 3rd row, the 4th card becomes the second card in the first row, the 5th card becomes the second card in the second row, and so on. On the third iteration (as shown above) the users card is guaranteed to be in the middle of the board!

You need to know the following concepts in order to write this program:

Everything from the previous assignments; Objects and Classes, and the Shapes example that uses classes for Square, and Circle along with the Canvas class; Arrays.


  1. Getting Started: Create a project directory called Mystery21.

  2. I recommend you write this program in stages as follows. You don't have to follow this sequence, it is just a recommendation. If you don't plan on creating a graphical user interface, then you don't need to use the sample files at all. The breakakdown of the 55 points for execution is also given:
    1. (45 points) Write the main functionality of your code inside the Constructor of Board.java. You can eliminate all the fancy drawing stuff for now and concentrate on getting the text-based interface to work. If you are not planning on implementing the graphical part, then just create your own single java file (again call it Board.java) similar to the starting point from program #3. I suggest you also use the Square class to implement storing each card, though you could simply use an array of Strings if you are not planning on implementing the graphical part.

      1. (5 points) Create 52 "cards" to start off. Instead of suits (Spades, Hearts, Diamonds, Clubs) we will be using colors (red, green, blue, yellow). Instead of the jack, queen, king and ace cards we will simply number each suit from 1 to 13. To do this you could create 52 variables of type Square, but instead I recommend that you create an array of size 52 Squares. After doing this you will need to allocate memory for each Square. Since for now you will not be displaying each Square, the size and location don't really matter. This will look something like:

        // create the array of 52 cards
        Square[] cardDeck = new Square[ 52]; 

        // Now allocate memory for each of the cards, initializing the values for each.
        // Since we are not displaying the square (for now) set x,y to 0 and size to 40 for all // and set visibility to false. We DO care about the color and the label. // Constructor for Square should have: int x, int y, int theSize, String theColor, boolean visibility, String theLabel cardDeck[ 0] = new Square( 0,0, 40, "red", false, "1"); // red 1 cardDeck[ 1] = new Square( 0,0, 40, "red", false, "2"); // red 2 cardDeck[ 2] = new Square( 0,0, 40, "red", false, "3"); // red 3 ... cardDeck[ 12] = new Square( 0,0, 40, "red", false, "13"); // red 13 // now start the 13 green cards cardDeck[ 13] = new Square( 0,0, 40, "green", false, "1"); // green 1 cardDeck[ 14] = new Square( 0,0, 40, "green", false, "2"); // green 2 ...
        and so on through the green cards and for the 13 blue and 13 yellow cards. If you think about it a little bit you should be able to do the above code using a loop rather than having 52 individual statements.

      2. (5 points) Write the code to display all the cards. To do this go through the array of Square and display each one. After displaying 13 of them, print a new line character so that you end up with 4 rows of 13 "cards" each. I suggest you modify the toString() method so that each card gets printed out in exactly 3 spaces using the first letter of the color as well as the card label. for cards whose number is < 10 (that is the number is a single digit) I suggest you prepend an extra space, so that everything lines up visually in columns. To pull out the first character of the color use something like:
        // get first character of the color for the card at index 2 in the array
        Square theSquare = cardDeck[ 2]; // get the square String theColorString = theSquare.getColor(); // get the color of the Square as a String char theColor = theColorString.charAt( 0); // get the first character of the color

        // or do the above steps all in one line as: char theColor = cardDeck[ 2].getColor().charAt( 0);
      3. (5 points) Now "shuffle" the deck of cards. To do this use a random number generator to get two random numbers (call them index1 and index2) between 0 and 51, storing them into int variables. These are the two card positions that will be swapped. To swap them you can just change the references (the addresses, the pointers to those Squares) at those positions in the array, such as:
        Square tempSquare = cardDeck[ index1];  // keep track of address of first card
        cardDeck[ index1] = cardDeck[ index2];  // make address of index1 point instead to the index2 card
        cardDeck[ index2] = tempSquare;         // make address of index2 point to the Square that originaly was at index1 
        You will need to do this multiple times in a loop many times so that the deck is "shuffled."

      4. (10 points) We now need to choose 21 cards to work with for the trick. Since the deck has already been shuffled, simply choose the first 21 cards (from index values 0 ..20) and copy them over into another array, say it could be called selectedCards.

        // copy over first 21 cards into new array
        Square[] selectedCards = new Square[ 21];
        for( int i=0; i<21; i++) {
             selectedCards[ i] = cardDeck[ i];    // copy the address from the card deck
        Print out this array of 21 cards, similar to how you printed out the whole deck previously, except now you just print out 3 rows of 7 cards each.

      5. (15 points) Now we start going through the process of having the user choose a card and then we reorder the cards. This will be done 3 times, after which the user's chosen card will be the middle card of the middle row. On each of the 3 times the user indicates which row their card is in. The trick is to make sure that "row" is placed in the middle of the other two "rows." There are different ways to do this. One way is to create a second array of 21 cards (e.g. cardsCopy) used to copy over values, one "row" at a time. Depending on which row the users card is in determines which row gets copied over first, which one second, and which one third.

      6. (5 points) Presto, after doing the above step 3 times the selected card is in the middle of the middle row, which is the 11th card in the array, which is at index position 10 since we start the index values at 0.

    2. (10 points) Create a graphical user interface to play the game using colored squares on the Board. Download the following files into the Mystery21 directory: Canvas.java, Square.java, MouseAndKeys.java, Board.java. Alternatively get all these at once in Files.zip You will substantially be changing the code shown in Board.java. You should create a new class called CardDeck that should be able to make an Array containing 52 cards, 13 each of red (r), green (g), blue (b) and yellow (y). The CardDeck class should also have a method for shuffling the cards (by choosing random cards and swapping them) and a method to return an array of the first 21 cards in the deck. If you created methods in writing your solution from the previous steps, then you should be able to reuse all your code so far. Note that you will not get any credit for the graphical version unless the text-based version also works. The user input should still come from the console window, just as in the text-only version.

  3. Turnin your program electronically into Blackboard into the Program 4 assignment.

[CS Dept] [UIC] [Prof. Reed]