2014-10-10 2 views
0

Я использую библиотеку ncurses для создания игры. У меня возникают проблемы с созданием правильных случайных чисел. Цикл while ниже должен содержать генерирование случайных чисел до тех пор, пока они не составят от 1 до 45 (это мои ограничения по оси Y на стандартном экране). Я не могу понять, что я делаю неправильно, потому что условие цикла while отлично подходит для меня. Проблема в том, что while цикл начинает работать бесконечно. Я ничего не делаю, кроме как печатать сгенерированные числа в конце, так как я просто хочу видеть, что генерируются правильные числа. может ли кто-нибудь помочь мне с этой проблемой? Следующее - мой int main.генерировать случайное число в диапазоне C++

int main() 
{ 
int r,c,x=0; 
initscr(); 
raw(); 
keypad(stdscr, TRUE); 
noecho(); 
//mvprintw(22,45,"<"); 
getmaxyx(stdscr,r,c); 

int n,n2 = 0; 

while((n<1)||(n>45)){ 
srand (time(NULL)); 
n = rand(); 
srand (time(NULL)); 
n2 = rand(); 
} 
mvprintw(4,10,"First Random Number: %d\n", n); 
mvprintw(5,10,"Second Random number: %d\n", n2); 

getch(); 
endwin(); 
return 0; 
} 
+3

Прежде всего, не назовите 'srand' несколько раз, это даст очень плохие результаты. Во-вторых, почему вы просто вызываете plain 'rand()' вместо чего-то вроде '(rand()% 45) + 1'? – UnholySheep

+0

Есть проблема с 'rand()', вы можете найти это http://www.lesinskis.com/code_repair_01_rand_problems.html, чтобы быть интересным. – shuttle87

+3

C или C++? ответы будут сильно различаться. – quantdev

ответ

2

Вы хотите назвать srandраз в начале вещей, а затем использовать модуль, чтобы принести rand результатов в ваш диапазон, что-то вроде:

srand(time(NULL)); 
n = rand() % 45 + 1; 
n2 = rand() % 45 + 1; 
+1

это не обеспечивает равномерного распределения из-за смещения – 4pie0

+4

@ 0d0a Автор (на вопрос) не уточнил, что ему нужно равномерное распределение – UnholySheep

+0

, но он предположил это, это то, что ему случайное средство IMO – 4pie0

1

Как @unholySheep комментировал, ранды () возвращает значение от 0 до RAND_MAX, что является огромным значением. Поэтому очень маловероятно, что вы быстро получите значение между 1 и RAND_MAX.

Таким образом, решение сделать напоминание о делении на номер, который вы хотите:

n = 1 + rand() % 45; 

Вам даже не нужно какое-то время.

+1

это ошибочный дизайн – 4pie0

+0

из-за [смещения, введенного rand] (http://stackoverflow.com/questions/24067831/random-over-a-range-is-number-bias-present-for-new-rand-version/24069874 # 24069874) – 4pie0

0

Вы можете получить случайное число между 1 и 45 включительно с:

n = rand() % 45 + 1; 

Это не будут совершенными с точкой зрения распределения, но это будет достаточно близко для любого, кто ни статистика, ни криптограф , и в этом случае вы, вероятно, будете использовать реальных случайных чисел.

Вы также должны позвонить srand() один раз, в начале своей программы где-то, а не несколько раз, особенно если вы используете текущее время для его семени.

Делать это несколько раз в течение одной секунды даст вам решительно неслучайный последовательности, такие как:

42, 42, 42, 42, 42, 42, 42, ... 
+2

Функция rand() вычисляет последовательность псевдослучайных целых чисел в диапазоне от 0 до RAND_MAX (как определено в файле заголовка ). – Alberto

+1

@ Энтони, 'rand()' does _not_ возвращает отрицательные числа, он дает числа в диапазоне '0..RAND_MAX'. – paxdiablo

2

Это, как вы можете это сделать в C++:

#include <iostream> 
#include <random> 

int main() 
{ 
    std::random_device rd; 
    std::mt19937 gen(rd()); 
    std::uniform_int_distribution<> dis(1, 45); 

    for (int n=0; n<1000; ++n) 
     std::cout << dis(gen) << ' '; 
    std::cout << '\n'; 
} 

Использование rand() % x является ошибочной конструкцией из-за введенного смещения, делящего диапазон неравномерно. Вы можете прочитать this, чтобы узнать больше о предвзятости, введенной rand() % x.

+2

В большинстве случаев 'rand()' просто отлично. Предвзятость, возникающая из-за неравного деления, незначительна и не соответствует требованиям распределения, не имеет значения. Например, выбор этого варианта для 6-из-45 номеров лото - это не совсем проблема :-) Тем не менее, это хороший ответ, показывающий новые случайные вещи C++. – paxdiablo

+0

@paxdiablo Да, вы правы, просто хотели предупредить ... – 4pie0

+0

@paxdiablo, 'rand()' следует избегать. Он не генерирует случайные числа. – CroCo

Смежные вопросы