import java.util.*; /* Driver */ class Driver { public static void main (String args[]) { // Stores 2 hands Hand hands[] = new Hand[2]; while (true) { // Display Main Menu and get user choice int choice = mainMenu(); switch (choice) { case 1: // Select a default hand subMenu1(hands); break; case 2: // Create a hand subMenu2(hands); break; case 3: // Print a hand subMenu3(hands); break; case 4: // Sort a hand subMenu4(hands); break; case 5: // Compare hands subMenu5(hands); break; case 6: //Initialize decks System.out.println("Boo"); int initChoice = initDeckMenu(); Deck deck; if( initChoice==1 ) deck = new Deck(); else { // Get cards from user int numCards = 0; while (numCards <= 0) { System.out.println("How many total cards do you want in the deck?"); numCards = UserInput.readInt(); if (numCards <= 0) System.out.println("Deck length has to be greater than zero."); } ///Card cards[] = new Card[numCards]; ArrayList cards = new ArrayList(); for (int i = 0; i < numCards; i++) { char suit; while (true) { System.out.println("Card " + i + "'s suit (c, d, h, s):"); suit = UserInput.readChar(); if (suit == 'c' || suit == 'd' || suit == 'h' || suit == 's') break; else System.out.println("That is not an option. Please select again. (c, d, h, s)"); } int number = 0; while (number == 0) { System.out.println("Card " + i + "'s number (1 - 13): "); number = UserInput.readInt(); if (number < 1 || number > 13) { System.out.println("That is not an option. Please select again. (1-13)"); number = 0; } } ////cards[i] = new Card(number, suit); cards.add( new Card(number, suit) ); } deck = new Deck(cards); } System.out.println("New deck initialized.\n"); boolean deckLoop = true; while (deckLoop) { int deckChoice = deckMenu(); switch (deckChoice) { case 1: //copy from sDeck into alDeck deck.copySDeckToALDeck(); System.out.println("sDeck is copied to alDeck. \n"); break; case 2: //copy from alDeck into sDeck deck.copyALDeckToSDeck(); System.out.println("alDeck is copied to sDeck. \n"); break; case 3: //print sDeck and alDeck deck.printSDeck(); deck.printALDeck(); break; case 4: //print sDeck deck.printSDeck(); break; case 5: //print alDeck deck.printALDeck(); break; case 6: //shuffle sDeck System.out.println("Partition size? (enter int value)"); deck.shuffle(UserInput.readInt()); break; case 7: //sort sDeck and alDeck deck.sortSDeck(); deck.sortALDeck(); break; case 8: deckLoop = false; break; default: break; } } break; case 7: return; default: break; } } } public static int initDeckMenu() { int userChoice = 0; while (userChoice == 0) { System.out.println("How would you like to initialize the deck? \n" + "---------------------------------------- \n" + "[1] Standard 52-card deck \n" + "[2] Custom deck: specify cards \n" ); userChoice = UserInput.readInt(); if (userChoice < 1 || userChoice > 2) { System.out.println("That is not an option. Please select again."); userChoice = 0; } } return userChoice; } public static int deckMenu() { int userChoice = 0; while (userChoice == 0) { System.out.println("What would you like to do with the deck? \n" + "---------------------------------------- \n" + "[1] Copy from sDeck into alDeck \n" + "[2] Copy from alDeck into sDeck \n" + "[3] Print sDeck and alDeck \n" + "[4] Print sDeck \n" + "[5] Print alDeck \n" + "[6] Shuffle sDeck \n" + "[7] Sort sDeck and alDeck \n" + "[8] Return to previous menu (the current deck will be lost) \n"); userChoice = UserInput.readInt(); if (userChoice < 1 || userChoice > 8) { System.out.println("That is not an option. Please select again."); userChoice = 0; } } return userChoice; } public static int mainMenu() { int userChoice = 0; while (userChoice == 0) { System.out.println("Make an choice\n" + "-----------------------\n" + "[1] Select a Pre-Created Hand \n" + "[2] Make a Hand \n" + "[3] Print Either Hand \n" + "[4] Sort a Hand \n" + "[5] Compare the Hands \n" + "[6] Initialize Deck (and perform various deck-related actions)\n" + "[7] Quit" ); userChoice = UserInput.readInt(); if (userChoice < 1 || userChoice > 7){ System.out.println("That is not an option. Please select again."); userChoice = 0; } } return userChoice; } public static void subMenu1 (Hand[] hands) { int defaultChoice = 0; while (defaultChoice == 0) { //User choses which of his hands he wants to set to a default System.out.println("Which Hand (1 or 2) would you like to set to the default? \n" + " [1] Hand 1 \n" + " [2] Hand 2 \n"); defaultChoice = UserInput.readInt(); if (defaultChoice < 1 || defaultChoice > 2){ System.out.println("That is not an option. Please select again."); defaultChoice = 0; } } int premadeChoice = 0; while (premadeChoice == 0) { //User choses which of the default hands he wants System.out.println("Which Pre-created hand would you like? \n" + " [1] Hand 1 \n" + " c1, d2, h3, s4, s11 \n" + " [2] Hand 2 \n" + " s1, h2, d3, c4, s11 \n"); premadeChoice = UserInput.readInt(); if (premadeChoice < 1 || premadeChoice > 2){ System.out.println("That is not an option. Please select again."); premadeChoice = 0; } } //cards for default hand #1 Card hand_1[] = new Card[5]; hand_1[0] = new Card(1, 'c'); hand_1[1] = new Card(2, 'd'); hand_1[2] = new Card(3, 'h'); hand_1[3] = new Card(4, 's'); hand_1[4] = new Card(11, 's'); //cards for default hand #2 Card hand_2[] = new Card[5]; hand_2[0] = new Card(1, 's'); hand_2[1] = new Card(2, 'h'); hand_2[2] = new Card(3, 'd'); hand_2[3] = new Card(4, 'c'); hand_2[4] = new Card(11, 's'); if (premadeChoice == 1) { //sets chosen hand to default hand #1 hands[defaultChoice - 1] = new Hand(hand_1); } else { //sets chosen hand to default hand #2 hands[defaultChoice - 1] = new Hand(hand_2); } } public static void subMenu2(Hand[] hands) { int userChoice = 0; while (userChoice == 0) { System.out.println("Which Hand (1 or 2) would you like to manually create? \n" + " [1] Hand 1 \n" + " [2] Hand 2 \n"); userChoice = UserInput.readInt(); if (userChoice < 1 || userChoice > 2){ System.out.println("That is not an option. Please select again."); userChoice = 0; } } int handLength = 0; while (handLength <= 0) { System.out.println("How many total cards do you want in the hand?"); handLength = UserInput.readInt(); if (handLength <= 0) System.out.println("Hand length has to be greater than zero."); } Card cards[] = new Card[handLength]; for (int i = 0; i < handLength; i++) { char suit; while (true) { System.out.println("Card " + i + "'s suit (c, d, h, s):"); suit = UserInput.readChar(); if (suit == 'c' || suit == 'd' || suit == 'h' || suit == 's') break; else System.out.println("That is not an option. Please select again. (c, d, h, s)"); } int number = 0; while (number == 0) { System.out.println("Card " + i + "'s number (1 - 13): "); number = UserInput.readInt(); if (number < 1 || number > 13) { System.out.println("That is not an option. Please select again. (1-13)"); number = 0; } } cards[i] = new Card(number, suit); } hands[userChoice - 1] = new Hand(cards); } public static void subMenu3(Hand[] hands) { //prints a hand int choice = 0; while (choice == 0) { System.out.println("Hand to print: \n" + " [1] Hand 1 \n" + " [2] Hand 2"); choice = UserInput.readInt(); if (choice < 1 || choice > 2) { System.out.println("That is not an option. Please select again. (1 or 2)"); choice = 0; } } System.out.println(hands[choice - 1].toString()); } public static void subMenu4(Hand[] hands) { //sorts a hand int choice = 0; while (choice == 0) { System.out.println("Hand to sort: \n" + " [1] Hand 1 \n" + " [2] Hand 2"); choice = UserInput.readInt(); if (choice < 1 || choice > 2) { System.out.println("That is not an option. Please select again. (1 or 2)"); choice = 0; } } int sortChoice = 0; while (sortChoice == 0) { System.out.println("How to sort: \n" + " [1] Sort by Number \n" + " [2] Sort by Suit \n" + " [3] Sort by Suit, then by Number \n"); sortChoice = UserInput.readInt(); if (sortChoice < 1 || sortChoice > 3) { System.out.println("That is not an option. Please select again. (1, 2, or 3)"); sortChoice = 0; } } if (sortChoice == 1) { //sorts hand by number by calling the hand's proper sort method hands[choice - 1].sortByNumber(); } else if (sortChoice == 2) { //sorts hand by suit by calling the hand's proper sort method hands[choice - 1].sortBySuit(); } else { //sorts hand first by suit, then by number, by calling the hand's proper sort method hands[choice - 1].sortBySuitThenNumber(); } } public static void subMenu5(Hand[] hands) { //compares hands int choice = 0; while (choice == 0) { System.out.println("How to compare Hand 1 to Hand 2: \n" + " [1] Compare hands by point total\n" + " [2] Compare hands by face cards\n" + " [3] Compare hands by same suit length\n"); choice = UserInput.readInt(); if (choice < 1 || choice > 3) { System.out.println("That is not an option. Please select again. (1, 2, or 3)"); choice = 0; } } if (choice == 1) { //compares the hands by point total int compare = hands[0].compareTo(hands[1]); if( compare < 0 ) System.out.println("Hand 1 is worth less total points than Hand 2"); else if( compare == 0 ) System.out.println("Hand 1 is worth the same total points as Hand 2"); else System.out.println("Hand 1 is worth more total points than Hand 2"); } else if (choice == 2) { //compares the hands by face cards HandFaceCardComparator handCompare = new HandFaceCardComparator(); int compare = handCompare.compare(hands[0], hands[1]); if( compare < 0 ) System.out.println("Hand 1 has less face cards than Hand 2"); else if( compare == 0 ) System.out.println("Hand 1 has the same total face cards as Hand 2"); else System.out.println("Hand 1 has more total face cards than Hand 2"); } else { //compares the hands by same suit length HandSameSuitComparator handCompare = new HandSameSuitComparator(); int compare = handCompare.compare(hands[0], hands[1]); if( compare < 0 ) System.out.println("Hand 1 has less total cards from the same suit than Hand 2"); else if( compare == 0 ) System.out.println("Hand 1 has the same total cards from the same suit as Hand 2"); else System.out.println("Hand 1 has more total cards from the same suit than Hand 2"); } } } /* Card class */ class Card implements Comparable, Cloneable { private int number; private char suit; public Card() { number = 2; suit = 'c'; } public Card(int number, char suit) { if (number <= 13 && number >= 1) { this.number = number; } else { this.number = 2; } if (suit == 'c' || suit == 'd' || suit == 'h' || suit == 's') { this.suit = suit; } else { suit = 'c'; } } public int compareTo(Object object) { if (object instanceof Card) { Card card = (Card) object; if (number == card.getNumber()) return 0; else if (number < card.getNumber()) return -1; else return 1; } else{ // Throw exception if object isn't a Card throw new ClassCastException(); } } public Object clone() { Object object = null; try { object = super.clone(); } catch (CloneNotSupportedException e) { //handle the exception } return object; } public int getNumber() { return number; } public char getSuit() { return suit; } public void setNumber(int number) { if (number <= 13 && number >= 1) { this.number = number; } else { this.number = 2; } } public void setSuit(char suit) { if (suit == 'c' || suit == 'd' || suit == 'h' || suit == 's') { this.suit = suit; } else { suit = 'c'; } } public String toString() { return "Number: " + number +"\n" + "Suit: " + suit + "\n"; } } /* Deck Class */ class Deck { private ArrayList alDeck; private Stack sDeck; public Deck() { // Default Constructor: Create a 52 card deck on both data structures char suit; alDeck = new ArrayList(); sDeck = new Stack(); for (int i = 1; i <= 4; i++) { if( i==1 ) suit = 'c'; else if( i==2 ) suit = 'd'; else if( i==3 ) suit = 'h'; else suit = 's'; for (int j = 1; j <= 13 ; j++) { Card card = new Card(j, suit); alDeck.add(card); } } copyALDeckToSDeck(); } public Deck( ArrayList alDeck ) { this.alDeck = alDeck; this.sDeck = new Stack(); } public Deck( Stack sDeck ) { this.sDeck = sDeck; this.alDeck = new ArrayList(); } public void copySDeckToALDeck() { long time1 = System.nanoTime(); Stack tempStack = new Stack(); // Clear alDeck alDeck.clear(); // Copy sDeck into alDeck while (sDeck.empty() == false) { Card tempCard = sDeck.pop(); alDeck.add(tempCard); tempStack.push(tempCard); } // Recover sDeck by flipping tempStack while (tempStack.empty() == false) { sDeck.push(tempStack.pop()); } long time2 = System.nanoTime(); printTime(time1, time2); } public void copyALDeckToSDeck() { long time1 = System.nanoTime(); // Clear sDeck while (sDeck.empty() == false) { sDeck.pop(); } // Copy alDeck into sDeck for (int i = alDeck.size()-1; i >= 0; i--) { sDeck.push(alDeck.get(i)); } long time2 = System.nanoTime(); printTime(time1, time2); } public void printSDeck() { long time1 = System.nanoTime(); System.out.println("sDeck: " + "\n"); System.out.println(getSDeckString()); printTime(time1, System.nanoTime()); } public String getSDeckString(){ String cardList = new String(); Stack tempStack = new Stack(); int i = 1; // Make the String while (sDeck.empty() == false) { Card tempCard = sDeck.pop(); cardList = cardList.concat("Card: " + i + "\n"); cardList = cardList.concat(tempCard.toString()); cardList = cardList.concat("\n\n"); tempStack.push(tempCard); i++; } // Recover sDeck by flipping tempStack while (tempStack.empty() == false) { sDeck.push(tempStack.pop()); } return cardList; } public void printALDeck() { long time1 = System.nanoTime(); System.out.println("alDeck: " + "\n"); System.out.println(getALDeckString()); printTime(time1, System.nanoTime()); } public String getALDeckString(){ String cardList = new String(); for (int i = 0; i < alDeck.size(); i++) { Card cardAL = alDeck.get(i); cardList = cardList.concat("Card: " + (i+1) + "\n"); cardList = cardList.concat(cardAL.toString()); cardList = cardList.concat("\n\n"); } return cardList; } public int countSDeck(){ Stack tempStack = new Stack(); // Count the number of cards in sDeck int deckCounter = 0; while (sDeck.empty() == false) { tempStack.push(sDeck.pop()); deckCounter++; } // Restore sDeck while (tempStack.empty() == false) { sDeck.push(tempStack.pop()); } return deckCounter; } public void shuffle(int partition) { long time1 = System.nanoTime(); // Split deck into two sub-decks int deckCounter = countSDeck(); int halfDeck = (int)Math.floor( ((double)deckCounter)/2.0 ); Stack subDeck1 = new Stack(); for (int i = 0; i < halfDeck; i++) { subDeck1.push(sDeck.pop()); } Stack subDeck2 = new Stack(); while (sDeck.empty() == false) { subDeck2.push(sDeck.pop()); } // Remerge the two decks, shuffled according to partition size while ( !subDeck1.empty() || !subDeck2.empty() ){ if (!subDeck1.empty()) { for (int i = 0; (i < partition) && !subDeck1.empty(); i++) { sDeck.push(subDeck1.pop()); } } if (!subDeck2.empty()) { for (int i = 0; (i < partition) && !subDeck2.empty(); i++) { sDeck.push(subDeck2.pop()); } } } long time2 = System.nanoTime(); printTime(time1, time2); } public void sortSDeck() { long time1 = System.nanoTime(); Stack tempStack = new Stack(); CardSuitNumberComparator cardComp = new CardSuitNumberComparator(); int deckCounter = countSDeck(); for (int place = 0; place < deckCounter; place++) { for (int place2 = 0; (place2 < deckCounter) && !sDeck.empty(); place2++) { int check = 0; for (int tempPlace = place2; (tempPlace > -1) && !sDeck.empty(); tempPlace--) { tempStack.push(sDeck.pop()); } if (!tempStack.empty() && !sDeck.empty()) { check = cardComp.compare((Card)tempStack.peek(), (Card)sDeck.peek()); } if (check > 0) { Card card = new Card(); card = (Card)sDeck.pop(); sDeck.push(tempStack.pop()); sDeck.push(card); } while (!tempStack.empty()) { sDeck.push(tempStack.pop()); } } } printTime(time1, System.nanoTime()); } public void sortALDeck() { long time1 = System.nanoTime(); CardSuitNumberComparator cardComp = new CardSuitNumberComparator(); // Uses BubbleSort for (int place = 0; place < alDeck.size(); place++) { for (int place2 = 1; place2 < alDeck.size(); place2++) { int check = cardComp.compare(alDeck.get(place2 - 1), alDeck.get(place2)); if (check > 0) { alDeck.add(place2 - 1, alDeck.get(place2)); alDeck.remove(place2 + 1); } } } printTime(time1, System.nanoTime()); } public Deck(ArrayList alDeck, Stack sDeck) { this.alDeck = alDeck; this.sDeck = sDeck; } public ArrayList getALDeck() { return alDeck; } public void printTime(long time1, long time2) { long nTime = time2 - time1; long sTime = nTime / 1000000000; long minutes = sTime / 60; long seconds = sTime % 60; System.out.println("Time to complete: \n" + " Nanoseconds: " + nTime + "\n" + " (Minutes, Seconds): (" + minutes + ", " + seconds + ")\n\n" ); } public Stack getSDeck() { return sDeck; } public void setAlDeck(ArrayList alDeck) { this.alDeck = alDeck; } public void setSDeck(Stack sDeck) { this.sDeck = sDeck; } public String toString() { String cardList = new String(); cardList.concat("Contents of ArrayList: \n"); cardList.concat(getALDeckString()); cardList.concat("\nContents of Stack: \n"); cardList.concat(getSDeckString()); return cardList; } } /* class CardSuitComparator - compares Cards based on suit */ class CardSuitComparator implements Comparator{ public CardSuitComparator() { } public int compare(Object object1, Object object2) { if( object1 instanceof Card && object2 instanceof Card ){ Card card1 = (Card)object1; Card card2 = (Card)object2; if (card1.getSuit() < card2.getSuit()) return -1; else if (card1.getSuit() == card2.getSuit()) return 0; else return 1; } else{ // Throw exception if either argument is not a Card object throw new ClassCastException(); } } } /* class CardSuitNumberComparator - compares Cards by suit then by number */ class CardSuitNumberComparator implements Comparator { public CardSuitNumberComparator() { } public int compare(Object object1, Object object2) { if( object1 instanceof Card && object2 instanceof Card ){ Card card1 = (Card)object1; Card card2 = (Card)object2; if (card1.getSuit() == card2.getSuit()) { if (card1.getNumber() < card2.getNumber()) return -1; else if (card1.getNumber() == card2.getNumber()) return 0; else return 1; } else if (card1.getSuit() < card2.getSuit()) return -1; else return 1; } else{ // Throw exception if either argument is not a Card object throw new ClassCastException(); } } } /* class Hand - an object containing an array of Cards */ class Hand implements Cloneable, Comparable{ private Card[] cards; public Hand() { char suit; cards = new Card[5]; for (int i = 0; i < cards.length; i++) { int number = (int)Math.floor(13.0*Math.random()) + 1; double suitNumber = 4.0*Math.random(); if( suitNumber < 1.0 ) suit = 'c'; else if( suitNumber < 2.0 ) suit = 'd'; else if( suitNumber < 3.0 ) suit = 'h'; else suit = 's'; cards[i] = new Card(number, suit); } } public Hand (Card[] cards) { this.cards = cards; } public int compareTo (Object object) { if (object instanceof Hand) { Hand hand = (Hand) object; int hand1 = 0; int hand2 = 0; for (int i = 0; i < cards.length; i++) hand1 += cards[i].getNumber(); for (int i = 0; i < hand.getNumberOfCards(); i++) hand2 += hand.getCardNumber(i); if (hand1 < hand2) return -1; else if (hand1 == hand2) return 0; else return 1; } else { // Throw exception if object isn't a Hand throw new ClassCastException(); } } public Object clone() { Card cardsCopy[] = new Card[cards.length]; for (int i = 0; i < cards.length; i++) { cardsCopy[i] = new Card(cards[i].getNumber(), cards[i].getSuit()); } return new Hand(cardsCopy); } public void sortByNumber() { Arrays.sort(cards); System.out.println("Hand after sort: "); System.out.println(toString()); } public void sortBySuit() { Arrays.sort(cards, new CardSuitComparator()); System.out.println("Hand after suit sort: "); System.out.println(toString()); } public void sortBySuitThenNumber() { Arrays.sort( cards, new CardSuitNumberComparator() ); System.out.println("Hand after suit-then-number sort: "); System.out.println(toString()); } public Card[] getCards() { return cards; } public int getCardNumber(int selection) { return cards[selection].getNumber(); } public int getNumberOfCards() { return cards.length; } public void setCards(Card[] cards) { this.cards = cards; } public String toString() { String cardList = new String(); for (int i = 0; i < cards.length; i++) { cardList = cardList.concat("Card " + i + "\n"); cardList = cardList.concat(cards[i].toString()); cardList = cardList.concat("\n"); } return cardList; } } /* class HandFaceCardComparator - compares Hands based on number of face cards in the hand */ class HandFaceCardComparator implements Comparator{ public HandFaceCardComparator() { } public int compare(Object object1, Object object2) { if( object1 instanceof Hand && object2 instanceof Hand ){ Hand hand1 = (Hand)object1; Hand hand2 = (Hand)object2; Card cards1[] = hand1.getCards(); Card cards2[] = hand2.getCards(); int numberOfFaces1 = 0; int numberOfFaces2 = 0; for (int i = 0; i < cards1.length; i++) if (cards1[i].getNumber() == 1 || cards1[i].getNumber() > 10) numberOfFaces1++; for (int i = 0; i < cards2.length; i++) if (cards2[i].getNumber() == 1 || cards2[i].getNumber() > 10) numberOfFaces2++; if (numberOfFaces1 < numberOfFaces2) return -1; else if (numberOfFaces1 == numberOfFaces2) return 0; else return 1; } else{ // Throw exception if either argument is not a Hand object throw new ClassCastException(); } } } /* class HandSameSuitComparator - compares Hands based on maximum number of cards in the hand with the same suit */ class HandSameSuitComparator implements Comparator{ public HandSameSuitComparator() { } public int compare(Object object1, Object object2) { if( object1 instanceof Hand && object2 instanceof Hand ){ Hand hand1 = (Hand)object1; Hand hand2 = (Hand)object2; Card cards1[] = hand1.getCards(); Card cards2[] = hand2.getCards(); int c1 = 0; int d1 = 0; int h1 = 0; int s1 = 0; for (int i = 0; i < cards1.length; i++) { char suit = cards1[i].getSuit(); if( suit=='c' ) c1++; else if( suit=='d' ) d1++; else if( suit=='h' ) h1++; else s1++; } int top1 = Math.max(c1, Math.max(d1, Math.max(h1, s1))); int c2 = 0; int d2 = 0; int h2 = 0; int s2 = 0; for (int i = 0; i < cards2.length; i++) { char suit = cards2[i].getSuit(); if( suit=='c' ) c2++; else if( suit=='d' ) d2++; else if( suit=='h' ) h2++; else s2++; } int top2 = Math.max(c2, Math.max(d2, Math.max(h2, s2))); if (top1 < top2) return -1; else if (top1 == top2) return 0; else return 1; } else{ // Throw exception if either argument is not a Hand object throw new ClassCastException(); } } }