Write a program for playing a variation of the Chinese game ”Tsyan-shizi” called
ID: 3739850 • Letter: W
Question
Write a program for playing a variation of the Chinese game ”Tsyan-shizi” called the game of NIM. Our version of the game starts with up to 20 rods and up to 10 stones in each rod. Two players take turns removing stones from the rods. On a player’s turn, she chooses a rod and removes one or more stones from that rod. She can remove all stones from the rod. The player who takes the last stone from the rods (so that all rods are empty) wins. DO NOT delete the code already given to you in the code template. You must use the code given to you in the template in your solution.
You will implement the following algorithm in the main function. Each line in the algorithm will correspond to a function call. Important! Write your code incrementally. This means you should write each function one at a time, check that it compiles and runs properly, test it, and then implement the next function.
i. Prompt and read the number of rods
ii. Prompt and read the number of stones in each rod;
iii. Draw the rods with percentages;
iv. Display statistics;
v. while (some rod is NOT empty) do
vi. Prompt and read the next player’s move (Prompt and read the rod to modify and the number of stones to remove from the rod);
vii. Remove the specified number of stones from the specified rod;
viii. if (all rods are empty) then
ix. Print a message congratulating the winning player.
x. else
xi. Redraw the rods with percentages;
xii. Display statistics;
xiii. Change to the other player;
xiv. end
xv. end
1. All functions should be written AFTER the main procedure.
2. All function prototypes should be written for each function and placed BEFORE the main procedure.
3. Each function should have a comment explaining what it does.
4. Each function parameter should have a comment explaining the parameter. 2
5. Your program MUST NOT use any global variables nor any global constants.
6. In addition to implementing the above algorithm in the main function, you must define the following constants and variables in the main function: - Define two constants to hold the maximum number rods (20) and the maximum number of stones per rod (10). - The list of rods will be stored in an array of integers, where each integer represents the number of stones in that rod. Define a pointer variable for this array (see the lecture notes on ”Arrays and Pointers”). Also define an integer to hold the size of this array. - Define a variable that represents the current player (1 or 2).
7. Important: PLEASE READ! The following description provides specifications for the functions you will write that includes input parameters and return values. You are responsible for implementing these functions as described in these specifications in order to receive full credit. These functions may call additional helper functions that you define. You must determine good function names as well as good variable names for your function parameters and local variables. You must correctly identify whether a function parameter should be passed by value or passed by reference. In addition you must correctly determine whether a function parameter should be declared with the const specifier. Remember, const is used to indicate that the function parameter is not modified in the function (see the lecture notes). It may be applied to a parameter that is either passed by value or passed by reference. It allows code developers to better undertand your code and ensure that they (and you) adhere to your specifications if they want to modify the code.
8. Write a function to implement step (i) of the algorithm. Define the function to have one input parameter that holds the maximum number of rods (see the constant defined above) and return an integer. Prompt the user for the number of rods used in the game. If the number entered is not between 1 and the maximum number of rods then display a warning message and prompt again. This is called input validation on the user’s input.
9. In the main function, allocate an array in the declared array pointer representing the list of rods (see description above) to have the same size as the number of rods returned from the function in step (i).
10. Write a procedure (this is a function that does not return a value and so is declared with a return type of void) that implements step (ii) of the algorithm. Define the procedure to have three input parameters: the array of rods, the size of the array, and the maximum number of stones per rod (see the constant defined above). This 3 procedure will traverse the array of rods and call the following helper procedure for each rod in the list. - Write a helper procedure that will prompt the user for the number of stones to place on this rod. If the number of stones entered for the rod is not between 1 and the maximum number of stones allowed then display a warning message and prompt again. Define this helper procedure to have three input parameters: the array entry for this rod (use pass by reference), the array index for this rod, and the maximum number of stones per rod. Important: Again, a procedure is a function that has no return value. You must define these functions as procedures by defining their return type as void.
11. Write a procedure to draw the rods to implement steps (iii) and (xi) of the algorithm. Draw each rod on its own row. In the row for rod i, there is a label ”Rod i: ” followed by n *’s where n is the number of stones in rod i. The procedure should output an empty line before and after the first and last rows, respectively. For instance if rod 0 has 3 stones, rod 1 has zero stones, and rod 2 has 8 stones, the procedure (and helper procedures) should output: Rod 1: *** (27.273%) Rod 2: (0.000%) Rod 3: ******** (72.727%) Define the procedure to have two input parameters: the array of rods and the size of the array. First, calculate the total number of stones in the array of rods. Next, traverse the array of rods and call a helper procedure to display each complete row. - Write the helper procedure to have three input parameters: the array index for this rod, the number of stones for this rod, and the total number of stones in the array of rods. The percentage displayed at the end of each row is the fraction of stones on this rod given the total number of stones in the array of rods (you just computed). Format each row using setw in iomanip and avoid using hard coded spaces. When there are ten or more rods to display, your output must align the labels ”Rod ?:” and ”Rod ??:” appropriately, where ”?” is a digit. Use setw to format the text between ”Rod” and the ”:”. Using setw, format the *’s in a column of size ten that is left justified (look up the ”left” specifier under iomanip). There needs to be five spaces between the column of *’s and the percentage. Do NOT hard code these five spaces. Instead, use setw to format the last column for the percentage. Look up how to use the ”right” specifier in iomanip to help you solve this problem. Also, format the percentage to show three digits after the decimal place. Decide if additional helper functions/procedures would be useful here. 4
12. Write a procedure to display the statistics for the list of rods that will be called in steps (iv) and (xii) of the algorithm. The statistics are 1) The rods with the smallest number of stones, 2) The rods with the largest number of stones, and 3) The average number of stones per rod taking into account only rods with stones. Define the procedure to have two input parameters: the array of rods and the size of the array. This procedure will call three helper procedures. - Write a helper procedure to display the rods with the smallest number of stones. This procedure will have two input parameters: the array of rods and the size of the array. Note that there may be more than one rod with the smallest number of stones. - Write a helper procedure to display the rods with the largest number of stones. This procedure will have two input parameters: the array of rods and the size of the array. Note that there may be more than one rod with the largest number of stones. - Write a helper procedure to display the average number of stones per rod, but only taking into account rods with at least one stone. The average must be formatted to display two digits after the decimal place.
13. Write a function which returns true (boolean) if all the rods have zero stones and returns false otherwise. Call this function to implement steps (v) and (viii) of the algorithm. Note that the same function will be used for both steps.
14. Write a procedure to implement step (vi) of the algorithm where the current player makes her next move. Define the procedure to have five input parameters: the array of rods, the size of the array, player id, which rod chosen by the player on this turn, and how many stones the player would like to remove from this rod. The player id is either the integer 1 or 2 to indicate which player is taking a turn. This procedure will perform two steps with the help of helper functions/procedures as specified below: 1) Using the following helper functions and procedures, prompt and read for the rod from which to remove stones. If the player inputs an invalid rod id or chooses a rod with no stones then display a warning message and prompt again. These three helper functions/procedures will be called from this procedure. In addition, the last two helper procedures will call the first helper function. - First, write a helper function to have one input parameter, the player id. Prompt the player to choose a rod (rod id) and then return this value. Thus, this helper function has a return type that is NOT void. Do not perform any input validation in this function. - Next, write a second helper procedure to have three input parameters: the player id, the rod selected by this player, and the total number of rods (i.e., the size of the array of rods). This procedure will validate the rod selected by this player, i.e. the rod selected must be between 0 and n - 1 where n is the total number of rods. If the rod 5 selected is invalid then the procedure displays a warning message and prompts for rod selection again by calling the first helper function. - Finally, write a third helper procedure to have three input parameters: the array of rods, the player id, and the rod selected by this player. This procedure will validate whether the rod selected has at least one stone. If the rod selected is invalid then the procedure displays a warning message and prompts for rod selection again by calling the first helper function. 2) Using the following helper function, prompt and read how many stones to remove from the chosen rod. If the player inputs an invalid number of stones then display a warning message and prompt again. The number of stones to remove must be positive and must not exceed the number of stones on the chosen rod. The following helper function will be called from this procedure and will perform the following task described below. This procedure will check if the returned value from the helper function is valid and prompt the user again if necessary. - Write a helper function to have two input parameters: the number of stones on the chosen rod and the rod id. The function will prompt the player for the number of stones to remove from the indicated rod and returns this value. Note this helper function will NOT perform any input validation checks. Instead the calling procedure will perform validation on the returned value from this helper function.
15. Write a procedure to implement step (vii) of the algorithm. Define the procedure to have three input parameters: the array of rods, the rod id of the chosen rod, and the number of stones to remove. This function will modify the array of rods by subtracting the specified number of stones from the chosen rod.
16. Write a procedure to implement step (ix) of the algorithm. Define the procedure to have a single input parameter that holds the player id. The procedure will print a message congratulating this winning player. The message should identify who won (player 1 or player 2).
17. Write a procedure to implement step (xiii) of the algorithm. Define this procedure to have a single input parameter that holds the player id. This procedure will switch the turn to the other player. In other words, if the player indicated in the input parameter is 1, then the procedure should change this value to 2. If the player indicated in the input parameter is 2, then the procedure should change this value to 1.
18. Be sure to modify the header comments ”File”, ”Created by”, ”Creation Date”, and ”Synopsis” at the top of the file. Each synopsis should contain a brief description of what the program does.
19. Be sure that there is a comment documenting each variable. 6
20. Be sure that your if statements, for and while loops and blocks are properly indented.
21. Check your output against the output from the solution executable provided.
pickstones.cpp template:
#include <iostream>
#include <iomanip>
using namespace std;
// FUNCTION PROTOTYPES GO HERE:
int main()
{
// Define variables and constants here
// Algorithm:
// Prompt and read number of rods
// Prompt and read the number of objects in each rod
// Draw the rods with percentages
// Display statistics
// WHILE some rod is NOT empty DO
// Prompt and read the next player's move
// Remove the specified number of objects from the specified rod
// IF all the heaps are empty, THEN
// Print a message congratulating the winning player.
// ELSE
// Redraw the rods with percentages
// Display statistics
// Change to the other player
// END IF
// END WHILE
return 0;
}
// FUNCTION DEFINITIONS GO HERE:
These are my function parameters:
// Parameter to read in number of rods
int read_rods(int maxrods);
// Parameter to read in number of stones per rod
void read_stones(int rods[], int size, int maxstones);
// Helper parameter for number of stones to place on each rod
void place_stones(int rods[], int rod,int maxstones);
// Parameter to draw rods
void draw_rods(int rods[], int size);
// Helper parameter to display percentage
void display_percentage(int rod, int num_stones, int total_stones);
// Parameter to display statistics
void display_stats(int rods[], int size);
// Helper parameter to display rods with the smallest number of stones
void smallest_stones(int rods[], int size);
// Helper parameter to display the rods with the largest number of stones
void largest_stones(int rods[], int size);
// Helper parameter to display the average number of stones per rod
void avg_stones(int rods[], int size);
// Parameter to check empty rods
bool empty_rods(int rods[], int size);
// Parameter for player to make their move
void make_move(int rods[], int size, int player, int & rod, int & how_many_stones);
// Helper parameter for player to choose rod
int choose_rod(int player);
// Helper parameter to validate rod chosen
void validate_rod(int player, int rod, int size);
// Helper parameter to validate if the rod selected has at least one stone
void validate_stones(int rods[], int player, int rod);
// Parameter to pick rod to remove from
int rod_picked(int rods[], int size, int player);
// Helper parameter to prompt player for number of stones to remove
int remove_stones(int rod);
// Parameter to validate the stone removal
void validate_removal(int rod, int num_stones, int how_many_stones);
// Parameter to pick stone removed from rod
int stone_picked(int rods[], int rod);
// Parameter to modify rod
void modify_rod(int rods[], int rod, int how_many_stones);
// Parameter to congratulate winner
void winner(int player);
// Parameter to switch players
void switch_players(int & player);
Explanation / Answer
code:
#include <iostream>
#include <string>
#include <iomanip>
#include <algorithm>
using namespace std;
bool verify(int[],int,int);
int main ()
{
const int MAX_RODS=20; int rods;bool ch=true;int pid,rod,nos,count=0;
const int MAX_STONES=10;
int ROD_ARRAY[MAX_RODS];
int check_max_rods(int);
void load(int[], int, int);
void print_rods(int[],int);
void print_stats(int[],int);
bool check_status(int[],int);
void play_NIM(int[],int,int, int, int);
rods=check_max_rods(MAX_RODS);
cout<<"rods : "<<rods;
load(ROD_ARRAY, rods, MAX_STONES);
while(ch)
{
print_rods(ROD_ARRAY,rods);
print_stats(ROD_ARRAY,rods);
if(count%2== 0)
{
pid=2;
cout<<" ....Player1 turn!!!.... ";
cout<<" Player1 choose the rod number: ";
cin>>rod;
cout<<" How many stones you want to remove :";
cin>>nos;
play_NIM(ROD_ARRAY, rods, pid, rod-1, nos);
}
else
{
pid=1;
cout<<" ....Player2 turn!!!.... ";
cout<<" Player2 choose the rod number: ";
cin>>rod;
cout<<" How many stones you want to remove :";
cin>>nos;
play_NIM(ROD_ARRAY, rods, pid, rod-1, nos);
}
ch= check_status(ROD_ARRAY,rods);
count++;
}
system("pause");
}
//code to ensure maximum rods 20
int check_max_rods(int x)
{
int num;
cout<<" Please enter the number of rods: ";
cin>>num;
if(num> x)
{cout<<"Maximum rods is : 20"; check_max_rods(20);}
else
{return num;}
}
//code to set stones in the rod
void load(int ROD_ARRAY[],int rods, int maxstn)
{
int k;
for(int i=0;i< rods;++i)
{
cout<<" Enter number of rods to b placed in ROD_"<<(i+1)<<" : ";
cin>>k;
if(k <= 10 && k>=0)
{ROD_ARRAY[i]=k;}
else
{cout<<" Please enter values between 0 to 10";i--;}
}
}
//code to print all the rods with percentage
void print_rods(int ROD_ARRAY[],int rods)
{
int i=0,sum=0;
//system("cls");
for(int j=0;j<rods;++j)
{sum=sum+ROD_ARRAY[j];}
cout<<"---- G A M E S T A T U S ---- ";
for(i=0;i<rods;++i)
{
if(ROD_ARRAY[i]==0)
{cout<<" ROD_"<<i+1<<" ";std::cout<<std::fixed<<" ( "<<std::setprecision(3)<< (0/(float)sum*100)<<"% )";}
if(ROD_ARRAY[i]==1)
{cout<<" ROD_"<<i+1<< "* ";std::cout<<std::fixed<<" ( "<<std::setprecision(3)<< (1/(float)sum*100)<<"% )"; }
if(ROD_ARRAY[i]==2)
{cout<<" ROD_"<<i+1<< "* * ";std::cout<<std::fixed<<" ( "<<std::setprecision(3)<< (2/(float)sum*100)<<"% )"; }
if(ROD_ARRAY[i]==3)
{cout<<" ROD_"<<i+1<< "* * * ";std::cout<<std::fixed<<" ( "<<std::setprecision(3)<< (3/(float)sum*100)<<"% )"; }
if(ROD_ARRAY[i]==4)
{cout<<" ROD_"<<i+1<< "* * * * ";std::cout<<std::fixed<<" ( "<<std::setprecision(3)<< (4/(float)sum*100)<<"% )"; }
if(ROD_ARRAY[i]==5)
{cout<<" ROD_"<<i+1<< "* * * * * ";std::cout<<std::fixed<<" ( "<<std::setprecision(3)<< (5/(float)sum*100)<<"% )"; }
if(ROD_ARRAY[i]==6)
{cout<<" ROD_"<<i+1<< "* * * * * * ";std::cout<<std::fixed<<" ( "<<std::setprecision(3)<< (6/(float)sum*100)<<"% )"; }
if(ROD_ARRAY[i]==7)
{cout<<" ROD_"<<i+1<< "* * * * * * * ";std::cout<<std::fixed<<" ( "<<std::setprecision(3)<< (7/(float)sum*100)<<"% )"; }
if(ROD_ARRAY[i]==8)
{cout<<" ROD_"<<i+1<< "* * * * * * * * ";std::cout<<std::fixed<<" ( "<<std::setprecision(3)<< (8/(float)sum*100)<<"% )"; }
if(ROD_ARRAY[i]==9)
{cout<<" ROD_"<<i+1<< "* * * * * * * * * ";std::cout<<std::fixed<<" ( "<<std::setprecision(3)<< (9/(float)sum*100)<<"% )"; }
if(ROD_ARRAY[i]==10)
{cout<<" ROD_"<<i+1<< "* * * * * * * * * * ";std::cout<<std::fixed<<" ( "<<std::setprecision(3)<< (10/(float)sum*100)<<"% )"; }
}
}
//code to print statistic of the game
void print_stats(int ROD_ARRAY[],int rods)
{
int arr[20],sum=0;
cout<<" ... G A M E S T A T I S T I C S...";
for(int i=0;i<rods;++i)
{arr[i]=ROD_ARRAY[i];sum =sum+arr[i];}
sort(arr, arr + rods);
cout<<" Rod with smallest number of stones: "<<arr[0];
cout<<" Rod with smallest number of stones: "<<arr[rods-1];
cout<<" Average number of stones in rods: "<<sum/rods;
}
//code to check all rods are empty or not
bool check_status(int ROD_ARRAY[],int rods)
{
int flag=1;
for(int i=0;i<rods;++i)
{
if(ROD_ARRAY[i]== 0)
{flag=0;}
else
{flag=1;}
}
if(flag==0)
{return false;}
else
{return true;}
}
//code to remove stones from the rod
void play_NIM(int ROD_ARRAY[],int rods ,int pid, int rod, int nos)
{
bool sts,final;
sts= verify(ROD_ARRAY,rod,nos);
if(sts == true)
{
ROD_ARRAY[rod]=ROD_ARRAY[rod]-nos;
final=check_status(ROD_ARRAY,rods);
if(final==false)
{
if(pid==1)
{cout<<" GAME OVER!!! Player_2 wins";}
else
{cout<<" GAME OVER!!! Player_1 wins";}
}
}
else
{cout<<" No stones available";}
}
//code to verify weather sufficient number of stones are available
bool verify(int ROD_ARRAY[], int rod, int nos)
{
if(ROD_ARRAY[rod]< nos)
{return false;}
else
{return true;}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.