С++ Использование ctime для генератора случайных чисел, но все еще получение того же числа

Я новичок, и я не совсем понимаю, что я делаю неправильно, используя ctime и переменные, которым присваиваются случайные числа. Моя переменная newCard продолжает возвращать одно и то же значение каждый раз, когда я ее вызываю. Любая обратная связь будет оценена!

Эта программа предназначена для просмотра циклов и не может включать пользовательские функции

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

int main()
{
    srand(static_cast<unsigned>(time(0)));

    int total = 0;
    int card1 = rand() % 10 + 1;
    int newCard = rand() % 10 +1;
    char deal, replay;

    do
    {   
         cout << " First Cards: " << card1 << ", " << newCard;
         total = card1 + newCard;
         cout << "\n Total: " << total;
         cout << "\n Do you want another card? (Y/N) ";
         cin >> deal;

         while(deal == 'y' || deal == 'Y')
         {
             cout << "\n New Card = " << newCard;
             total += newCard;
             cout << "\n Total: " << total;

            if(total == 21)
            {
                cout << "\n Congratulations!! BLACKJACK! ";
                cout << "\n Would you like to play again? (Y/N):";
                cin >> replay;
                break;
            }
            else if(total > 21)
            {
                cout << "\n BUST ";
                cout << "\n Would you like to play again? (Y/N):";
                cin >> replay;
                break;
            }

            cout << "\n Would you like another card? (Y/N): ";
            cin >> deal;
         }

         while (deal == 'n' || deal == 'N')
         {
             cout << "\n Would you like to play again? (Y/N): ";
             cin >> replay;
         }
    }
    while(replay == 'y' || replay == 'Y');

    while (replay =='n' || replay == 'N')
    {
        cout << "\n Exiting BlackJack \n\n";
        return 0;
    }
}

person Lilly B    schedule 03.09.2018    source источник
comment
Переменная содержит одно и то же значение, если вы не измените значение, которое она содержит. Вот как работают переменные...   -  person user253751    schedule 03.09.2018
comment
Аналогия: вчера я бросил пару игральных костей и получил 8. Я написал 8 на клочке бумаги. Почему на клочке бумаги каждый раз, когда я смотрю на него, написано 8?   -  person user253751    schedule 03.09.2018
comment
Как я уже сказал... Я новичок и не имею опыта работы с C++, поэтому реальные отзывы будут полезны. Я искал информацию о том, как работает генератор случайных чисел. Я не уверен, как изменить значение на другое случайное число (я думал, что объявление srand сделало это).   -  person Lilly B    schedule 03.09.2018
comment
Вы сделали эту часть (посев) хорошо. Ваша проблема носит более фундаментальный характер и не имеет ничего общего со случайным числом. int newCard = rand() % 10 +1; выполняется 1 раз при запуске вашей программы. Значение newCard не меняется. c++ не пересчитывает формулу, если вы предполагали, что это произойдет.   -  person drescherjm    schedule 03.09.2018


Ответы (3)


Если вы хотите сгенерировать случайное число, вам нужно позвонить rand().

Так вот:

int newCard = rand() % 10 +1;

Я бросаю 10-гранный кубик, выпадает 5, поэтому я пишу 5 на листе бумаги с надписью newCard.

Теперь каждый раз, когда я смотрю на свой лист бумаги с надписью newCard, на нем все равно будет написано 5. Оно не меняется каждый раз, когда я смотрю на него.

Если вы хотите бросить еще раз, вам нужно снова бросить и записать новое число, выполнив это снова:

newCard = rand() % 10 +1;
person user253751    schedule 03.09.2018
comment
О, спасибо! Я понимаю, насколько прямым было это решение. Спасибо за объяснение. - person Lilly B; 03.09.2018

int card1 = rand() % 10 + 1;
int newCard = rand() % 10 +1;

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

Что вам нужно сделать, так это сгенерировать новую карту, если игрок бьет.

Это так же просто, как вставить строку в ваш цикл:

 while(deal == 'y' || deal == 'Y')
 {
     newCard = rand() % 10 +1;              // <<<--- this one.
     cout << "\n New Card = " << newCard;
     :
}

(a) Не совсем верно вполне для блэкджека, так как карт номиналом в десять больше, чем обычных карт (все 10/J/Q/K имеют значение десять).

Лучшим способом было бы использовать что-то вроде:

newCard = rand() % 13 + 1;
if (newCard > 10) newCard = 10;
person paxdiablo    schedule 03.09.2018

Ваша проблема

Вы вызываете rand() только один раз в начале, как это

int card1 = rand() % 10 + 1;
int newCard = rand() % 10 +1;

Однако каждый раз, когда вам нужно новое значение, вам нужно переназначить newCard следующим образом.

newCard = rand() % 10 +1;

перед повторным использованием. Вы должны вызывать его снова и снова, чтобы получить новые значения.

Подсказка

Просто потому, что это еще не было упомянуто, здесь хороший разговор о том, почему вы не должны не использовать std::rand(). Хотя другие ответы также будут давать случайные числа, их распределение может быть неправильным. C++ обеспечивает лучший способ получения случайных чисел, и я предлагаю вам привыкнуть к нему как можно скорее.

std::random_device rd;  //Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<> dis(1, 10);

int newCard = dis(mt);

Для этого вам понадобятся следующие заголовки

#include <random>
#include <iostream>

Если вам нужна еще лучшая случайность, вы можете использовать random_device вместо генератора mt19937.

Поэтому я советую сделать это с самого начала и удалить rand() из вашего кода.

person user32434999    schedule 03.09.2018
comment
Я ценю этот совет! К сожалению, вводный курс, на котором я учусь, не зашел так далеко, и я не должен превзойти его учение. Я обязательно применю это на практике в свободное время! Благодарю вас! - person Lilly B; 05.09.2018