Need help with random char generator with multiply ranges

Hi, im trying to create a 2d maze that changes every time you run it, but im having troubles generating random numbers between multiply ranges of numbers, like, i want to generate a random number that is in (191 to 197), (217 to 218) and 32 by itself.

i tried using if statement to determine which range to use, but it doesnt seem to workout..

***i do not want to use array to do this also***

thanks for reading.

my code is:

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <cstdbool>

using namespace std;
int main()
{
int number;

cout << "*** Super 2D Maze***" << endl;

cout << char(218) << char(196) << char(196) << char(32) << char(32) << char(196) << char(196) << char(191);

for (int i = 0; i < 8; i++)
{
cout << (char)179;
for (int j = 0; j < 6; j++)
{
number = rand() % 218 + 1;
if ((number == 32) || (number >= 179 && number <= 180) || (number >= 191 && number <= 197) || (number >= 217 && number <= 218));

cout << char(number);
}

cout << (char)179 << endl;
}

cout << char(192) << char(196) << char(196) << char(32) << char(32) << char(196) << char(196) << char(217);
cout << endl << endl;

return 0;

}
First of all, I highly recommend (if you haven't already) acquiring a C++11 (or higher) compliant compiler. It will give you access to standardized, random number generating facilities far superior to the archaic rand and srand found in cstdlib.

Here is an elegant function to wrap just one of the random number generating facilities.

1
2
3
4
5
6
int random(int min, int max) {
	static std::random_device device{};
	static std::default_random_engine engine{ device() };
	std::uniform_int_distribution<int> distribution{ min, max };
	return distribution(engine);
}


In the function above, std::random_device is a uniformly-distributed random number generator. It can produce non-deterministic random numbers if a non-deterministic source (e.g. hardware) is available to the implementation. Otherwise, it will generate pseudo-random numbers.
(You can check the non-deterministic property of this generator by accessing it's entropy member, which should be a non-zero value if a non-deterministic source is available.)

We'll be calling the device's constructor to supply a seed to engine, which is a pseudo-random number generator.
We then obtain random numbers, uniformly distributed on the interval [min, max] inclusive.

Regardless of which implementation you end up using, it's helpful to wrap random number generating code in a function.

Here's one possible solution to your problem:

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 <iostream>
#include <random>

int random(int min, int max) {
	static std::random_device device{};
	static std::default_random_engine engine{ device() };
	std::uniform_int_distribution<int> distribution{ min, max };
	return distribution(engine);
}

int main() {

	struct Range {
		int min, max;
	};

	const int num_ranges = 3;
	const Range ranges[num_ranges] = {
		{191, 197},
		{217, 218},
		{32, 32}
	};

	Range index = ranges[random(0, num_ranges-1)];

	int number = random(index.min, index.max);

	std::cout << "Min:\t" << index.min << "\nMax:\t" << index.max << "\nNumber:\t" << number << std::endl;

	return 0;
}
@xismn your solution is non-uniform. You need to use discrete_distribution to select range as they have different cardinality.

Alternative approaches is to generate flat number (1-10 in your case) and then map it to the real number (highly suggested, might even write a distribution for that later):
1
2
3
int arr[] = {32, 191, 192, 193, 194, 195, 196, 197, 217, 218};
int i = /*get random number in range[1; 10]*/
std::cout << arr[i]; //Select number you need. 


Or apply knowledge of standard library and C++ rules on type converting:
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 <array>
#include <iomanip>
#include <iostream>
#include <map>
#include <random>

std::piecewise_constant_distribution<> init()
{
    std::array<double, 6> i{32, 33, 191, 198, 217, 219};
    std::array<double, 5> w{  1,  0,   7,   0,   2};
    return {i.begin(), i.end(), w.begin()};
}

int get_number()
{
    thread_local std::mt19937_64 gen{std::random_device{}()};
    thread_local std::piecewise_constant_distribution<> dist{init()};
    return dist(gen);
}

int main()
{
    std::map<int, int> hist;
    for(int n = 0; n < 500000; ++n) {
        ++hist[get_number()];
    }
    for(const auto& p : hist) {
        std::cout << std::setw(3) << p.first << ' ' << 
                     std::string(p.second/1000, '*') << '\n';
    }
}
 32 **************************************************
191 **************************************************
192 *************************************************
193 *************************************************
194 *************************************************
195 *************************************************
196 *************************************************
197 **************************************************
217 **************************************************
218 *************************************************

Thanks for the suggestion guys, ill try accordingly
Topic archived. No new replies allowed.