Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

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!!

 

http://codepad.org/RtxjDQ4E 

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);
}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote