Filling an 8x8 class template array with UNIQUE random numbers from -50 to 50 .

I'm on a mini game project for my first c++ class and there's this thing i've been stuck on for like 2 weeks now , i hope i can find my savior ! what i'm looking for is to fill an 8x8 class template array (not built-in) with UNIQUE random numbers from -50 to 50 . well i got it working but i got some identical numbers . I really need help . Thank you . (we cannot use vectors)
Last edited on
Put the numbers -50 to 50 in a vector of size 101.
Shuffle them using std::shuffle.
Put the first 64 in your 8x8 array.
Imagine that you have a deck of 101 unique cards that have numbers -50..50 on them.
http://www.cplusplus.com/reference/numeric/iota/

First you suffle that deck: http://www.cplusplus.com/reference/algorithm/shuffle/

Then put the first 64 cards into the array. They will be unique.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <algorithm>
#include <chrono>
#include <iostream>
#include <random>
#include <vector>

int gameboard[8][8];

void initialize_gameboard( std::ranlux48& rng )
{
  std::vector <int> numbers( 101 );
  std::iota( numbers.begin(), numbers.end(), -50 );
  std::shuffle( numbers.begin(), numbers.end(), rng );
  auto iter = numbers.begin();
  for (int row = 0; row < 8; row++)
  for (int col = 0; col < 8; col++)
    gameboard[row][col] = *iter++;
}

int main()
{
  std::ranlux48 rng( std::chrono::system_clock::now().time_since_epoch().count() );
  initialize_gameboard( rng );

  for (int row = 0; row < 8; row++)
  {
    for (int col = 0; col < 8; col++)
      std::cout << gameboard[row][col] << "\t";
    std::cout << "\n";
  }
}

You haven’t seen complicated.
oh yes , i forgot to say that we cannot use vectors :/ thank you anyway but if you can do it just using arrays , loops ,bool , and u know , kinda basic stuff..
 
  int numbers[ 101 ];

It doesn’t get more basic.
The links that I did give do show that iota and shuffle are essentially simple loops.


If someone claims that you cannot use:
1
2
3
4
5
#include <chrono>
#include <random>
std::ranlux48
std::chrono::system_clock
std::uniform_int_distribution

Then ask confirmation that surely the equivalent (but inferior):
1
2
3
4
5
#include <cstdlib>
#include <ctime>
srand()
rand()
time()

are equally banned.
yes . those can be used . sorry about that but that's what the course instructor wants .
#include <cstdlib>
#include <ctime>
srand()
rand()
time()
You know, I wish more students would push back when confronted with 30-year old practices.

C++ has had the random library since before 2011, and rand() has been known to be a bad RNG for 30 years.
That rand() % N is still taught is inexcusable.

If learning C++, learn friggin C++, not C, and not stuff that is twice as old as the student body.

Complain to the board about the quality of your education being 30 years out of date.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <cstdlib>
#include <ctime>

int gameboard[8][8];

// Get a random number the CORRECT way
// (Simplified version. Don't use a tiny a range.)
//
int random_int_in_range( int a, int b )
{
  int n;
  do n = rand(); while (n < a || n > b);
  return n;
}

// Knuth-Fisher-Yates random shuffle
//
void swap( int* a, int* b )
{ 
  int 
   c = *a;
  *a = *b;
  *b =  c;
}

void shuffle( int* xs, int n )
{
  if (n--)
    while (n)
    {
      swap( xs, xs + random_int_in_range( 1, n-- ) );
      xs++;
    }
}

void initialize_gameboard()
{
  int numbers[ 101 ];
  for (int n = 0; n < 101; n++) numbers[n] = n + -50;
  shuffle( numbers, 101 );
  int* n = numbers;
  for (int row = 0; row < 8; row++)
  for (int col = 0; col < 8; col++)
    gameboard[row][col] = *n++;
}

int main()
{
  std::srand( std::time( nullptr ) );
  initialize_gameboard();
  
  for (int row = 0; row < 8; row++)
  {
    for (int col = 0; col < 8; col++)
      std::cout << gameboard[row][col] << "\t";
    std::cout << "\n";
  }

Enjoy!
Feels like hard work! Highly inefficient.

trusttheprocess wrote:
oh yes , i forgot to say that we cannot use vectors :/ thank you anyway but if you can do it just using arrays , loops ,bool , and u know , kinda basic stuff..

I'm amazed: you can use a "class template array" but you can't use a vector!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <iomanip>
#include <ctime>
#include <cstdlib>
using namespace std;

const int SIZE = 8;
const int LOW = -50, HIGH = 50;

void getRandomNumbers( int a[], int N )
{
   for ( int i = 0; i < N; i++ )
   {
      bool seen;
      int x;
      do
      {
         x = LOW + rand() % ( HIGH - LOW + 1 );
         seen = false;
         for ( int j = 0; j < i; j++ )
         {
            if ( x == a[j] ) 
            {
               seen = true;
               break;
            }
         }
      } while( seen );
      a[i] = x;
   }
}


void printBoard( int board[SIZE][SIZE] )
{
   for ( int i = 0; i < SIZE; i++ )
   {
      for ( int j = 0; j < SIZE; j++ ) cout << setw( 4 ) << board[i][j];
      cout << '\n';
   }
}


int main()
{
   srand( time( 0 ) );

   int a[SIZE * SIZE];  
   getRandomNumbers( a, SIZE * SIZE );
   
   int board[SIZE][SIZE];
   int pos = 0;
   for ( int i = 0; i < SIZE; i++ )
   {
      for ( int j = 0; j < SIZE; j++ ) board[i][j] = a[pos++];
   }
   
   printBoard( board );
}


  15  12   1  14  -3 -32 -11 -43
 -33 -22 -31 -30  45  48  49 -34
  -9 -10  19   2  44  10  24  18
  40 -21  28 -17 -45  34 -26  13
 -24   8  -5  33  -6  27  -8  20
  43  -1  26 -23 -29   6  47  50
 -35  21  -4   0 -18  -7  17 -16
 -14 -47  16 -27  39 -20  38 -41
Last edited on
Thank you guys , really ! And yes , that's what we students here in Lebanon are suffering from . The VERY slow pace of evolution in our courses material , and not only in programming . Complaints have been submitted but it's a waste of time . We here are just doing our best to get our degrees so we can move to another country.
Ah, yes. Sadly, computer science education in the Middle East is typically very poor. You should probably count yourself lucky you aren’t being forced to do this with Turbo C++ 4.0.
closed account (E0p9LyTq)
Duthomhas wrote:
That rand() % N is still taught is inexcusable.

I've mentioned the shortcomings of the C library PRNG routines when replying to more than a few questions and got stomped on by some people, long time posters with more C++ experience than I have, saying the C random routines are "good enough for trivial purposes."

Using the C++ <random> & <chrono> libraries is not all that hard to learn, if someone really wants to learn. The ways the PRNG objects are used just looks complicated since they are scary looking.

srand(time(0));
vs.
std::default_random_engine eng (std::chrono::system_clock::now().time_since_epoch().count());

Duthomhas wrote:
If learning C++, learn friggin C++, not C, and not stuff that is twice as old as the student body.

Amen! Preach it, Brother! Testify! :)
FurryGuy wrote:
I've mentioned the shortcomings of the C library PRNG routines when replying to more than a few questions and got stomped on by some people, long time posters with more C++ experience than I have, saying the C random routines are "good enough for trivial purposes."

Alas, this is a common defect in the collective consciousness of C and C++ programmers.

The reality is that relatively few people actually understand how random numbers really work, especially when it comes to initialization and CSPRNGs. For most programmers it is a magical black box, even for those who have been around for a while—

And the reason is... it is because that is how they have been taught!

(Either by formal schooling or by other big egos who have told them the same crap when they asked about RNGs.)


They wrote:
good enough for trivial purposes

Technically true, maybe, but what is a “trivial purpose”?

If you can name anything except simple video games and MyFirstProgram™, you are probably ahead of the game in understanding the relative uselessness of rand().


The sad thing is, there really isn’t a whole lot to learn about high-quality random numbers. A good, inexhaustible CSPRNG is actually pretty easy* to create, so long as you make sure to cross your 'T's and dot your 'I's.

*Don’t confuse easy for just a few lines of code. The actual effort is rather involved. But, that said, you would still surprised how short and simple powerful TPRNG → STRNG → CSPRNG systems are.


And the best part of it all? Modern operating systems do all the hard work for you!
Hence the reason for my (CSPRNG Library|https://github.com/Duthomhas/CSPRNG)
/shameless plug

It makes using high-quality random numbers in C and C++ stupidly easy.


In any case, it is long past time to begin teaching C++’s random number capabilities over something people like because it is short and brain-off required.
Topic archived. No new replies allowed.