我正在写一个关于在竞技场与对手战斗的程序(实际上是一个游戏)。开始营业,我创建了以下标题,其中包含有关战士的信息:
#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循环中生成。 非常感谢每一位帮助。
此致
答案 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);