Link to my code is at the bottom end. This is the assignment specs: Alright, so
ID: 3641566 • Letter: L
Question
Link to my code is at the bottom end.
This is the assignment specs:
Alright, so my problem is, despite codepad responding with warnings, i am able to compile and run the program using Dev C++. Everything works fine except when playing in "smart mode", i think it has to do with my powers_of_2 function, but I don't know what's wrong, so if someone could help me fix this (and please put comments next to the code so I know what you did) i'll definitely rate LIFESAVER!!
Explanation / Answer
//#include <cstdlib> //don't need
#include <iostream>
#include <string>
#include <ctime>
#include <cmath>
using namespace std;
int user_play(int &pile);
int computer_play(int &pile, string &mode);
int power_of_2(int n);
int main(int argc, char *argv[])
{
string ans, mode;
srand(time(NULL)); //seeding random function
do
{
cout << "Welcome to the Game of Nim!!" << endl << endl
<< "Rules: The number of stones you take away must be between 1 and" << endl
<< "half of the total pile inclusive. " << endl
<< "The one who takes the last marble loses. " << endl << endl;
int pile = rand() % 91 + 10;
cout << "The game starts out with a size of " << pile << " stones. ";
int player1 = rand() % 2;
if (player1 == 0)
cout << "The computer gets to go first. ";
else
cout << "You go first. ";
cout << "Choose the mode for the computer, naive or smart? ";
cin.sync(); //use sync() instead of ignore(),
//because sometimes ignore() consumes
//the 1st letter of the input string
getline(cin, mode);
cout << endl;
int nim = pile;
while (nim !=1)
{
if (player1 == 1) // *
{
user_play(nim);
player1 = 0; //player1 is currently 1 (see * above).
//To switch player change it to 0
}
else
{
computer_play(nim, mode);
player1 = 1;
}
}
if (player1 == 1)
cout << " You are forced to take the last marble "
<< "THE COMPUTER WINS! Better luck next time! ";
else
cout << " The computer is forced to take the last marble, YOU WIN! ";
cout << " Do you want to play again? ";
cin.sync(); //use sync() instead of ignore()
getline(cin,ans);
cout << endl;
}
while ((ans.compare("yes") == 0) || (ans.compare("y") == 0)); //use string compare() to compare 2 strings
//system("PAUSE"); don't use system("PAUSE"). Use cin.sync(); cin.get(); instead.
cin.sync();
cin.get();
return EXIT_SUCCESS;
}
int user_play(int &pile)
{
int stones;
int tries = 1; //you don't have to initialize tries with a very large number
while (tries) //c++ is not a type-safe language. You can use integers as booleans.
//integers have value of 0 is false and other values is true
//so (tries) is equal to (tries != 0)
{
cout << "Enter the number of marble(s) you wish to take away: ";
cin >> stones;
if (1 <= stones && stones <= pile / 2)
{
pile = pile - stones;
cout << "There is/are " << pile << " marble(s) left. " << endl;
tries = 0;
}
else
{
cout << "Error! Please enter a number between 1 and "<<pile/2<<" inclusive. ";
//tries --; //why decrement a number that is suppose to be infinite?
//initialize it to 1 and don't decrement it
}
}
return 0; //int function should return an int.
//You should make user_play() a void function
//and you don't have to return any number
// void user_play(int &pile)
}
int computer_play(int &pile, string &mode) //you need to pass string mode to computer_play()
{
//string mode;
if((mode.compare("naive") == 0) || (mode.compare("n") == 0)) //use string compare
{
int stones = rand() % (pile / 2) + 1;
pile = pile - stones;
cout << "The computer took away " << stones << " nim marble(s). "
<< "There is/are " << pile << " nim marble(s) left. ";
}
else
{
int stones = pile - power_of_2(pile);
if (stones > pile / 2)
stones = rand()%(pile/2)+1;
pile = pile - stones;
cout << "The computer took away " << stones << " nim marble(s). "
<< "There is/are " << pile << " nim marble(s) left. " << endl;
}
return 0; //use void function and you don't need this line
}
int power_of_2(int x)
{
if (x == 2) return 1;
int i = -1;
while ((int)pow(2.0, i++) < x);
i -= 2; //for example x = 65, the first 2^i > x is 2^7 = 128
//but you use postfix increment i++,
//so after 2^7 > 65 it will increment i to 8
//you need 2^6 or i = 6. Hence, you must decrease i by 2
//or put i++ in the body of the while loop:
/*
while ((int)pow(2.0, i) < x)
i++;
i--; //if 2^i > x then it will terminate the loop,
//thus not increment i one more time,
//and you only need to decrease i by 1
*/
return ((int)pow(2.0, i) - 1);
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.