Home > other >  Generating a random number for players in a dice game
Generating a random number for players in a dice game

Time:01-30

I am writing a simple dice game where two players play against each other. The winner is the one who gets the largest number when the dice is rolled. However, when I press enter to make a random number get generated for the first player, I just get new empty lines. Here is the code:

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>

using namespace std;

int main()
{
    srand(time(0));
    
    int p1 = (rand() % 6)   1;
    cout << "Player 1: Press enter to roll your dice" << endl;
    cin >> p1;

    
    int p2 = (rand() % 6)   1;
    cout<<"Player 2: Press enter to roll your dice" << endl;
    cin >> p2; 
    

     if(p1 == p2) 
      {
          cout<<"You tied! \n";
      }
      
      else if(p1 > p2)
      {
          cout<<"You won! \n";
      }
      
      else
      {
          cout<<"You lost! \n";
      }
}

CodePudding user response:

You're trying to prompt the user for discardable action, but in-fact actually requesting they provide integer input to the console (which, inconveniently, will overwrite the random draws you just pulled).

When the stream is in a good state:

cin >> p1;

will attempt to read a formatted integer off the stream. During this attempt, whitespace (including newline) will be ignored. Therefore, until such time as you (a) enter a valid integer, (b) enter any non-whitespace that will fail to be parsed as an integer, or (c) the stream is already in EOF state so any further pulls without clearing are going to fail, so you're just left staring at an input prompt.

What you seem to really want is to just ignore data on the input stream until such time as a newline is entered (or EOF is encountered). One way to do that is to use the stream ignore member. For example:

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

will pull all input from std::cin and discard it until such time as a newline is entered, or the stream reaches and error or eof state. Using that, what you probably really want is this:

#include <iostream>
#include <limits>
#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
    srand(static_cast<unsigned>(time(0)));

    int p1, p2;

    cout << "Player 1: Press enter to roll your dice" << endl;
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    p1 = (rand() % 6)   1;

    cout << "Player 2: Press enter to roll your dice" << endl;
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    p2 = (rand() % 6)   1;

    cout << "Player 1: " << p1 << '\n';
    cout << "Player 2: " << p2 << '\n';

    if (p1 == p2)
    {
        cout << "You tied! \n";
    }

    else if (p1 > p2)
    {
        cout << "Player 1 won! \n";
    }

    else
    {
        cout << "Player 2 won! \n";
    }
}

I'd use <random> for the actual draw, but that is unrelated to the root problems in your posted code.

CodePudding user response:

To get an Enter key press you need to read the newline. In C that’s the rather wordy:

#include <iostream>
#include <limits>

std::cin.ignore( std::numeric_limits <std::streamsize> ::max(), '\n' );

Note that your program really does not need user input as it is written — everything that happens is independent of the user’s action.

RNG and the Pigeonhole Principle

Whatever RAND_MAX is on your system, if it isn’t 32767 it is probably a number of the form 2n-1. This doesn’t divide nicely by 6. So you are more likely to get a random number of 0 than 2 or 5, for example.

The way to fix this is to ignore numbers past some multiple of 6.

int multiples = RAND_MAX / 6;
int new_rand_max = multiples * 6;

If the value from rand() is not strictly less than new_rand_max then you can just throw it away.

while ((x = rand()) >= new_rand_max) ;

Now you can get the remainder and return that:

return x % 6;

Put all that in a function, making 6 an argument value, and you are good to go!

int random( int n )
{
  int max = (RAND_MAX / n) * n;
  int result;
  while ((result = rand()) >= max) ;
  return result % n;
}

And to use it:

int p1 = random( 6 )   1;
  •  Tags:  
  • Related