您的位置:

Qt 随机数详解

一、Qt随机数函数的使用

Qt中提供了一组名为QRandomGenerator的工具类,它提供了几个生成随机数的函数,在使用时需要先实例化该类,代码如下:


QRandomGenerator rg;
int number = rg.bounded(10);

其中rg.bounded(n)函数可以生成一个0~n-1之间的随机数,包括0和n-1,n为自然数。 如果需要生成一组随机的颜色,可以使用Qt内置的QRgb数据类型和qRgb函数,代码如下:


QRandomGenerator rg;
QColor color(qRgb(rg.bounded(256), rg.bounded(256), rg.bounded(256)));

上述代码可以随机生成一个RGB颜色值,并用QColor类型去接受它。

二、随机数种子的设置

随机数的生成是基于随机数生成器的一种运算。而这个运算必须要有一个起点,这个起点被称为随机数种子(seed)。如果不设置随机数种子,那么每次生成的随机数都是相同的,所以需要设置不同的种子来获得不同的随机数。 可以使用qsrand()函数设置随机数种子,但是qsrand()本身并不能保证种子的随机性,所以更好的选择是使用QRandomGenerator自带的种子,代码如下:


QRandomGenerator rg(QDateTime::currentMSecsSinceEpoch());
int number = rg.bounded(10);

其中QDateTime::currentMSecsSinceEpoch()可以获得当前时间的毫秒值,保证了每次程序执行时的随机性。

三、高效生成随机序列

在某些情况下,需要如此大量的随机数,以至于一次生成一个的方式变得低效。幸运的是,Qt提供了一种高效生成伪随机序列的方式,代码如下:


QRandomGenerator rg;
QVector<quint32> sequence = rg.generate(10);

其中generate()函数可以高效生成包含n个随机数的序列,并返回一个QVector<quint32>类型的数据。

四、Qt随机数的实际应用

Qt中的随机数可以用于许多应用领域,如游戏、动画效果等。下面以多个实际应用场景来作为示例:

1. 图像噪点效果

可以使用Qt生成一组随机数,在图像上添加一些随机的像素点,模拟图像的噪点效果。代码如下:


QRandomGenerator rg(QDateTime::currentMSecsSinceEpoch());
for(int x = 0; x < image.width(); x++) {
    for(int y = 0; y < image.height(); y++) {
        if(rg.bounded(100) < 5) {
            image.setPixel(x, y, qRgb(255, 255, 255));
        }
    }
}

2. 随机漫步算法

可以使用Qt生成一组随机数,在二维平面上用简单随机游走模型演示随机漫步算法的过程,模拟粒子在空气中的运动情况。代码如下:


QRandomGenerator rg(QDateTime::currentMSecsSinceEpoch());
QPoint currentPoint(0, 0);
for(int i = 0; i < 100; i++) {
    int direction = rg.bounded(4);
    switch(direction) {
        case 0: currentPoint += QPoint(0, -1); break;
        case 1: currentPoint += QPoint(0, 1); break;
        case 2: currentPoint += QPoint(-1, 0); break;
        case 3: currentPoint += QPoint(1, 0); break;
    }
    painter.drawPoint(currentPoint);
}

3. 游戏随机关卡生成

可以使用Qt生成一组随机数,在游戏中生成关卡地图。代码如下:


QRandomGenerator rg(QDateTime::currentMSecsSinceEpoch());
const int width = 20;
const int height = 10;
QVector<bool> map(width * height);
for(int i = 0; i < width * height / 2; i++) {
    int index = rg.bounded(width * height);
    map[index] = true;
    map[(width * height) - 1 - index] = true;
}
for(int y = 0; y < height; y++) {
    for(int x = 0; x < width; x++) {
        if(map[y * width + x]) drawWall(x, y);
        else drawFloor(x, y);
    }
}

上述代码将地图分割成若干个小方块,在小方块之间随机生成墙壁或地板。