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:

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.

Notes:

Getting Started: Create a project directory called Mystery21.

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:

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

(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:

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.

(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 arraySquare 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);

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

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

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.

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

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

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

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