Advertisement
jdalbey

AcesHighFunctional.java

Oct 8th, 2015
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5 11.90 KB | None | 0 0
  1. import java.util.*;
  2.  
  3. /**
  4.  * Aces High.  Functional Solution.
  5.  * Sample Output: http://pastebin.com/raw.php?i=RN5UrCXY
  6.  * @author jdalbey
  7.  * @version Sep 2015
  8.  */
  9. public class AcesHighFunctional
  10. {
  11.     private Scanner scanner = new Scanner(System.in);
  12.     private final static int kNumPiles = 4;
  13.     /* The four piles of cards */
  14.     private Stack<Integer>[] cardPiles;
  15.     /* The deck of 52 playing cards */
  16.     private Stack<Integer> deck;
  17.  
  18.     /** Construct the application */
  19.     @SuppressWarnings("unchecked")    
  20.     public AcesHighFunctional()
  21.     {
  22.         // Initialize the card piles
  23.         cardPiles = (Stack<Integer>[]) new Stack[kNumPiles];
  24.     }
  25.  
  26.     /** Entry point for the application.
  27.      * @param args ignored
  28.      */
  29.     public static void main(String[] args)
  30.     {
  31.         // Instantiate this class
  32.         AcesHighFunctional app = new AcesHighFunctional();
  33.         // See if a command line argument was given
  34.         if (args.length != 0)
  35.         {
  36.             // Create deck from a single string of 52 card names with NO embedded blanks
  37.             app.createDeckFromString(args[0]);
  38.         }
  39.         else
  40.         {
  41.             // create a random deck
  42.             app.createRandomDeck();
  43.         }
  44.         // run the game
  45.         app.run();
  46.     }
  47.  
  48.     /** Play the game until the user quits or the game is over.  */
  49.     public void run()
  50.     {
  51.         // Initialize the Piles of cards
  52.         initPiles();
  53.         // Deal four cards
  54.         dealFour();
  55.         // Show Welcome message
  56.         System.out.println("See rules at: http://pastebin.com/raw.php?i=dhsNmQeq");
  57.         System.out.println("Welcome to Aces High");
  58.         // Display the table
  59.         printTable();
  60.         char userAction;
  61.         boolean notDone = true;
  62.         // repeat until game over
  63.         do
  64.         {
  65.             // Display the prompt
  66.             System.out.println("Enter pile number 1-4, D for draw, Mx for Move, or Q for quit");
  67.             // Obtain user's turn
  68.             String line = scanner.next();
  69.             userAction = Character.toLowerCase(line.charAt(0));
  70.             // IF User wants to draw THEN
  71.             if (userAction == 'd')
  72.             {
  73.                 // deal four cards
  74.                 notDone = dealFour();
  75.             }
  76.             // IF user wants to move a card THEN
  77.             else if (userAction == 'm')  
  78.             {
  79.                 // Move a card to an empty space
  80.                 char choice = Character.toLowerCase(line.charAt(1));
  81.                 int pile = choice - '1';
  82.                 move(pile);
  83.             }
  84.             // IF user isn't quitting  THEN
  85.             else if (userAction != 'q')
  86.             {
  87.                 // assume user wants to discard from a given pile
  88.                 int pile = userAction - '1';
  89.                 discard(pile);
  90.             }
  91.             // Display table
  92.             printTable();
  93.         }
  94.         while (userAction != 'q' && notDone);
  95.         // Display score
  96.         System.out.println("Your score is " + getScore());
  97.     }
  98.    
  99.     /** Perform a discard.
  100.      * @pile desired pile from which to discard the top card
  101.      */
  102.     public void discard(int pile)
  103.     {
  104.         // is legal pile number
  105.         if (pile >= 0 && pile < kNumPiles)
  106.         {
  107.             // is it legal to discard the top card on this pile?
  108.             if (canDiscard(pile))
  109.             {
  110.                 // remove the top card from the pile
  111.                 removeTop(pile);
  112.             }
  113.         }
  114.         else
  115.         {
  116.             System.out.println("Sorry, pile must be between 1 and 4.");
  117.         }
  118.     }
  119.     /** Perform move to empty spot.
  120.      * @param desired pile from which to move the top card
  121.      */
  122.     public void move(int pile)
  123.     {
  124.         // if the chosen pile is legal
  125.         if (pile >= 0 && pile < kNumPiles)
  126.         {
  127.             // if there is an available spot
  128.             if (canMove(pile) > -1)
  129.             {
  130.                 // move the top card to the empty pile
  131.                 moveTop(pile);
  132.             }
  133.         }
  134.         // ELSE show an error message
  135.         else
  136.         {
  137.             System.out.println("Sorry, pile must be between 1 and 4.");
  138.         }
  139.     }
  140.     /** Create the empty card piles */
  141.     public void initPiles()
  142.     {
  143.         // Create four empty stacks of cards
  144.         for (int pile = 0;  pile < cardPiles.length; pile++)
  145.         {
  146.             cardPiles[pile] = new Stack<Integer>();
  147.         }
  148.     }
  149.  
  150.     /** Deal one card from the deck onto each pile.
  151.      * @return false if unable to deal all four cards.
  152.      */
  153.     public final boolean dealFour()
  154.     {
  155.         boolean result = true;
  156.         // place a card on each pile from the deck
  157.         try
  158.         {
  159.             cardPiles[0].push(dealCard());
  160.             cardPiles[1].push(dealCard());
  161.             cardPiles[2].push(dealCard());
  162.             cardPiles[3].push(dealCard());
  163.         }
  164.         catch (EmptyStackException ex)
  165.         {
  166.             result = false;
  167.         }
  168.         return result;
  169.     }
  170.  
  171.     /** See if the card on top of pileNum can be discarded.
  172.      *  @param pileNum the number of the pile selected for discard.
  173.      *  @pre 0 <= pileNum < 4
  174.      *  @return true if there exists another visible card of the same suit
  175.      *  with a higher rank than the top card of selected pile.
  176.      */
  177.     public boolean canDiscard(int pileNum)
  178.     {
  179.         boolean result = false;
  180.         // is the chosen pile occupied?
  181.         if (!cardPiles[pileNum].isEmpty())
  182.         {
  183.             int chosen = cardPiles[pileNum].peek();
  184.             // consider each pile
  185.             for (int pile = 0; pile < cardPiles.length; pile++)
  186.             {
  187.                 // is another pile occupied?
  188.                 if (pile != pileNum && !cardPiles[pile].isEmpty())
  189.                 {
  190.                     // is the visible card of the same suit and higher rank?
  191.                     if (lessThan(chosen, cardPiles[pile].peek()))
  192.                     {
  193.                         // result is true
  194.                         result = true;
  195.                     }
  196.                 }
  197.             }
  198.         }
  199.         // return result
  200.         return result;
  201.     }
  202.  
  203.     /** Remove the top card from selected pile.
  204.      * @param pileNum selected pile
  205.      * @pre cardPiles[pileNum].size() > 0
  206.      */
  207.     public void removeTop(int pileNum)
  208.     {
  209.         cardPiles[pileNum].pop();
  210.     }
  211.  
  212.     /** See if the card on top of pileNum can be moved.
  213.      *  @param pileNum the number of the pile selected for discard.
  214.      *  @pre 0 <= pileNum < 4
  215.      *  @return the available pilenumber, if it exists, otherwise -1
  216.      */
  217.     public int canMove(int pileNum)
  218.     {
  219.         int result = -1;
  220.         // consider all the piles
  221.         for (int pile = 0; pile < cardPiles.length; pile++)
  222.         {
  223.             // is there an empty pile?
  224.             if (pile != pileNum && cardPiles[pile].isEmpty())
  225.             {
  226.                 // store this pile as the one we want
  227.                 result = pile;
  228.             }
  229.         }
  230.         // return target pile
  231.         return result;
  232.     }
  233.  
  234.     /** Move the top card from selected pile to an empty pile.
  235.      * @param pileNum selected pile
  236.      * @param emptyPile the pile number of the empty pile
  237.      * @pre canMove(pileNum) > -1
  238.      */
  239.     public void moveTop(int pileNum)
  240.     {
  241.         cardPiles[canMove(pileNum)].push(cardPiles[pileNum].pop());
  242.     }
  243.  
  244.     /** Compute the score; how many cards are left on the table.
  245.      * @return the table score.
  246.      */
  247.     public int getScore()
  248.     {
  249.         int total = 0;
  250.         // Accumulate the number of cards in each pile
  251.         for (int pile = 0; pile < cardPiles.length; pile++)
  252.         {
  253.             total += cardPiles[pile].size();
  254.         }
  255.         return 52 - total;
  256.     }
  257.  
  258.     /** Print the table. */
  259.     public void printTable()
  260.     {
  261.         String result = "";
  262.         // Get each pile in turn
  263.         for (int pile = 0; pile < cardPiles.length; pile++)
  264.         {
  265.             String line = "";
  266.             // Get each card from this pile
  267.             for (Integer card: cardPiles[pile])
  268.             {
  269.                 // Add this card's symbol to the line
  270.                 line = line + getCard(card) + ' ';
  271.             }
  272.             result += line + "\n";
  273.         }
  274.         // show the result
  275.         System.out.println(result);
  276.     }
  277.  
  278.     /**  Construct a deck of cards in random order. */
  279.     public void createRandomDeck()
  280.     {
  281.         deck = new Stack<Integer>();
  282.         // add 52 cards to the deck
  283.         for (int card = 0; card <= 51; card++)
  284.         {
  285.             // pust this number onto the deck
  286.             deck.push(new Integer(card));
  287.         }
  288.         // shuffle the deck
  289.         Collections.shuffle(deck);
  290.     }
  291.  
  292.     /**  Construct a deck of cards in the order specified.
  293.     @param cardInput a string of 52 card abbreviations with no blanks,
  294.     E.g., "2C5HTJ..."
  295.      */
  296.     public void createDeckFromString(String cardInput)
  297.     {
  298.         deck = new Stack<Integer>();
  299.         for (int x = 0; x < cardInput.length(); x = x + 2)
  300.         {
  301.             char rank = cardInput.charAt(x);
  302.             char suit = cardInput.charAt(x+1);
  303.             int rankNum = rankSymbols.indexOf(rank);
  304.             int suitNum = suitSymbols.indexOf(suit);
  305.             int cardvalue = suitNum * 13 + rankNum;
  306.            
  307.             deck.push(cardvalue);
  308.         }
  309.     }
  310.  
  311.     /** Deal (remove and return) the top card from the deck.
  312.      * @return the top card
  313.      */
  314.     public int dealCard()
  315.     {
  316.         return deck.pop();
  317.     }
  318.  
  319.     /** Determine if the deck has no more cards.
  320.      * @return true if the deck is empty.
  321.      */
  322.     public boolean isEmpty()
  323.     {
  324.         return deck.empty();
  325.     }
  326.  
  327.     /*
  328.      * Card represents one of the 52 cards in a
  329.      * standard deck of playing cards.  Each card has a suit and a rank.
  330.      * The card is represented as an integer between 0 and 51 inclusive.    
  331.      */
  332.     //private final String suits = "CCCCCCCCCCCCCDDDDDDDDDDDDDSSSSSSSSSSSSSHHHHHHHHHHHHH";
  333.     private final static String rankSymbols = "23456789TJQKA";
  334.     private final static String suitSymbols = "CDSH";
  335.     /** Accessor to the rank symbol of a card.
  336.      *  @param card the card for which the rank is extracted
  337.      */
  338.     public char getRank(int card)
  339.     {
  340.         // ranks go from 2 to K then Ace, which correspond to ints 0 - 12.
  341.         return rankSymbols.charAt(card % 13);
  342.     }
  343.  
  344.     /** Accessor to the suit symbol of a card.
  345.      *  @param card the card for which the suit is extracted
  346.      */
  347.     public char getSuit(int card)
  348.     {
  349.         return suitSymbols.charAt(card / 13);
  350.     }
  351.  
  352.     /** Return a printable representation of this card.
  353.      *  This implementation returns a 2 letter abbreviation.
  354.      *  @return abbrevation of the card, e.g., "2C"
  355.      */
  356.     public String getCard(int card)
  357.     {
  358.         //return "" + getRank(card) + suits.charAt(card);
  359.         return "" + getRank(card) + getSuit(card);
  360.     }
  361.  
  362.     /** Does this card have the same suit and a lower rank
  363.      * than Other card.
  364.      * @param card1 first card to be compared
  365.      * @param card2 other card to be compared
  366.      * @return true if card1 is less than card2
  367.      */
  368.     public boolean lessThan(int card1, int card2)
  369.     {
  370.         boolean result = false;
  371.         // Suits equal?
  372.         if (getSuit(card1) == getSuit(card2))
  373.         {
  374.             // rank lower?
  375.             if (card1 < card2)
  376.             {
  377.                 // indicate it's good!
  378.                 result = true;
  379.             }
  380.         }
  381.         // return result
  382.         return result;
  383.     }
  384.     //"2C3C4C5C6C7C8C9CTCJCQCKCAC2D3D4D5D6D7D8D9DTDJDQDKDAD2H3H4H5H6H7H8H9HTHJHQHKHAH2S3S4S5S6S7S8S9STSJSQSKSAS"
  385.     //"2C 3C 4C 5C 6C 7C 8C 9C TC JC QC KC AC 2D 3D 4D 5D 6D 7D 8D 9D TD JD QD KD AD 2H 3H 4H 5H 6H 7H 8H 9H TH JH QH KH AH 2S 3S 4S 5S 6S 7S 8S 9S TS JS QS KS AS "
  386. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement