Функция rand () генерирует числа в неправильном диапазоне - PullRequest
6 голосов
/ 15 марта 2020

У меня проблема с моей игрой в числа. Программа состоит из 2 частей. В первой части пользователь пытается угадать число, случайно сгенерированное компьютером. Во второй части компьютер пытается оценить число, введенное пользователем. В части 1 проблем нет, но в части 2 компьютер оценивает значения, которые не обеспечивают диапазоны при прогнозировании. Итак, я использовал переменные a и b для создания чисел от 1 до 1000 в функции rand () и определил ее как a = 1 b = 1000. Компьютер постоянно сужает этот диапазон в соответствии с ответами пользователя.

Например, пользователь ввел число 649. Если компьютер оценивает 800, соответствующая часть работает, и новое значение b равно 800, а не 1000, поэтому верхний предел обновляется. Если компьютер оценивает 200, соответствующая часть снова работает, и новое значение a равно 200, и когда l oop оборачивается, получается число от 200 до 800, а не от 1 до 1000. Но проблема в том, что что, хотя значения обновляются, компьютер генерирует число выше 800 (например, 1246). Именно в этом проблема.

Мне нужно доставить это задание во вторник, но я все еще не смог найти решение этой ошибки. Я отправляю вам исходный код и подробно описываю, как каждая переменная, которую я использую, работает как номер комментария. Если вы хотите, я могу отправить видео описание ошибки. Пожалуйста, помогите мне.

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

/*
                VARIABLES

    a=          rand() fonction min limit.
    b=          rand() fonction max limit.
    i=          attempts of user
    j=          attempts of computer
    rnd1=       The computer generated number that the user is trying to find.
    rnd2=       The number generated by the computer when estimating the number entered by the user and changing in each cycle.
    number2=    The number the computer is trying to find.
    number1=    Each number that the user enters when trying to find the number created by the computer.
    input=      The value that takes the answer to the questions the computer asks the user.
    restart=    The value that is defined to 1 and allows the game to restart unless the user changes the value.

    ATTENTION:  In order to help you find and test the problem faster, I disabled some 
                lines where the user was asked questions with a comment line.
*/

#include "stdlib.h"
#include <stdio.h>
#include <dos.h>
#include <windows.h>
#include <locale.h>

int main()
{
    int i, j = 1, rnd1, rnd2, number2 = 0, number1 = 0, b = 1000, a = 1, input, restart = 1;

    setlocale(LC_ALL, "Turkish");       

    do
    {
        printf("\t\t\t\t-----------------------------------------\n");
        printf("\t\t\t\t|                    |\n");
        printf("\t\t\t\t|      Welcome to Guess Number Game      |\n");         
        printf("\t\t\t\t|                    |\n");
        printf("\t\t\t\t-----------------------------------------\n");

        printf("Game is starting...\n");
        printf("3\n");
        Sleep(1000);
        printf("2\n");
        Sleep(1000);            
        printf("1");
        Sleep(1000);
        system("cls");

        srand(time(NULL));
        rnd1 = a + rand() % b;      

        printf("Computer: Let's try to guess the number that in my mind :)\n\n");
        for (i = 1; number1 != rnd1; i++)
        {
            printf("Computer: What is your guess?\n");
            printf("Number: ");                 
            scanf_s("%d", &number1);
            printf("\n");

            if (number1 < rnd1)
            {
                printf("Computer: The secret number is greater than your guess. Try again...\n");
            }
            else if (number1 > rnd1)
            {
                printf("Computer: The secret number is smaller than your guess. Try again...\n");
            }
            else
            {
                printf("Computer: Congratulations!!!  You know the number at your %d’th guess\n\n\n", i);
                printf("\t\t\t\t------------------------------------------\n");
                printf("\t\t\t\t|                     |\n");
                printf("\t\t\t\t|           Computer's Turn...        |\n");
                printf("\t\t\t\t|                     |\n");
                printf("\t\t\t\t------------------------------------------\n");

                printf("3\n");
                Sleep(1000);
                printf("2\n");
                Sleep(1000);            
                printf("1");
                Sleep(1000);
                system("cls");
            }
        }
        printf("Computer: Now, its my turn. Write a number and I'll try to find it...\n");
        printf("Number: ");
        scanf_s("%d", &number2);
        printf("\n");

        while (j != -1)
        {
            rnd2 = a + rand() % b;
            if (rnd2 == number2)
            {
                printf("Computer: My guess is %d. Is this true ?\n", rnd2);
                //printf("1)Yes. It is equal to the number which is in my mind.\n");
                //printf("2)No. It is greater than to the number which is in my mind.\nNumber: ");
                //printf("2)No. It is smaller than to the number which is in my mind.\nNumber: ");
                //scanf_s("%d", &input);
                //printf("\n\n");
                //if (input == 1)
                //{
                //  printf("Computer: I found! I found!. The secret number is %d.\n\n", rnd2);
                //}
                //else if (input == 2)
                //{
                //  printf("Don't try to fool me, I'm a computer. I know it's true :)\n");
                //}
                //else if (input == 3)
                //{
                //  printf("Don't try to fool me, I'm a computer. I know it's true :)\n");
                //}
                break;
            }
            else if (rnd2 < number2)
            {
                printf("Computer: My guess is %d. Is this true ?\n", rnd2);
                //printf("1)Yes. It is equal to the number which is in my mind.\n");
                //printf("2)No. It is greater than to the number which is in my mind.\nNumber: ");
                //printf("2)No. It is smaller than to the number which is in my mind.\nNumber: ");
                //scanf_s("%d", &input);
                //printf("\n\n");
                //if (input == 1)
                //{
                //  printf("Don't try to fool me, I'm a computer. I know it's smaller than yours :)\n");
                //}
                //else if (input == 2)
                //{
                //  printf("Don't try to fool me, I'm a computer. I know it's smaller than yours :)\n");
                //}
                //else if (input == 3)
                //{

                //}
                a == rnd2;
            }
            else if(rnd2>number2)
            {
                printf("Computer: My guess is %d. Is this true ?\n", rnd2);
                //printf("1)Yes. It is equal to the number which is in my mind.\n");
                //printf("2)No. It is greater than to the number which is in my mind.\nNumber: ");
                //printf("2)No. It is smaller than to the number which is in my mind.\nNumber: ");
                //scanf_s("%d", &input);
                //printf("\n\n");
                //if (input == 1)
                //{
                //  printf("Don't try to fool me, I'm a computer. I know it's greater than yours :)\n");
                //}
                //else if (input == 2)
                //{

                //}
                //else if (input == 3)
                //{
                //  printf("Don't try to fool me, I'm a computer. I know it's greater than yours :)\n");
                //}
                b == rnd2;
            }
            j++;
        }

        if (i < j)
        {
            printf("Game is ending...\n");
            printf("3\n");
            Sleep(1000);
            printf("2\n");
            Sleep(1000);                            //
            printf("1");                        
            Sleep(1000);
            system("cls");

            printf("\t\t\t\t------------------------------------------\n");
            printf("\t\t\t\t|                    |\n");
            printf("\t\t\t\t|  You are the winner. CONGRATULATIONS.  |\n");
            printf("\t\t\t\t|                    |\n");
            printf("\t\t\t\t------------------------------------------\n");
            printf("You know the number at your %d’th guess\n", i);
            printf("Computer know the number at %d’th guess\n\n", j);
            printf("Do you want to play again?\n");
            printf("1)Yes\n");
            printf("2)No\nSelection:");
            scanf_s("%d", &restart);

        }
        else if (i > j)
        {
            printf("Game is ending...\n");
            printf("3\n");
            Sleep(1000);
            printf("2\n");
            Sleep(1000);            //Game end countdown.
            printf("1");
            Sleep(1000);
            system("cls");
            printf("\t\t\t\t-----------------------------------------\n");
            printf("\t\t\t\t|                    |\n");
            printf("\t\t\t\t|      Computer is the winner. You lose.     |\n");
            printf("\t\t\t\t|                    |\n");
            printf("\t\t\t\t-----------------------------------------\n");
            printf("You know the number at your %d’th guess\n", i);
            printf("Computer know the number at %d’th guess\n\n", j);
            printf("Do you want to play again?\n");
            printf("1)Yes\n");
            printf("2)No\nSelection:");
            scanf_s("%d", &restart);
        }
        else
        {
            printf("Game is ending...\n");
            printf("3\n");
            Sleep(1000);
            printf("2\n");
            Sleep(1000);            //Game end countdown.
            printf("1");
            Sleep(1000);
            system("cls");
            printf("\t\t\t\t-----------------------------------------\n");
            printf("\t\t\t\t|                    |\n");
            printf("\t\t\t\t|      Your match ended in a draw. Do you want to play again?    |\n");
            printf("\t\t\t\t|                    |\n");
            printf("\t\t\t\t-----------------------------------------\n");
            printf("You know the number at your %d’th guess\n", i);
            printf("Computer know the number at %d’th guess\n\n", j);
            printf("Do you want to play again?\n");
            printf("1)Yes\n");
            printf("2)No\nSelection:");
            scanf_s("%d", &restart);
        }
    } while (restart == 1);

    system("PAUSE");
    return 0;
}

1 Ответ

9 голосов
/ 15 марта 2020

In a + rand() % b;, rand() % b приводит к числу от 0 до b -1, включительно. Затем добавление a дает число от a до a + b -1 включительно. Таким образом, если a равно 200, а b равно 800, получается число от 200 до 200 + 800−1 = 999 включительно.

Для получения числа от a до b включительно, используйте a + rand() % (b+1-a). Или, чтобы исключить b, используйте a + rand() % (b-a).

Обратите внимание, что:

(a) Использование % со случайным отклонением распределения к низким значениям. Это связано с тем, что диапазон чисел, полученных с помощью rand (от 0 до RAND_MAX включительно), как правило, не делится на b, поэтому существует некоторый остаточный фрагмент, и использование % помещает все числа в этом фрагменте в нижний предел распределения.

(b) Исторические c реализации rand печально известны низкой энтропией в младших битах, поэтому всякий раз, когда b кратно степени двух, скажем, 2 n , младшие биты n не очень случайны.

По этим причинам использование % с rand в этот способ не должен выполняться вне простых классных упражнений и других случайных применений.

...