Programming and Computer Science in Java:
Homework #19:
Group Assignment, Arrays and Cards
David Kosbie, 2002-2003

Due Date:  Wed, April 9, 2003

For this assignment, you are to do all the following problems working as a group.  You should use the perry2 mailing list for all of your correspondence.  Divide the work, help each other do the work, submit a single final version.

Hint:  please be certain to use perry2 extensively.  Not only will that help you in your group effort, but it will help me give each of you the right grade for your individual participation.

Question 1:  Subset Sums.  Write a Java program which reads in an integer N followed by N more integers. You are guaranteed that the sum of some of those numbers equals the sum of the rest of the numbers. Print out a line showing the correct equality (if there is more than one, any one will do). Always place the first number on the left-hand-side, and on both the left-hand and right-hand sides, list the integers in the same order as given in the input.   So, if the input is 4 3 8 6 2 9, your output must be 4 + 3 + 9 = 8 + 6 + 2.

Hint: first, store all the numbers in an array (of course). After that, this problem really reduces to finding all the possible SUBSETS of a set with N elements in it. To do this, run a counter from 0 to 2^N.  At each step, the ith bit of the counter indicates whether the ith element in the array is a member of this subset. Think carefully about this, as it is a very useful general concept.

Question 2:  Shuffling a Deck.  Write a Java program which prints out a deck of cards in a randomly shuffled order.  To do this, you first need a deck of cards.  For that, use an array of integers numbered 0 to 51.  For a variable "card", its suit is (card/13, where 0 is spades, 1 is hearts, 2 is diamonds, and 3 is clubs) and its face value is (1 + card%13, where 1 is an ace, 2-10 are obvious, and 11-13 are jack, queen, and king).  So, if card == 37, then its suit is (37/13), or 2 (that is, diamonds), and its face value is (1 + 37%13), or 12 (that is, a queen).  Thus, 37 is the Queen of Diamonds.

So, create an array with 52 integers, call it "deck", and load each element deck[i] with i, so deck[0] is 0, deck[1] is 1, etc.  This, of course, is a perfectly sorted and hence unshuffled deck.  To shuffle the deck, we want in some sense to unsort it (shuffled == unsorted).  To do this, create a second array with 52 elements in it, and load each element with a random number.  Keep it simple, make the array full of doubles, and set each element randArray[i] = Math.random().  Now comes the trick:  you sort the random array, and each time you swap two elements in that array, you also swap the corresponding two elements in the deck array.  Since sorting a random array should require random swaps, this is effectively the same thing as shuffling the array.  Making the same swaps to the deck, thus, shuffles the deck.  When you're done, you can forget about the random array, and just return the sorted array.  This is more general than just a deck, in fact, and can work to sort an array of any size.  So, write a method with the following signature:
public static void sortArray(int[] a)
Be sure to use an efficient sort, say quicksort.  Just adapt the code to make duplicate swaps in the deck array.

Question 3:  Blackjack.  Now that you can create a sorted deck, make a game of Blackjack, where there is one player who always plays against the computer, and the computer is always the "house".  Each game will begin by printing out the current score and then freshly shuffling the deck if (and only if) there are fewer than 20 unused cards remaining.  The computer will be dealt two cards -- one face down the other face up.  The player will be dealt two cards -- both face up.  At this point, so long as the player has fewer than 21 points, he or she can elect to take another card (hit) repeatedly, or at any point to stop taking cards (stand).  If the player breaks 21, he or she busts and the computer wins (and each hand will be worth 1 point).  If the player gets 21 exactly, he or she gets Blackjack which will be worth 2 points.  Otherwise, the player has less than 21, and so it becomes the dealer's turn.  The dealer's second card is turned face up, and then the dealer repeatedly takes cards until either getting 17 or greater, or busting.  If the dealer busts, the player wins one point.  Otherwise, the higher of the dealer or the player gets one point, with a tie going to the dealer.

One odd point:  aces can be either 1 or 11.  You must count them whichever way leads to the better score for either the player or the dealer.

Also:  as we have not yet covered graphics, plainly you should use a text-based interface for this game.  Try to make it as attractive, informative, and usable as you can.

Question 4:  Solitaire.  Similarly, write a game of Solitaire.  There are many, many versions available, so pick one that has simple rules and would be easy to write.  Send the rules to everyone on perry2, so that we all know which version of Solitaire you are creating.  Then write the game, again using a text-based interface for this game.  Try to make it as attractive, informative, and usable as you can.

Extra Credit:  As you might guess, any game which requires an array is fair game here, if you pardon the pun.  Just be sure that it is a group effort.

Good luck!

DK