我正在开展一个项目而且我被困住了。我有两个生成随机数的变量。我想做一个检查,检查以确保变量不是相同的数字,如果是,则重复该过程,直到它们不相同。这就是我所拥有的:
num_enemy = 3;
int f = rand() % num_enemy;
int m = rand() % num_enemy;
if ( f != m )
{
enemy_ptr[f] -> fire_Weapon();
enemy_ptr[m] -> update_Status();
}
上面的代码不会工作加上如何才能使它如果它的错误会再次生成随机数?
我不是在寻找答案,只是帮助我确切需要做什么。谢谢!
答案 0 :(得分:5)
问题是当它到达这一部分时......
if ( f != m )
{
enemy_ptr[f] -> fire_Weapon();
enemy_ptr[m] -> update_Status();
}
...由于模数,变量f
和m
可能具有相同的值,因此永远不会调用fire_Weapon()
和update_Status()
函数。您将需要循环,直到两个变量具有不同的值。下面的代码应该排除你。
const int num_enemy = 3;
int f = rand() % num_enemy;
int m;
// A do-while loop is guaranteed to be called at least once.
do
{
m = rand() % num_enemy;
} while ( f == m ); // Repeat the loop if the values are the same
// At this point, f and m will always have different values.
enemy_ptr[f] -> fire_Weapon();
enemy_ptr[m] -> update_Status();
因为你的变量是模数较低的值,所以循环可能必须在f != m
之前运行很多次。
此外,如果您希望每次运行游戏时rand()
返回的伪随机数序列不同,请通过调用srand( time() )
为伪随机数生成器播种一次。如果您希望每次运行游戏时序列保持不变,请保持原样。这可以极大地帮助调试,如果您的游戏需要deterministic,则需要这样做。
在此处详细了解rand()
和srand()
:http://www.cplusplus.com/reference/cstdlib/rand/
如另一个答案所述,C ++ 11改进了随机数生成。点击此处了解更多信息:http://www.cplusplus.com/reference/random/
答案 1 :(得分:4)
一个解决方案是
num_enemy = 3;
int f = rand() % num_enemy;
int m = rand() % num_enemy;
while(f==m) {
f = rand() % num_enemy;
//m = rand() % num_enemy;
}
enemy_ptr[f] -> fire_Weapon();
enemy_ptr[m] -> update_Status();
但是你应该阅读Reservoir sampling来学习如何从一组中随机选择k数。你可以有一个从1到num_enemy的整数数组。然后从该数组中随机选择两个数字。这是一个n阶解决方案,如果你的阵列很小,它会很好用。
编辑:根据评论编辑代码
答案 2 :(得分:4)
“上面的代码不起作用”有点模糊。我猜你的意思是每次f == m
?
在这种情况下,您可能忘记播种 RNG。请参阅srand
的文档。或者更好的是,将新的c ++ Random Library用于伪随机数生成器。
关于如何在f == m
...时重新生成随机数?你知道while
循环吗?阅读control structures和简单的c ++语法是个好主意。
答案 3 :(得分:2)
如果您考虑一下,您可以通过从较少的可能性池中选择,确保第二个随机数与第一个随机数不同:
num_enemy = 3;
int f = rand() % num_enemy;
// pick another non-zero number from a pool that's smaller by one than before
int next_offset = 1 + (rand() % (num_enemy-1));
// add it to the previous result (modulo the range)
int m = (f + next_offset) % num_enemy;
assert( 0 <= f && f < num_enemy);
assert( 0 <= m && m < num_enemy);
assert( f != m );
enemy_ptr[f] -> fire_Weapon();
enemy_ptr[m] -> update_Status();
当然,因为rand()
不一定是一个伟大的RNG,并且因为仅使用%
将随机数映射到某个范围通常会引入偏差,您可能想要调整实施这是为了解决这些问题,如果这很重要的话。
如果您更喜欢循环解决方案,则无需继续选择这两个数字(尽管我认为也没有太大的危害):
int f = rand() % num_enemy;
int m;
do {
m = rand() % num_enemy;
} while (f == m);
答案 4 :(得分:1)
如果您想要的是在某些条件下重复某些事情,那么您需要的是一个循环,重复构造。在这种情况下,由于你想在检查条件之前至少做一次这件事,我建议做一个do-while循环:
int f, m;
do {
f = rand() % num_enemy;
m = rand() % num_enemy;
} while(f == m);
enemy_ptr[f] -> fire_Weapon();
enemy_ptr[m] -> update_Status();
答案 5 :(得分:0)
num_enemy = 3;
int f = rand() % num_enemy;
int m = rand() % (num_enemy-1);
m += (m>=f);
enemy_ptr[f] -> fire_Weapon();
enemy_ptr[m] -> update_Status();
我们的想法是,从f
的可能值集合中取出m
得到的任何数字。由于已从m
的可能集中删除了某个值,因此我们使用m
减少了% (num_enemy-1)
的可能值,并调整为m
选择的任何值成为可能的价值之一。也就是说,如果m
大于或等于为f
选择的值,我们会添加一个。这被“巧妙地”写成m += (m>=f);
,因为布尔值被转换为零或一。
此外,rand()
通常不是一个好的随机数生成器,并且使用mod不能很好地在所需范围内生成均匀分布。您应该使用C ++ 11 <random>
库。
#include <random>
int num_enemy = 3;
// set up decent random number engine and distributions
std::mt19937 eng;
std::uniform_int_distribution<> f_dist{0, num_enemy-1};
std::uniform_int_distribution<> m_dist{0, num_enemy-2};
int f = f_dist(eng);
int m = m_dist(eng);
m += (m>=f);