CSCI 132 Data Structures--Spring 2014

    Home | | Syllabus | | Assignments | | Lecture Notes

    Assignment 2 Solutions

    Solution to war.cc

      /*******************************************************************
      * Name: Brenda Student
      * Date: 2/7/14
      * Course: CSCI 132 Section 01
      * Assignment: Assignment 2
      * Instructor: Royden
      * Program: war.cc
      * Purpose:  Implementation of the card game War.  Asks for number of cards
      *	to be dealt, deals cards betwen computer and user.  Asks user if 
      *	they want to continue on each play of the hand.  In each hand, 
      *	each player turns over the top card in their pile.  The
      *	player with the highest valued card wins both cards. Winner is the one
      *	with the most total cards at the end of play.  The game automatically
      *	ends if one player runs out of cards.
      ***************************************************************************/
      
      
      #include "card.h"
      #include "stack.h"
      
      int get_number_cards();
      void deal_cards(Deck &, Stack &,Stack &, int);
      void get_top_card(Stack &, Card &);
      void play_round(Card, Card, Stack &, Stack &, Stack &);
      void check_card_piles(Stack &, Stack &, Stack &, Stack &, bool &);
      void move_cards(Stack &, Stack &);
      void compute_winner(Stack &, Stack &, Stack &, Stack &, Stack &);
      
      int main(void) {
        Stack computer_win, computer_draw;    //Stacks to hold the computer's cards
        Stack user_win, user_draw;            //Stacks to hold the user's cards
        Stack tie;                            //Stacks to hold cards from a tie
        Deck warDeck;                         //Deck of cards
        char answer;                          //User's answer to query about continuing play
        bool done = false;                    //Is one player out of cards yet?
        int numCards;                         //Number of cards in each hand
        Card userCard;                        // Holds the card the user turns over
        Card computerCard;                    // Holds the card the computer turns over
      
      
        // Shuffle the deck and deal the cards
        cout << "Shuffling cards." <> answer;
        cout << endl;
       
        while ((answer == 'y') && (!done)) {
      
          /* Turn over the top cards and compare them. */
        	get_top_card(user_draw, userCard);
        	get_top_card(computer_draw, computerCard);
        	
          cout << "Your card is a ";
          userCard.write_card();
          cout << endl;
          cout << "The computer's card is a ";
          computerCard.write_card();
          cout << endl;
      
          play_round(userCard, computerCard, user_win, computer_win, tie);
          
          check_card_piles(user_draw, user_win, computer_draw, computer_win, done);
              
          if (!done) {
            cout << "Do you want to continue (y/n)? ";
            cin >> answer;
            cout << endl;
          } //end if
        
        } //end while
      
        compute_winner(user_draw, user_win, computer_draw, computer_win, tie);
      
        return 0;
      } //end main()
      
      
      
      int get_number_cards() {
      /*******************************************************************************
       * Pre: None
       * Post: Asks user for number of cards.  Returns user's input integer
       *      between 1 and 26
       *******************************************************************************/
        int numCards;
        
        cout << "How many cards in each hand (not more than 26)? ";
        cin >> numCards;
        while ((numCards < 1) || (numCards > 26 )) {
        	if (numCards < 1) {
        		cout << "Please enter a number greater than zero: ";
        	} else {
        		cout << "That's too many cards.  Please enter a number less than 27: ";
        	} //end if else
        	cin >> numCards;
        } //end while
        
        return numCards;
      } //end get_number_cards()
      
      
      void deal_cards(Deck &warDeck, Stack &computer_draw, Stack &user_draw, int numCards) {
      /*******************************************************************************
       * Pre: Deck has been shuffled. numCards is less than or equal to half the deck.
       * Post: Deals numCards cards from warDeck into computer_draw and user_draw stacks.
       *******************************************************************************/
      
        cout << endl << "Dealing cards." << endl;
        for (int i = 0; i < numCards; i++){
          if (computer_draw.push(warDeck.dealCard()) == overflow) {
          	cout << "Computer's draw pile is full.  No more cards dealt to computer." << endl;
          	/*Note--you could exit the program here, but it's not necessary */
          } //end if
          if (user_draw.push(warDeck.dealCard()) == overflow) {
          	cout << "User's draw pile is full.  No more cards dealt to user." << endl;
          	/*Note--you could exit the program here, but it's not necessary */
          } //end if
        } //end for
      } //end deal_cards()
      
      
      void get_top_card(Stack &card_stack, Card &top_card) {
      /*******************************************************************************
       * Pre: card_stack has cards in it.
       * Post: Stores the value of the top card of card_stack in top_card and pops()
       *       the top card off card_stack.
       *******************************************************************************/
        	
          if (card_stack.top(top_card) == underflow) {
            cout << "Error! User tried to draw card from empty draw pile. Exiting program." << endl;
            exit(0);	//Exit program
          } // end if
          card_stack.pop();                //Don't need error checking here, since
                                          //top function worked above
      } //end get_top_card()
      
      
      void play_round(Card userCard, Card computerCard, Stack &user_win, Stack &computer_win, Stack &tie) {
      /*******************************************************************************
       * Pre: userCard and computerCard have been drawn off the top of the draw stacks
       * Post: Compares user's card and computer's card and pushes them onto the appropriate
       *       stack (user_win, computer_win or tie) depending on which is bigger.
       *******************************************************************************/
      
          if (userCard.get_value() > computerCard.get_value()) {
            cout << "You win this round." << endl << endl;
            if (user_win.push(userCard) == overflow) {
              cout << "Error!  User tried to push onto a full win pile. Exiting program.";
              exit(0);
            } //end if
            if (user_win.push(computerCard) == overflow) {
              cout << "Error!  User tried to push onto a full win pile. Exiting program.";
              exit(0);
            } // end if
          } else if (computerCard.get_value() > userCard.get_value()) {
            cout << "Computer wins this round" << endl << endl;
            if (computer_win.push(computerCard) == overflow ) {
              cout << "Error!  Computer tried to push onto a full win pile. Exiting program.";
              exit(0);
            } // end if
            if (computer_win.push(userCard) == overflow ) {
              cout << "Error!  Computer tried to push onto a full win pile. Exiting program.";
              exit(0);
            } // end if
          } else {
            cout << "This round is a tie. " << endl << endl;
            if (tie.push(computerCard) == overflow ) {
            	cout << "Error!  Tried to push onto a full tie pile. Exiting program.";
              exit(0);
            } // end if
            if (tie.push(computerCard) == overflow ) {
            	cout << "Error!  Tried to push onto a full tie pile. Exiting program.";
              exit(0);
            } // end if
          } // end if - else
      } //end play_round()
      
      void check_card_piles(Stack &user_draw, Stack &user_win, Stack &computer_draw, 
                            Stack &computer_win, bool &done) {
      /*******************************************************************************
       *Pre: user_draw, user_win, computer_draw and computer_win have cards from previous rounds 
       *Post: If either draw pile is empty, moves cards from corresponding win pile to draw pile.
       *      If either player's hand is empty, prints winner and sets done to true.
       *******************************************************************************/ 
        /* Check if the computer's draw pile is empty.  If so, check for an empty win pile
         * If win pile is empty, end the game.  Otherwise transfer cards from win pile to draw pile */
        if (computer_draw.empty()){
          if(computer_win.empty()) {
            cout << "Computer has no cards left.  You win!" << endl;
            done = true;
          } else {
            cout << "Moving computer's win pile to draw pile." << endl;	    
            move_cards(computer_win, computer_draw); 
          } //end if else
        } //end outer if
          
        /* Check if the user's draw pile is empty.  If so, check for an empty win pile
         * If win pile is empty, end the game.  Otherwise transfer cards from win pile to draw pile */
        if (user_draw.empty()){
          if ( user_win.empty() ) {
      	  cout << "You have no cards left.  The computer wins!" << endl;
      	  done = true;
          } else {
            cout << "Moving your win pile to draw pile." << endl;
            move_cards(user_win, user_draw);
          } //end if else
        } //end outer if
      } //end check_card_piles( )
      
      void move_cards(Stack &player_win, Stack &player_draw){
      /*******************************************************************************
       * Pre: player_win stack has some cards in it.
       * Post: Moves all the cards from the player_win stack to the player_draw stack.
       *******************************************************************************/
        Card myCard;       //Holds a single card for temporary purposes
      
        //Loop to transfer cards from win pile to draw pile.
        while (!player_win.empty()){
          if (player_win.top(myCard) == underflow) {
            cout << "Error! player tried to draw card from empty win pile. Exiting program";
            exit(0);
          } // end if
          player_win.pop();
          cout << "Moving ";
          myCard.write_card();
          cout << endl;
          if (player_draw.push(myCard) == overflow) {
            cout << "Error! player tried to push onto a full draw pile.  Exiting program.";
            exit(0);
          } // end if
        } // end while
      } //end move_cards()
      
      void compute_winner(Stack &user_draw, Stack &user_win, Stack &computer_draw, 
                          Stack &computer_win, Stack &tie) {
      /*******************************************************************************
       * Pre: It's the end of the game.
       * Post: Computes and outputs the winner according to who has the most cards.
       *******************************************************************************/
        int computer_count = computer_draw.size() + computer_win.size();
        int user_count = user_win.size() + user_draw.size();
        cout << "You have " << user_count << " cards." << endl;
        cout << "The computer has " << computer_count << " cards." << endl;
        cout << "There are " << tie.size() << " cards in the tie pile." << endl;
        if (computer_count > user_count) {
          cout << "The computer wins!" << endl;
        } else if (user_count > computer_count) {
          cout << "You win!" << endl;
        } else {
          cout << "It's a tie!" << endl;
        } //end if else
      } //end compute_winner()
      
      


    Home | | Syllabus | | Assignments | | Lecture Notes