C++ 我的RNG值确定意外值

C++ 我的RNG值确定意外值,c++,C++,我知道随机不是真正的随机,因此实现了随时间变化的srand,但是它不是每次运行程序时都给出随机值,而是完全相同的值92和98,或者更确切地说是2和8。我想要我的变量int randValPlayer=rand()%20+1和int randValCPU=rand()%20+1以提供随机值 我把srand(时间(0))在我的主函数中。我试着改变我期望值的随机算法 class Game { private: int playerHealth = 100; int cpuHealth

我知道随机不是真正的随机,因此实现了随时间变化的srand,但是它不是每次运行程序时都给出随机值,而是完全相同的值92和98,或者更确切地说是2和8。我想要我的变量
int randValPlayer=rand()%20+1
int randValCPU=rand()%20+1以提供随机值

我把
srand(时间(0))在我的主函数中。我试着改变我期望值的随机算法

class Game 
{
private:
    int playerHealth = 100;
    int cpuHealth = 100;
    int userChoice;
    int randValPlayer = rand() % 20 + 1;
    int randValCPU = rand() % 20 + 1;
public:
    int attackPlayer()
    {

        playerHealth = playerHealth - randValPlayer;
        return playerHealth;
    }
    int attackCPU()
    {

        cpuHealth = cpuHealth - randValCPU;
        return cpuHealth;
    }
    void choice() 
    {
        cout << "Input '1' to attack CPU" << endl;
        cin >> userChoice;
        if (userChoice == 1)
        {
            attackCPU();
            cout << "CPU's health reduced to " << cpuHealth << endl;
            attackPlayer();
            cout << "Player health reduced to " << playerHealth << endl;
            system("pause");
        }
    }
}gameobj;

class Foundation 
{
private:
    int userChoice;

public:
    void startProgram() 
    {
        cout << "Please input desired number: " << endl;
        cout << "1. Calculator" << endl;
        cout << "2. Equation calculator" << endl;
        cout << "3. Game" << endl;
        cin >> userChoice;
        system("cls");
        if (userChoice == 1) {
            calcobj.calcOperation();
        }
        if (userChoice == 2) {
            equationobj.equationChoice();
        }
        if (userChoice == 3) {
            gameobj.choice();
        }
    }
}foundobj;

int main()
{
    foundobj.startProgram();
    srand(time(0));
    return 0;
} ```

I expected the output to be random but the integer values are just the exact same, via 8 and 2.
类游戏
{
私人:
int playerHealth=100;
int cpuHealth=100;
int用户选择;
int randValPlayer=rand()%20+1;
int randValCPU=rand()%20+1;
公众:
int attackPlayer()
{
playerHealth=playerHealth-randValPlayer;
回归玩家健康;
}
int attackCPU()
{
cpuHealth=cpuHealth-randValCPU;
回归健康;
}
无效选择()
{
不能选择;
if(userChoice==1)
{
攻击CPU();

难道你忘了考虑时间?你需要在使用生成器之前为它设定种子,但你是在程序中做最后一件事

即使您先在
main
中移动
srand
,此程序也不会工作,因为您的全局
游戏
实例是在这之前创建的

由于(可变)全局变量通常不是一个好主意,因此这是一个重写的好机会

我建议这样做:

class Game
{
   // ...
};

class Foundation 
{
private:
    Game gameobj;
    // The other objects here...
public:
    void startProgram() 
    {
        int userChoice = 0;
        cin >> userChoice;
        // ...
        if (userChoice == 3) {
            gameobj.choice();
        }
    }
};

int main()
{
    srand(time(0));
    Foundation foundobj;
    foundobj.startProgram();
    return 0;
} 

这里有很多错误:

1) 在调用
rand()
之前,必须通过调用
srand()
为随机生成器设定种子。当前,在调用
srand()
之后,您将始终从
rand()
获得相同的数字序列

2)
时间(0)
是一个相当糟糕的种子。它的分辨率只有1秒,因此两个人在同一秒内启动程序将得到相同的伪随机数。它也是一个高度可猜测的种子

3) 如果
int randValPlayer=rand()%20+1;
的输出范围不能被20平均整除,则在语句中使用模会引入偏差


4)
rand()
(通常)有一个相当短的周期和有限的输出范围。a与a组合可能会更好。请参阅链接页面上的示例。

在startProgram()调用之后,您正在播种随机流,因此使用的种子始终是相同的。并且使用rand()用于初始化类成员的函数也将在种子设定之前被调用。与
rand()
相比,更喜欢标题中的现代工具。另请参见