Search code examples
c++random

Using uniform_int_distribution in a function


I'm using the stackoverflow boilerplate (variable names modified):

std::random_device seed;  
std::mt19937 gen(seed()); 
std::uniform_int_distribution<> d6(1, 6);
std::cout << std::endl << "roll = " << d6(gen);  //verifies that the basic generator works

In main(), this works just fine. What I want to do is write a simple function that will take a desired number of dice, roll them, add up the number of times that a dice shows a result meeting some condition, and return this number as an integer. I have not been able to find any combination of parameter types or return types that will accomplish this without throwing an error.

Example function (some pseudo code for brevity):

int dice ( int Pn )
{
   int hit = 0;
   for loop ( starting from 0, exit @ Pn )
   {
       if d6(gen) > 3 hit++;
       if d6(gen) == 6 hit++; //these conditions are arbitrary and only included for completeness
   }
   return hit;
}

Now obviously, I need to pass some parameters to my function dice so it has access to the distribution and generator - I just haven't been able to find any combination of types that won't throw errors.

Here is an example of one such attempt, in full :

#include <iostream>
#include <random>

int dice ( std::uniform_int_distribution<int> , std::mt19937 G , int Pn );

int main()
{  
  std::random_device seed;  
  std::mt19937 gen(seed()); 
  std::uniform_int_distribution<> d6( 1, 6 );
  std::cout << std::endl << "roll = " << d6(gen);
  
  dice ( d6 ( 1 , 6 ) , 12 ); // Roll 12 dice - arbitrary
    
  return 0;
}

int dice ( std::uniform_int_distribution<int> R , std::mt19937 G , int Pn )
{
   int hit = 0;
   int num_dice = Pn;
   for ( int i = 0; i < num_dice; i++ ) // Pn is the number of dice we want to roll
   {
       if ( R(G) > 3 ) hit++;
       if ( R(G) == 6 ) hit++; //these conditions are arbitrary and only included for completeness
   }
   return hit;
}

And here are the resulting errors for this attempt :

main.cpp:13:10: error: no matching function for call to object of type 'std::uniform_int_distribution<>'
  dice ( d6 ( 1 , 6 ) , 12 ); // Roll 12 dice - arbitrary
         ^~
/root/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/__random/uniform_int_distribution.h:207:39: note: candidate function template not viable: no known conversion from 'int' to 'const param_type' for 2nd argument
    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
                                      ^
/root/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/__random/uniform_int_distribution.h:205:39: note: candidate function template not viable: requires single argument '__g', but 2 arguments were provided
    template<class _URNG> result_type operator()(_URNG& __g)
                                      ^
1 error generated.

Solution

  • dice() expects the distribution object itself and a generator object, but you are passing it the result of invoking the distribution, and no generator at all.

    Try changing this:

    dice ( d6 ( 1 , 6 ) , 12 );

    To this instead:

    dice ( d6, gen, 12 );