83 lines
2.1 KiB
C++
83 lines
2.1 KiB
C++
#ifndef MY_RANDOM_HPP
|
|
#define MY_RANDOM_HPP
|
|
|
|
#include <vector>
|
|
#include <random>
|
|
|
|
/* For spawning a truck, we would like to have a system where they mostly come from a lane.
|
|
* However, that would be too predictable.
|
|
* For this reason we implement our own distribution of probabilities,
|
|
* where they scew to both sides.
|
|
* Very roughly this:
|
|
* .. ..
|
|
* .-` `-.-` `-.
|
|
*/
|
|
class RadicalNumberGenerator {
|
|
public:
|
|
const int range_max = 100;
|
|
private:
|
|
std::mt19937 gen;
|
|
std::discrete_distribution<> dist;
|
|
|
|
/* To achieve the desired form,
|
|
* we use the sum of 2 normal distributions.
|
|
*/
|
|
double normal_probability_density_function(double x, double mean, double variance) {
|
|
return (1 / sqrt(2*M_PI*pow(variance, 2)))
|
|
* exp(-0.5 * (pow(x-mean, 2) / (2*pow(variance, 2))))
|
|
;
|
|
}
|
|
|
|
double radical_probability_density_function(double x) {
|
|
double variance = 6.8d;
|
|
|
|
return normal_probability_density_function(x, range_max * 0.2, variance)
|
|
+ normal_probability_density_function(x, range_max - (range_max * 0.2), variance);
|
|
}
|
|
|
|
public:
|
|
RadicalNumberGenerator(int seed) : gen(seed) {
|
|
std::vector<double> probabilities(range_max);
|
|
for (int i = 0; i < range_max; i++) {
|
|
probabilities[i] = std::max(
|
|
0.0,
|
|
radical_probability_density_function((double)i)
|
|
);
|
|
}
|
|
|
|
dist = std::discrete_distribution(probabilities.begin(), probabilities.end());
|
|
}
|
|
|
|
double operator()(void) {
|
|
return dist(gen);
|
|
}
|
|
|
|
} radical_number_generator(rand());
|
|
|
|
|
|
/* We would like to spawn enemies and trucks at semi-random intervals,
|
|
* without too much RNG involved.
|
|
*/
|
|
class Spawner {
|
|
public:
|
|
int last_blaze = 0;
|
|
int min_distance;
|
|
int denominator;
|
|
|
|
void reset() {
|
|
last_blaze = 0;
|
|
}
|
|
|
|
bool blaze(int current_distance) {
|
|
if ((current_distance - last_blaze) > min_distance
|
|
&& rand() % denominator) {
|
|
last_blaze = current_distance;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
};
|
|
|
|
#endif
|