How to make rand generation exclude certain values?

Simple, how do I make it so that when I randomly generate a number, it cannot generate one certain value. The point of this is so that the it does not generate a number it had already created before.
I don't know if you can actually prevent a number from being generated again, but you can prevent it from being used. At the top of my head, I would make it so that a number generated by rand() is stored in an array or something, and then make a check if that same number was generated. If it isn't I'd let it be used, else I would restart the rand() function.
Sorry, I'm a bit of a newb at CPP, can you put that in more layman's terms? Just tell me how to exclude a value from the generation, that way I can just exclude the variables that were generated previously.
Well, are you familiar with loops and arrays?
Is this for dealing a deck?
I'm fa bit familiar with arrays, but not so much loops.

This is for creating a Sudoku board.
You could create the random number, until that number be valid.
Or store in an array all the valid numbers and generate a random index.
Remember, I'm a total newb, so how do I generate a random index of an array? Can you give some example code?
1
2
3
4
5
int values[10];  //store the valid numbers (not necessary full)
int size; //the actual number of values
//So the index should be from 0 to size-1
int index = rand() % size;
return values[index]; //what you put in the board 
CCNezin, if you know arrays, that's good:

1
2
3
4
5
6
//Declaration of an array:
type variable_name[number];
type variable_name[] = {0, 0, 0, 0};

//To access the value stored in an element, you do this:
variable_name[x]; //where x is the index of the element. 


The first array is merely given a size. For instance, if I would replace number with 10, the size of the array would be 10, that is, it would hold 10 elements. In the second array, we do not need to give it its size because the size is determined by the number of elements, in this case 4. To clarify, an element is basically a "slot" with a value can be stored. An index is basically the "slot number". The first index is always 0. An array with 10 elements (slots) would have 0 as its first number, and 9 as its last number. So the last element of n array is always (size of array) - 1. As a side note, when dealing with char arrays, remember that it needs to be null terminated, which means that the last element must contain the character '\0'.

As for loops, read up on these loops: while and for. I like for loops when dealing with arrays. For example, assume you create this array:

1
2
3
4
5
6
7
8
//exampleArray is of the type int and its size is 4. Thus, it has 4 elements
//that are number from 0 to 3. 0 contains the value 2, 1 contains the value 6,
//2 contains the value 12 and 3 contains the value 28.
int exampleArray[] = {2, 6, 12, 28};

//And you can use a for loop to print out the value of every element:
for (int i = 0; i < 4; i++)
  std::cout << exampleArray[i] std::endl;


You can read up on for loops on the main site here. But essentially, it first declares a variable called i, and it does so only once when the loop is first initialized. It then checks that the value of i is less than 4. THEN it runs the code within the loop. When it's done with that, it adds 1 to the value of i (so if the value of i was 4, it will now be 2+1 which is 3). It then starts the loop again, checking if i is less than 4, runs the code within the block, adds 1 to i again... until the value of i is not less than 4. When that happens, the loop ends.
Sorry, but I really don;t understand the for loop part... What exactly is the loop accomplishing?
Please note for Random class we use in various SDK it is not truly random. If you keep on calling it multiple times, you can actually "detect" the pattern. Of cuz seeding the Random is a good way but after multiple times, you still can actually "detect" the pattern.

It is just the pattern only repeat after some(or more depending on the SDK) iterations so for casual user, to them it looks "random". I believe a lot of computer scientists is doing research in this area to come out with a truly random class.

Random is important in particular games. A lot of games need the random feature to engage Human players. If the random is not random enough, the Human player that play a lot of times will "anticipate" the Computer next move and they can then easily come out with a strategy such that every game Human will win over Computer.

For games that react to Human input (say Chess) it will be different. It depend on Human move first and then based on that make it's decision by considering all other possibilities so no random is really needed here. Exception maybe the very first step if Computer starts first, it has to determine which move cuz it cannot always make the same move also.

So if anyone has created a truly random class can share in this forum? I also need one too :P

Haha, I was actually just discussing this with someone else, and I know. If you want to get int o philosophy, nothing in the universe is truly random. However, that's neither here nor there.

I have a code that works, but it's much to large, can anyone show me how to condense this:

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <iostream>
using namespace std;

int main(){

int row1[9];

row1[0] = rand() % 9+1;

do
{
row1[1] = rand() % 9+1;
}
while ((row1[1] == row1[0]));

do
{
row1[2] = rand() % 9+1;
}
while((row1[2] == row1[0]) || (row1[2] == row1[1]));

do
{
row1[3] = rand() % 9+1;
}
while((row1[3] == row1[0]) || (row1[3] == row1[1]) || (row1[3] == row1[2]));

do
{
row1[4] = rand() % 9+1;
}
while((row1[4] == row1[0]) || (row1[4] == row1[1]) || (row1[4] == row1[2]) || (row1[4] == row1[3]));

do
{
row1[5] = rand() % 9+1;
}
while((row1[5] == row1[0]) || (row1[5] == row1[1]) || (row1[5] == row1[2]) || (row1[5] == row1[3]) || (row1[5] == row1[4]));

do
{
row1[6] = rand() % 9+1;
}
while((row1[6] == row1[0]) || (row1[6] == row1[1]) || (row1[6] == row1[2]) || (row1[6] == row1[3]) || (row1[6] == row1[4]) || (row1[6] == row1[5]));

do
{
row1[7] = rand() % 9+1;
}
while((row1[7] == row1[0]) || (row1[7] == row1[1]) || (row1[7] == row1[2]) || (row1[7] == row1[3]) || (row1[7] == row1[4]) || (row1[7] == row1[5]) || (row1[7] == row1[6]));

do
{
row1[8] = rand() % 9+1;
}
while((row1[8] == row1[0]) || (row1[8] == row1[1]) || (row1[8] == row1[2]) || (row1[8] == row1[3]) || (row1[8] == row1[4]) || (row1[8] == row1[5]) || (row1[8] == row1[6]) || (row1[8] == row1[7]));






cout << row1[0];
cout << row1[1];
cout << row1[2];
cout << row1[3];
cout << row1[4];
cout << row1[5];
cout << row1[6];
cout << row1[7];
cout << row1[8];




}
Last edited on
to condense space, I believe you can do something like this:

while((row1[3] == row1[0]) || (row1[3] == row1[1]) || (row1[3] == row1[2]));

to

while((row1[3]) == ((row1[0])||(row1[1])||(row1[2])))
Wrong. No, you can't.
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
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>

using namespace std;

// Simple Check for Unique Values
bool isUniqueVal(const vector<int> &exclude, int test_val)
{
  for (int i = 0; i < exclude.size(); ++i)
    if (test_val == exclude[i]) return false;

  return true;
}

int main()
{
  srand(time(0));
  
  vector<int> exclude;
  // Test Values for Exclude
  exclude.push_back(4);
  exclude.push_back(6);
  exclude.push_back(2);
  exclude.push_back(1);

  // Run a quick test
  int test = 0;
  for (int i = 0; i < 3; ++i)
  {
    do
    {
      test = (rand() % 9) + 1;
    } while ( !isUniqueVal(exclude, test) ); 
    // While we haven't gotten a unique val.

    exclude.push_back(test); // Add to exclude
    cout << test << endl; // Print to test.
  }

  return 0;
}


Simple code. Checks if the value is unique when tested against a list of previous defined items.
Not very efficient probably and I don't recommend for larger than a few test values (aka 1-9); This will probably lag if you attempt to use this over a large range of data.
closed account (D80DSL3A)
Here's my try. I wrote it as a function to randomize the elements in a given array. I hope the comments explain how it works well enough. Seed the rand() before calling it the first time.
1
2
3
4
5
6
7
8
9
10
11
12
void randomizeElements(int A[], int size)
{
	int temp = 0;// swap buffer
	int rIdx=0;// randomly chosen index
	for(int j=size-1; j>0; j--)// from end of array to beginning
	{
		rIdx = rand()%j;// swap jth element with one selected at random from before it
		temp = A[j];
		A[j] = A[rIdx];
		A[rIdx] = temp;
	}
}

EDIT:
@ProgrammingNoob. To expand on the elegant reply from rocketboy9000, your code won't work because ((row1[0])||(row1[1])||(row1[2])) evaluates to just 1 or 0 (a bool result) which you then compare to row1[3]. The individual comparisons are needed there.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**do
{
row1[8] = rand() % 9+1;
}
while((row1[8] == row1[0]) || (row1[8] == row1[1]) || (row1[8] == row1[2]) || (row1[8] == row1[3]) || (row1[8] == row1[4]) || (row1[8] == row1[5]) || (row1[8] == row1[6]) || (row1[8] == row1[7]));**/

do
{
row1[8] = rand() % 9+1;
}while( not valid (row1, 8 ) );
//...
bool valid(int *array, int test ){ //generalize a little more, for columns and square
  for( int K=0; K<9; K++){
    if( K == test ) continue;
    if( array[K] == array[test] ) return false;
  }
  return true;
}
Last edited on
Topic archived. No new replies allowed.