I was given an assignment to make a domino program in which you make a structure to contain info/the numbers on each domino piece, display all of those pieces in a table, and also randomize the pieces and display them after they have been randomized. The only catch is that each of those things must be done in four separate class files: CRandom (creates the random order in which the dominoes will be displayed), CTable(displays the dominoes in an ordered table), CDominoes (contains the struct), and CPlayer (displays the randomly ordered dominoes). Now, I have figured out how write the program, but as a singular program with no classes. What would be the best approach to split the code up into these classes? Here is the code I have (warning: it's long and messy)
#include <iostream>
#include <vector>
#include <string>
#include <ctime>
usingnamespace std;
/*--------------------------
|| CDOMINOES SECTION ||
--------------------------*/
struct data{
int left;
int right;
}piece[28];
vector<data> random;
void setnumbers(){
piece[0].left = 0;
piece[0].right = 0;
piece[1].left = 1 ;
piece[1].right = 1;
piece[2].left = 1;
piece[2].right = 0;
piece[3].left = 2;
piece[3].right = 2;
piece[4].left = 2;
piece[4].right = 1;
piece[5].left = 2;
piece[5].right = 0;
piece[6].left = 3;
piece[6].right = 3;
piece[7].left = 3;
piece[7].right = 2;
piece[8].left = 3;
piece[8].right = 1;
piece[9].left = 3;
piece[9].right = 0;
piece[10].left = 4;
piece[10].right = 4;
piece[11].left = 4;
piece[11].right = 3;
piece[12].left = 4;
piece[12].right = 2;
piece[13].left = 4;
piece[13].right = 1;
piece[14].left = 4;
piece[14].right = 0;
piece[15].left = 5;
piece[15].right = 5;
piece[16].left = 5;
piece[16].right = 4;
piece[17].left = 5;
piece[17].right = 3;
piece[18].left = 5;
piece[18].right = 2;
piece[19].left = 5;
piece[19].right = 1;
piece[20].left = 5;
piece[20].right = 0;
piece[21].left = 6;
piece[21].right = 6;
piece[22].left = 6;
piece[22].right = 5;
piece[23].left = 6;
piece[23].right = 4;
piece[24].left = 6;
piece[24].right = 3;
piece[25].left = 6;
piece[25].right = 2;
piece[26].left = 6;
piece[26].right = 1;
piece[27].left = 6;
piece[27].right = 0;
}
/*--------------------------
|| CRANDOM SECTION ||
--------------------------*/
void randomize(){
constint AMOUNT = 28; //amount of random numbers that need to be generated
constint MAX = 28; //maximum value (of course, this must be at least the same as AMOUNT;
int value[AMOUNT]; //array to store the random numbers in
srand(time(NULL)); //always seed your RNG before using it
//generate random numbers:
for (int i=0;i<AMOUNT;i++)
{
bool check; //variable to check or number is already used
int n; //variable to store the number in
do
{
n=rand()%MAX;
//check or number is already used:
check=true;
for (int j=0;j<i;j++)
if (n == value[j]) //if number is already used
{
check=false; //set check to false
break; //no need to check the other elements of value[]
}
} while (!check); //loop until new, unique number is found
value[i]=n; //store the generated number in the array
random.push_back(piece[n]);
}
}
int main(){
/*--------------------------
|| CTABLE SECTION ||
--------------------------*/
setnumbers();
cout << "CTable Example: " << endl << piece[0].left << "|" << piece[0].right << endl;
for(int i=1; i < 3; i++)
cout << piece[i].left << "|" << piece[i].right << " ";
cout << endl;
for(int i=3; i < 6; i++)
cout << piece[i].left << "|" << piece[i].right << " ";
cout << endl;
for(int i=6; i < 10; i++)
cout << piece[i].left << "|" << piece[i].right << " ";
cout << endl;
for(int i=10; i < 15; i++)
cout << piece[i].left << "|" << piece[i].right << " ";
cout << endl;
for(int i=15; i < 21; i++)
cout << piece[i].left << "|" << piece[i].right << " ";
cout << endl;
for(int i=21; i < 28; i++)
cout << piece[i].left << "|" << piece[i].right << " ";
cout << endl << endl;
/*--------------------------
|| CPLAYER SECTION ||
--------------------------*/
randomize();
cout << "CPlayer Example: " << endl;
for(int i = 0; i < 28; i++)
cout << random[i].left << "|"<< random[i].right<< endl;
return 0;
}
I'm not asking anyone to write the code for me, but rather hints as to how I should start with the header and implementation files. The first thing I did was make the struct data in my CDominoes class, but then soon realized that I don't know how to access and use that struct from the other classes.
Anywhere you have a struct is a good place to start. Also, try to write the names of the classes down and think about what each class should hold and how the rest of your code would interface with the class.
Are you sure they should be done in 4 separate classes? Did the prof mean 4 separate files that implement 4 separate methods? The reason I ask is that it makes no sense (to me anyway) to put this functionality inside separate classes.
Line 15: That's really your CRandom class. It represents the unplayed dominios. It should become a vector<CDomino>. Methods you you might want for this class: Populate(), isEmpty(), Draw(), Display(). I prefer the name CBag for this class, but your prof may not permit renaming the class.
Your CPlayer class should hold up to 6 Dominos. Methods you might want: Remove(), Display(), Draw(), isEmpty().
CTable repsents the dominos that have been played on the table. This could get get tricky depending on how closely you want to follow the rules of dominos. i.e. Doubles are played sideways. Other dominos can be placed off the sideways doubles. I expect for your assignment, this can be disregarded. Methods you might want: PlaceLeft(), PlaceRight() depending on which side of the domino chain you want to place a domino.
LeftValue(), RightValue() return the value of the left or right end of the chain. Hint: you might want a std::deque to allow easy access to both ends.
IMO, the CDominos class should be singular. It should represet a single domino (as your struct does). One or more CDomino instances can be held by the CRandom class, each CPlayer instance and the CTable class.
One other comment:
Line 114: I disagree with calling srand() within your randomize function. Were you to extend your program to allow playing multiple games, you would call randomize() again, which would reset the RNG to the same sequence. The call to srand() belongs after line 144.
Edit: In the CDomino class, you might want a flip() function that transposes left and right sides so that when you place the tile, the side matches the end of the chain where you're placing it.
@dhayden That's what I interpreted his assignment as, since we're learning about separate compilation right now. On the other hand, he doesn't speak a lot of English so maybe I'm misunderstanding what he wants. =_=
edit: This is exactly what he assigned:
1. Have a Class CRandom as sorting approach for the sequence that the domino pieces will be shown/picked.
2. Have a Class CTable to show/display the sorted pieces.
3. Have a Class CDominoes to contain the data structure with pieces.
4. Have a Class CPlayer to select a randomly picked and sequentially show the selected pieces.
5. For attributes and variables from each piece in your dominoes, use a struct named: "struct data{...}..piece" as dynamically allocated vector, properly allocating and making the memory free as appropriate.
6. Make proper initialization and clean up of each class you implemented.