Objective of this Program:
(a) To learn more about modularization of a program into independent modules,
(b) To use arrays in a program,
(c) To get some experience with using files, and
(d) to learn about top down program development.
Main Problem to be Solved
The idea behind modularization is to break the problem into smaller units each of which are easier to understand. Each module should solve a "logically independent" problem. That is to say, if a part of the problem we are trying to solve (encode) has a self-contained logical status, we will make it a separate module and put it into a separate file. Each file will have its own header, its own preamble, and its own listing of input and output parameters.
The modularization serves three purposes. (1) it makes the program easier to understand and create (both writing and debugging), (2) it allows one to develop the program in parallel, i.e., different people can develop different parts of the program at the same time, and (3) it allows for reusable code. I.e., the independent modules can be used in other programs if they are needed.
The fifth program consists of playing the card game of war. To simplify the programming assignment, we will simplify the game. In the extra credit we will implement the actual game. Note that the same techniques we are using for the game of war could be used to implement the game of blackjack or poker or bridge. I have chosen war as its rules are sufficiently simple to ease the difficulty of the assignment.
The (simplified) game of war is played as follows:
Two players each take a card from the deck; the player with higher rank card wins that round and gets two points. If they choose cards with equal rank, they select from the deck again. They continue to choose cards until a winner is decided. The winner of that round then gets the number of points corresponding to the number of cards won. So the minimum is 2 points, and more if a "war" occurs. For example, if both players play a 7, then a "war" occurs. They continue to play to see who has won, so they each play a card again. If the first player has a higher ranked card than the second player, the first player gets 4 points, 2 for the higher ranked card, and two for the 7's. If the second card of each are also the same rank, a "double war", then they each play another card, etc. The winner of the game is the player with the most points when the deck has been entirely dealt out. So at the end, the sum of the points for the two players will be 52. The program should output the cards for each player and the total number of points for each player for each play of the cards. The easiest way to do this is to put them out in four columns: card for player one, card for player two, total points for player one, total points for player two, and output one row for each play.
Note that the rank of a card is its value, with the order starting at two though ten, followed by jack, queen, king and ace, the highest. In this game the suits, clubs, spades, diamonds, and hearts are irrelevant.
Note:Each of the 6 procedures discussed below should be in a separate .cpp file. That is to say, you should have a file called readDeck.cpp, printDeck.cpp, shuffle.cpp,war.cpp, saveDeck.cpp, and random.cpp. You will also have a header file called cards.h, which will be included in all of your 7 .cpp files. The seventh file is main.cpp. The header file is discussed below.
Documentation for Implementing the Deck of Cards
The deck of cards is an array of size 52 corresponding to the cards in the deck. The array will consist of a permutation of the numbers from 0 to 51 inclusive. The integers are assigned to cards by first suit and then rank. So the first 13 cards are hearts, the next 13 are diamonds, the next 13 are clubs, and the last 13 are spades. The rank goes from 2 to 10, then J, Q, K, and A. So the number 12 corresponds to the ace of spaces, for example. Similarly the number 29 corresponds to the 5 of clubs.
To convert the integer representation to the usual representation of a card, notice that one can find the rank via the modulo function (%) of 13 and the suit by dividing by 13:
int card;
int rank;
int suit;
rank = card % 13;
suit = card /13;
Thus for the value of 12 (ace of spades) we get that using the above calculations that
rand = 12 % 13 = 12
suit = 12/13 = 0 //this is integer division
So its rank if 12 (the ace) and it suit is 0, which is hearts.
Similarly 29 yields rank of 3, which is a 5 (rank equal to 0 is the 2), and suit of 2, which is clubs. Finally, 48 has rank 9, which is a jack, and suit 3, which is spades.
To print out a card, then find its rank and suit and use a switch to convert it to the proper character value. One can also use an array of chars to convert it to the proper character value in one line each for rank and suit.
Documentation for readDeck
You are to call an external function to read in deck of cards.
The calling protocol for the procedure will be readDeck(fileName,deckOfCards); where fileName is the name of the file which will have the 52 cards to play the game of war. For the moment, you will not implement this until part II of the assignment. You will just have a single line of code in your routine:
cout <<"We are in readDeck\n" ;
Documentation for random
There are two auxiliary function you will need setRan and ran. setRan will use the system clock to set the value of the seed. This will guarantee that each time you run the program, you get a different shuffling of the cards. ran is passed an int, say k, and returns a value from 0 to k-1 at random with a uniform distribution. That means that the values of 0 to k-1 will appear equally likely.
Both of these functions have been implemented for you in the file random.cpp which you should add to your project.
Documentation for shuffle
The routine shuffle will shuffle the cards, meaning that it will do a permutation of the array of 52 cards. You will use the ran.cpp method to do this. How you implement this is up to you, but you should have a loop from 0 to 51 so that each card is "moved".
The protocol for calling it is
shuffle(deckOfCards);
where deckOfCards is the array of 52 ints.
Documentation for saveDeck
saveDeck will be an external procedure which will print out an the 52 cards to the file it is sent. The protocol for invoking it is as follows:
saveDeck(fileName,deckOfCards);
where fileName is the name of the file where the data is to be printed. deckOfCards is an array of ints which represents the deck of cards.
For the moment, you will not implement this until part II of the assignment. You will just have a single line of code in your routine:
cout <<"We are in saveDeck\n";
So the file will look like:
void saveDeck(char fileName [], int deckOfCards [])
{
cout <<"We are in saveDeck\n";
}
Documentation for printDeck
printDeck will be an external procedure which will print out the deck of cards to the terminal window, 13 cards per line. Its protocol is
printDeck(deckOfCards);
It will print each card as 3 characters. The first character is the rank, the second is the suit, and the third character is a blank character to separate each card. The character "T" is used to designate the ten, "J" for the jack, "Q" for the queen, "K" for the king, and "A" for the ace. The character "S" is used to designate spaces, "D" for diamonds, "C" for clubs, and "H" for hearts.
Note that printDeck will call printCard to print out the actual card. Thus printDeck will be a for loop of 52 times, and the for loop will be 3 lines: two lines to check if it is the 13th card, so a endl is printed, and one line which is a call to printCard. printCard will use the discussion above about representation of cards to convert the int representation to the two character representation. After exiting the loop, printDeck will print out a endl so that the next output will be on a new line and not after the last card of the deck.
Documentation for War
The first part of the assignment is just to write the main routine and the two routines shuffle, and printDeck. For now there should be 'stubs' for the routines of war, readDeck, and printDeck.
All that war.cpp will do is that it will put a
cout <<"You are in the routine war" << endl;
and set the two passed ints to zero.
Thus, the code for war will be:
void war(int deck[],int& one, int& two)
{
cout <<"You are in war" << endl;
one = two = 0;
}
The second part of the assignment will be to write the war routine.
Documentation for main
The first part of the assignment is just to write the main routine and the 5 routines readDeck, shuffle, printDeck, printCard, and saveDeck. There should be a 'stub' for the routine of war, as well as the routine of printDeck and readDeck. Note that you can download the cpp file of random here.
Note that you will have completely finished the main.cpp when you finish part I of this project. That is to say, in part II you will not modify the main.cpp. All you will be doing is to put the code inside the stub for merging the arrays. This type of development is referred to as top down development. What we have been doing in the development of the asteroid game is referred to as bottom up development.
main will do the following:
It creates the deck of cards, an array of size 52.
It will first call setRan to set the seed for the random number generator.
It will then ask the user if the cards are to be read from a file or are to be created and shuffled.
If it is to read from a file, the file name is asked for and readDeck is called.
If it is to be created, the deck of cards are initialized, with the ith card set to the value of i. Then shuffle is called.
For both cases the deck of cards is printed out by calling printCards.
It then will call "war" which plays the game and returns the result.
It will print out the results of who won the game and by what score.
It then asks the user for the name of the file where the the array of cards is to saved into a file. It then calls saveDeck which will write the deck of cards to the file.
It terminates the program.
Note that for this part, three of the methods will just have a cout statement as their body. However, main will not "know" this and will call them anyway.
So what you are doing in part one is shuffling a deck of cards and printing out the shuffled cards, 13 cards to a line.
Note: To read in the file name, you use
char fileName [40];
cin>>fileName;
Creating a Header File
You will need to have a header file, whose contents will be the prototypes of all of the external functions:
void printDeck(int deck []);
void printCard(int card);
void shuffle(int deck []);
void setRan();
int ran(const int k);
void war(int deckOfCards[],int& one,int& two);
void readDeck(char fileName[],int deckOfCards[]);
void saveDeck(char fileName [],int deckOfCards []);
This file will have to be included in each of the files that you have of source code. You use the same syntax as you did with program4 with the "win.h".
Various hints will be given in class.
What to Hand-in
You should post your project as a 'zip' file on the COL website. The zip file should only be the .cpp and .h files you created.
Also indicate how many hours you worked on the program in the Readme.txt file.