如何调用一个变量(包含rand()函数)并获得总是不同的数字?

时间:2014-02-19 14:18:57

标签: c++ c++11

我正在写一个关于在竞技场与对手战斗的程序(实际上是一个游戏)。开始营业,我创建了以下标题,其中包含有关战士的信息:

#ifndef COMPETITOR_H_INCLUDED
#define COMPETITOR_H_INCLUDED

#include <cstdlib>

int ID = 0;

struct competitor
{
    std::string name;
    int health;
    int attack;
};

competitor player;

player.health = 25;
player.attack = (rand()%6)+1;


competitor opponent[2];

opponent[0] = {"Rat", 6, (rand()%4)+1};
opponent[1] = {"Drunkard", 10, (rand()%6)+1};

#endif // COMPETITOR_H_INCLUDED

在这里我有我的功能我有问题:

int fight()
{

    int number = 1;

    cout << "Your opponent is " << opponent[ID].name;
    cout << endl << "Your opponent's health: " << opponent[ID].health;
    cout << endl << "Your health: " << player.health << endl;

    while (opponent[ID].health > 0 || player.health > 0)
        {
            cout << endl << endl << "Round " << number << endl;

            cout << opponent[ID].name << " inflicts" << opponent[ID].attack << " damage, ";
            cout << "you have " << (player.health = player.health - opponent[ID].attack) << " health points" << endl;

            if (player.health <= 0) break;

            cout << player.name << " inflicts " << player.attack << " damage, ";
            cout << "your opponent has " << (opponent[ID].health = opponent[ID].health - player.attack) << " health points" << endl;

            if (opponent[ID].health <= 0) break;

            number++;
        }

    if (player.health > opponent[ID].health)
        {
            cout << endl << "Congratulations! You managed to defeat your opponent. Prepare for the next fight.";
            ID++;
        }

         else
        {
            cout << endl << "Unfortunately, you have been defeated. Start again.";
            ID = 0;
        }

        getch();

    }

我也有srand(time(NULL));在我的main()函数的开头。基本上它起作用,在每个程序运行时攻击值都不同,但它们在每一轮都是相同的。我不知道如何让它们在每个while循环中生成。 非常感谢每一位帮助。

此致

5 个答案:

答案 0 :(得分:1)

你问如何在while循环中的每次迭代中分配一个新的攻击值,只需这样做:

while (opponent[ID].health > 0 || player.health > 0)
{
   opponent[ID].attack = (rand()%6)+1;
   player.attack = (rand()%6)+1;
   ...

答案 1 :(得分:1)

首先,请注意建议不要使用rand。相反,您应该使用<random>标题及其好处。如果你没有C ++ 11,那么Boost.Random就会有一对一的映射。

然后,生成一个随机值:

  • 找到自己的种子(建议使用std::random_device
  • 创建伪随机引擎(std::default_random_engine)并使用种子
  • 对其进行初始化
  • 例如,使用适当的发布(在您的情况下为std::uniform_distribution_int<int>)并为您的播放器初始化其参数(1, 6)
  • 最后,每当您需要一个随机数时,请通过从引擎中提取随机性来询问您的发行版。

在代码中:

// Seed with a real random value, if available
std::random_device rd;

// Choose a random mean between 1 and 6
std::default_random_engine e1(rd());
std::uniform_int_distribution<int> uniform_dist(1, 6);

然后每次拨打uniform_dist(e1)都会返回1到6之间的数字,几乎没有偏见。重要的是发动机和分配是长寿的=&gt;对于给定的随机序列,您应该始终使用相同的引擎和分布。使用具有各种分布的相同引擎也是完美的(否则会有一个对象)。

因此,适应您的代码:

using AttackDice = std::uniform_distribution_int<int>;

struct Competitor {
    std::string name;
    int health;
    AttackDice attackDice;
};

Competitor player = {"", 25, AttackDice{1, 6}};

opponent[0] = {"Rat", 6, AttackDice{1, 4}};
opponent[1] = {"Drunkard", 10, AttackDice{1, 6}};

然后在你的主要:

std::random_device rd;
std::default_random_engine myRandomEngine(rd());

// .. stuff

while (opponent[ID].health > 0 || player.health > 0)
    {
        cout << endl << endl << "Round " << number << endl;

        int playerAttack = player.attackDice(myRandomEngine);
        int opponentAttack = opponent[ID].attackDice(myRandomEngine);

        // .. resolve
    }

// .. stuff

注意:你应该只在循环的每次迭代中抛出一个骰子,最有可能;)

答案 2 :(得分:0)

除了在初始化播放器实例时设置攻击时,您还需要在while循环中重置它。

基本上添加:

while (opponent[ID].health > 0 || player.health > 0)
{
    player.attack = (rand()%6)+1;  // <<< add this

    cout << endl << endl << "Round " << number << endl;

    // rest of code is unchanged
}

答案 3 :(得分:0)

由于您使用C++11标记了问题,因此在C ++ 11中请不要使用rand,这不是一个好的随机函数。使用新添加的。

以下是我的代码库中的一些片段:

#include <random>
using namespace std;

auto engine = mt19937{ random_device()() };
function<int(int)> rand = [=](int range) mutable {
  auto idist = uniform_int_distribution<int>(0, range);
  return idist(engine);
};

auto myRandomNumberIn100 = rand(100);

提示:存储rand类型的function<int(int>对象,并通过引用传递它。如果您复制它,rand将始终产生相同的结果。

答案 4 :(得分:0)

您正在使用旧的rand功能。那不是最好的设计。现在C ++有一个更好的概念:将随机生成器和随机分布分开。

在您的情况下,.attack确实应该是std::uniform_int_distribution<>。用最小/最大值{1, N}初始化它,其中N在不同的对手之间变化。

设置一个随机生成器:std::mt19937 random;并获得一个随机损坏值,如下所示:int damage = opponent[ID].attack(random);