在C++中是否有更有效的生成随机数的算法?
(这段代码正在Dev-C++上运行,但我不确定它是否能在Borland编译器上工作。)
/*
Author: Arpit Agrawal
Email: arpitagrawal294@gmail.com
Description: Dice Roll Algorithm.
Project Name: e-Roll.
*/
#include<iostream.h>
#include<conio.h>
#include<time.h>
#include<stdlib.h>
#include <stdio.h>
#include <Windows.h>
void call();
void one();
void two();
void three();
void four();
void five();
void six();
void call();
int main()
{
//gotoxy(30,15);
cout<<"\n\n\n\n\t\tAuthor: Arpit Agrawal\n\t\tEmail: arpitagrawal294@gmail.com\n\t\tDescription: Dice Roll Algorithm.\n\t\tProject Name: e-Roll.\n\t\t" ;
cout<<"\n\n\t\tLoading. . . . . . . ";
Sleep(3000);
cout<<"\n\n\t\tPress r to roll or q to quit the game "<<endl;
char ch;
ch = getch();
xm:
if (ch=='r'){
system("cls");
call(); }
else
exit (0);
cout<<endl<<endl<<"Press r to roll again q to quit!";
ch = getch();
goto xm;
getch();
}
void call()
{
srand (time(NULL));
int n;
n= rand();
n = 1 + n % 6;
switch (n)
{
case 1:
one();
break;
case 2:
two();
break;
case 3:
three();
break;
case 4:
four();
break;
case 5:
five();
break;
case 6:
six();
break;
default:
cout<<"NONUM";
}
}
void one()
{
cout << " -----" << endl;
cout << "| |" << endl;
cout << "| O |" << endl;
cout << "| |" << endl;
cout << " -----" << endl;
}
void two()
{
cout << " -----" << endl;
cout << "| O|" << endl;
cout << "| |" << endl;
cout << "|O |" << endl;
cout << " -----" << endl;
}
void three()
{
cout << " -----" << endl;
cout << "| O|" << endl;
cout << "| O |" << endl;
cout << "|O |" << endl;
cout << " -----" << endl;
}
void four()
{
cout << " -----" << endl;
cout << "|O O|" << endl;
cout << "| |" << endl;
cout << "|O O|" << endl;
cout << " -----" << endl;
}
void five()
{
cout << " -----" << endl;
cout << "|O O|" << endl;
cout << "| O |" << endl;
cout << "|O O|" << endl;
cout << " -----" << endl;
}
void six()
{
cout << " -----" << endl;
cout << "|O O|" << endl;
cout << "|O O|" << endl;
cout << "|O O|" << endl;
cout << " -----" << endl;
}
发布于 2013-09-29 11:57:24
只在应用程序中调用srand()
一次:
srand (time(NULL));
应该是在main()
启动之后。
这不会产生均匀分布的随机数。
n= rand();
n = 1 + n % 6;
这是因为rand()返回来自[0,RAND_MAX)或[0,32767)的数字,该数字不能完全被6整除。
1: 1/5462 Notice this is one more than the others.
2: 1/5461
3: 1/5461
4: 1/5461
5: 1/5461
6: 1/5461
对于一个简单的应用程序来说,这可能不是一个问题,但值得注意。这样做的正确方法是:
int dieRoll() // 1-6 evenly distributed.
{
static int const max = RAND_MAX/6*6;
int r = rand();
while(r >= max) { r = rand();}
return r%6+1;
}
最好不要使用goto:
xm:
if (ch=='r'){
system("cls");
call(); }
else
exit (0);
cout<<endl<<endl<<"Press r to roll again q to quit!";
ch = getch();
goto xm;
更喜欢(标准循环):
while (ch=='r') {
system("cls");
call();
cout<<endl<<endl<<"Press r to roll again q to quit!";
ch = getch();
}
让我们也压缩您的开关语句:
switch (n) {
case 1: one();break;
case 2: two();break;
case 3: three();break;
case 4: four();break;
case 5: five();break;
case 6: six();break;
// We know the number will never be anything else
// so don't need the default.
}
不需要使用那么多std::endl。
cout << " ----- \n"
<< "|O O|\n"
<< "| |\n"
<< "|O O|\n"
<< " -----" << endl;
endl用于刷新输出。如果您只想要一个新行,请使用"\n“。
发布于 2014-08-13 10:02:15
你的函数名是完全没用的。它们都应该是动词形式,因为它们执行一个动作,使函数的目的明确。您已经在call()
中这样做了,尽管名称本身并不有用,因为函数是调用的。
根据他们正在做的事情,call()
可以重命名为类似runGame()
的东西,其余的可以重命名为displayDiceX()
(用相应的数字替换X
)。
main()
函数不同代码行之间没有分离(基于目的),条件语句中也没有任何缩进。不仅如此,您还使用了goto
,它很有可能导致“意大利面代码”(这不是件好事)。尽量保持控制流尽可能容易遵循。
我很难一目了然地理解逻辑,但有一点是有意义的,那就是输出,甚至其中的一些也很奇怪。它不是技术上的“加载”,如果它是睡了一段时间,虽然我可以理解你想要达到的审美效果。另外,你真的需要输出你的电子邮件地址吗?这和这个项目有什么关系?
我也不知道你为什么把这些函数缩进右边。您已经正确地对齐了main()
,那么为什么其他的不对齐呢?乍一看,我认为所有这些都是main()
的一部分,使我认为您缺少了函数定义。您还没有在这些"number“函数中缩进代码,尽管您在其他地方正确地完成了它。尽量让事情保持一致。
总的来说,这看起来像C代码,一点也不像C++。为了学习的目的,保持简单是可以的,但是这可能需要大量的工作来使它看起来像一个理想的游戏实现。
如果您想更进一步,使它看起来更像C++,请考虑定义您自己的类,例如Game
和Die
类。Game
类将定义游戏规则,而Die
类将表示一个骰子,并允许您创建骰子(Die
对象)。Game
类将处理大部分工作,main()
只需要有一个可以调用public
接口函数来运行游戏的Game
对象。在main()
中不需要做任何其他事情。
发布于 2014-08-13 12:04:36
你的main()
很乱而且很难读懂.我不会对while
循环发表评论,因为其他人已经这样做了(我同意他的意见),但从风格上讲,为了使您的代码更具可读性,您希望有适当的缩进:
int main()
{
//gotoxy(30,15);
cout<<"\n\n\n\n\t\tAuthor: Arpit Agrawal\n\t\tEmail: arpitagrawal294@gmail.com\n\t\tDescription: Dice Roll Algorithm.\n\t\tProject Name: e-Roll.\n\t\t" ;
cout<<"\n\n\t\tLoading. . . . . . . ";
Sleep(3000);
cout<<"\n\n\t\tPress r to roll or q to quit the game "<<endl;
char ch;
ch = getch();
xm:
if (ch=='r') {
system("cls");
call();
}
else
exit (0);
cout<<endl<<endl<<"Press r to roll again q to quit!";
ch = getch();
goto xm;
getch();
}
我不知道你的目标是什么,但这就是你的代码所做的。最后一个getch()
永远不会因为goto xm
语句而被执行,而且它真的是一团糟。只有在ch=='r'
中才能执行这3行代码,所以在该块中使用它就更清楚了。
无论如何,做你想做的事情的最好的方法就是循环--即使它有效地和你的goto
做同样的事情,它也是最清晰的。使用goto
,您必须分析代码以确定您想要循环行为。当有人看while
时,他们会自动知道它会根据while
内的条件循环。
https://codereview.stackexchange.com/questions/31980
复制