【问题标题】:C++ Guessing a number within a range using srand(time(0))C++ 使用 srand(time(0)) 猜测一个范围内的数字
【发布时间】:2014-08-07 23:38:03
【问题描述】:

好的,这是我的问题...我几乎完成了我制作的小游戏,但我想测试它是否适用于“调试作弊”,以查看程序是否实际上向您显示了正确的数字。

我设置了 srand(time(0)) ,这样当你玩游戏时,程序显然每次都会使数字选择不同。不过,它显然会不断生成不同的数字,因为系统时间在变化。

正如您在代码中看到的,我有一个名为“ANSWER”的变量,即 Range(low,high)。检查名为“guessN”的用户输入变量以查看它是否与“ANSWER”匹配。如果是这样,那么程序会说用户赢得了游戏,我相信这是有效的。

问题是当我想要程序时首先显示答案是什么,恰好是 47,当我输入 47 时,它实际上是错误的,因为时间生成器仍在运行并且已经是 37 岁了。

我需要什么帮助:目前有没有办法暂停生成,直到用户输入他的答案?..

提前感谢您对我的帮助! :)

屏幕截图:

http://i.imgur.com/mVRSWCU.png

#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib> // For srand and rand

using namespace std;

/*Guessing Game: Program generates random #'s,
user has 3 chances to guess one number at a time,
otherwise the Computer wins.
*/


static unsigned int rangevalue;

void NewRange(int nLow, int nHigh) // Range for generated #'s.
{
    rangevalue = (rand() % (nHigh - nLow + 1)) + nLow;
}


unsigned int getRange() 
{
    return rangevalue;
}

//DON'T GET LOST!
string DescRange; // Descriptive Range
string SelectionInput;
int low = 1;
int high;
//DON'T GET LOST!

void NumberGen()
{



    do
    {
        cout << "Guess a number in between...\n " << endl;
        cout << "1.) 1-5\t\t[EASY]" << endl;
        cout << "2.) 1-10\t[MEDIUM]" << endl;
        cout << "3.) 1-50\t[HARD]" << endl;
        cout << "4.) 1-100\t[IMPOSSIBLE]" << endl;
        cout << "\n5.) Choose a custom range? *" << endl;
        cout << "6.) EXIT \n" << endl;
        cout << "=> ";
        getline(cin, SelectionInput);

    } while (
           SelectionInput != "1" && SelectionInput != "2" && SelectionInput != "3" && SelectionInput != "4" && SelectionInput != "5" && SelectionInput != "6"
        && SelectionInput != "EASY" && SelectionInput != "Easy" && SelectionInput != "easy"
        && SelectionInput != "MEDIUM" && SelectionInput != "Medium" && SelectionInput != "medium"
        && SelectionInput != "HARD" && SelectionInput != "Hard" && SelectionInput != "hard"
        && SelectionInput != "IMPOSSIBLE" && SelectionInput != "Impossible" && SelectionInput != "impossible"
        && SelectionInput != "CUSTOM" && SelectionInput != "Custom" && SelectionInput != "custom" 
        && SelectionInput != "EXIT" && SelectionInput != "Exit" && SelectionInput != "exit"
            );



    if (SelectionInput == "1" || SelectionInput == "EASY" || SelectionInput == "Easy" || SelectionInput == "easy")
    {
        high = 5;
        DescRange = "1-5";

        cout<<"\t[Input was \"" << SelectionInput << "\"]\n\n" << endl;

    }

    else if (SelectionInput == "2" || SelectionInput == "MEDIUM" || SelectionInput == "Medium" || SelectionInput == "medium")
    {
        high = 10;
        DescRange = "1-10";
        cout<<"\t[Input was \"" << SelectionInput << "\"]\n\n" << endl;

    }

    else if (SelectionInput == "3" || SelectionInput == "HARD" || SelectionInput == "Hard" || SelectionInput == "hard")
    {
        high = 50;
        DescRange = "1-50";
        cout<<"\t[Input was \"" << SelectionInput << "\"]\n\n" << endl;

    }

    else if (SelectionInput == "4" || SelectionInput == "IMPOSSIBLE" || SelectionInput == "Impossible" || SelectionInput == "impossible")
    {
        high = 100;
        DescRange = "1-100";
        cout<<"\t[Input was \"" << SelectionInput << "\"]\n\n" << endl;

    }

    else if (SelectionInput == "5" || SelectionInput == "CUSTOM" || SelectionInput == "Custom" || SelectionInput == "custom")
    {

        cout<<"\t[Input was \"" << SelectionInput << "\"]\n\n" << endl;

        cout << "Input a digit range for you to guess a number in between. " << endl;

        cout << "Low: ";
        cin >> low;

        cout << "High: ";
        cin >> high;

    }

    else if (SelectionInput == "6" || SelectionInput == "EXIT" || SelectionInput == "Exit" || SelectionInput == "exit")
    {

        high = 10;

        cout << "\nYou've chosen to terminate the program!" << "\t[Input was \"" << SelectionInput << "\"]\n\n" << endl;
        for (int iii = 0; iii < 5; iii++)
        {
            cout << "The program will now collapse..." << endl;

        }

        cout << "\n" << endl;

    }



    NewRange;

    int ANSWER = getRange();


    cout << "For debugging/test purposes, the range is: \"" << ANSWER << "\". \n" << endl; // DEBUG for knowing what the 'ANSWER' is.


}



void Guessing()
{


    NumberGen();

    int ANSWER = getRange(); // Making things SIMPLE
    int guessN;

    if (SelectionInput == "5" || SelectionInput == "CUSTOM" || SelectionInput == "Custom" || SelectionInput == "custom")
    {

        cout << "Guess the number I picked between " << low << "-" << high << ": ";


        cin >> guessN;

        if (guessN == ANSWER)
            cout << "Oh no, you won! The answer \"" << guessN << "\", is... correct! \n\n" << endl;

        else
            cout << "\nSorry you lose, try again! Answer was " << ANSWER << ". \n\n" << endl;



    }

    else
    {
        cout << "Guess the number I picked between " << DescRange << ": ";

        cin >> guessN;

        if (guessN == ANSWER)
            cout << "Oh no, you won! The answer \"" << guessN << "\", is... correct! \n\n" << endl;

        else
            cout << "\nSorry you lose, try again! Answer was "<<ANSWER<<". \n\n" << endl;


    }



}


int main()
{

    srand(time(0));

    Guessing();







//system("PAUSE");      //  * Temporarily Disabled *

    return 0;

}

【问题讨论】:

  • NumberGen 有一个int Answer,而Guessing 有一个完全不同的int ANSWER 变量,它们分别被初始化。为什么你会期望这些数字是一样的。
  • 其实我是这么想的!不过,我将如何解决这个问题,因为显然 srand(time(0)) 必须在 int ANSWER 之前声明
  • srand() 只是随机生成器的种子——你根本不需要调用它,只要你每次都能得到相同的“随机”数字序列——所以移动srand() 到 main,只有在你真正想要一个新范围时才调用你的“范围”函数。
  • 但是如果人们再次玩这个游戏,他们不会得到同样的可预测答案吗?不会有什么不同。
  • @Jordan -- 是的,他们会的 -- 这就是为什么我说“只要你对获得相同的序列感到满意”。如果不是,您只需要在程序的生命周期中播种一次,而不是在执行 rand() 之前的每次调用中播种 - 如果您播种多次,您实际上将面临每次 rand() 调用获得相同数字的风险,如果您经常这样做,并且每次调用都会重置生成器。

标签: c++ random range srand


【解决方案1】:

你应该在你的程序中只执行一次srand(time(0))——在调用其他代码之前将它移动到 main() 程序。

srand(time(0)) 在涉及安全性的情况下通常被认为是一个坏主意,但这是一个不同的话题,在这里讨论太长了。

编辑

对您的代码最简单的解决方法是创建两个函数——一个用于生成新值,一个用于检索该值;

static unsigned int rangevalue;
void NewRange(int nLow, int nHigh) // Range for generated #'s.
{
    rangevalue = (rand() % (nHigh - nLow + 1)) + nLow;
}
unsigned int getRange() {
    return rangevalue;
}

然后在你的代码中使用这两个函数。

如果你想让你的代码更像 C++,考虑使用类概念来包装你的逻辑......类似的东西;

class RangeValues {
    unsigned int rvalue;
public:
    RangeValues() {
       static bool initialized = false;
       if (!initialized) {
          initialized = true;
          srand(time(0));
       }
       rvlaue = rand();
    }
    unsigned getRange(int nLow, int nHigh) { // Range for generated #'s.
        return (rvalue % (nHigh - nLow + 1)) + nLow;
    }
}

每次创建 RangeValues 的新实例时都会生成一个新值,然后您可以通过引用传递它。

【讨论】:

  • 谢谢你,但这并没有解决我的实际问题:(
  • rand() cal;l 每次 cal;led 都会返回一个新的数字(例如一个新的随机数)——所以如果你想重用(或按你说的暂停它),你将需要将其存储在局部变量中,并且仅在需要新号码时才调用rand()
  • 我不确定你对什么感到困惑——你为每个问题和每个答案多次调用 Range——你只需要调用一次
  • 噢噢噢!我现在明白了。我只是使用呼叫向用户显示号码,而不是重置它。我怎样才能解决这个问题只是为了显示范围?
  • 我更新了答案,建议您如何实现“显示”功能......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多