注册 登录
编程论坛 C++教室

投骰子游戏,还有未解决问题,寻帮助!

梦幻尘 发布于 2012-09-26 11:56, 637 次点击
#include<iostream>
#include<cstdlib>
using namespace std;
int rollDice()
{
    int read1=1+rand()%6;
    int read2=1+rand()%6;
    int sum=read1+read2;
    cout<<"poayer rolled "<<read1<<"+"<<read2<<"="<<sum<<endl;
    return sum;
}
enum Zhuangtai{WIN,LOSE,PLAYING};
int main()
{
    int mypoint;
    Zhuangtai status;
    unsigned seed;
    cout<<"请输入随机数种子:";
    cin>>seed;
    srand(seed);[color=#CC3366][color=#FFFF00]//将种子传递给rand()[/color][/color]
    int sum=rollDice();[color=#FFFF00]//第一轮投骰子,计算和数[/color]
    switch(sum)
    {
    case 7:           [color=#FFFF00] //如果和为7或11则为胜,状态为WIN[/color]
    case 11:
        status=WIN;
        break;
    case 2:            [color=#FFFF00]//和数为2,3,12则为负,状态为LOSE[/color]
    case 3:
    case 12:
        status=LOSE;
        break;
    default:    [color=#FFFF00] //其他情况,游戏尚无结果,状态为PLAYING,记下点数,为下一轮做准备[/color]
        status=PLAYING;
        mypoint=sum;
        cout<<"point is "<<mypoint<<endl;
        break;
    }
    while(status==PLAYING) [color=#FFFF00]//只要状态为PLAYING,就继续下一轮[/color]
    {   
        /*mypoint=sum;
        srand(mypoint);*/

        sum=rollDice();
        if(sum=mypoint) [color=#FFFF00]//某轮的和数等于点数则取胜,状态为WIN[/color]
            status=WIN;
        else if(sum==7)  [color=#FFFF00]//如果和数为7则为负,状态为LOSE[/color]
            status=LOSE;
    /*    else
            status=PLAYING;*/
   

    }
    [color=#FFFF00]//当状态不为PLAYING时上面的循环结束,以下程序段输出游戏结束[/color]
    if(status==WIN)
        cout<<"胜"<<endl;
    else
        cout<<"负"<<endl;
    return 0;
}
此程序是用VC++ 6.0编译,下面是运行结果:
请输入随机数种子:8 换成23
poayer rolled 5+1=6   变成 6+3=9
point is 6            变成 9
poayer rolled 6+6=12  变成 5+4=9
胜                       还是胜

但是如果加入/*....*/中的一段,运行结果为:
请输入随机数种子:8 换成23
poayer rolled 5+1=6   变成 6+3=9
point is 6            变成 9
poayer rolled 5+2=7  变成 3+2=5
胜                      还是胜


请帮我修改下,谢谢!(在我的基础上)


还有一个问题,/*...*/之间的一段代码要不要都是正确的,虽然运行结果不同。
当然/*...*/中是我加上的;我的理解为:
既然如果第一轮胜负未分,且是将第一轮点数和sum作为下轮游戏的点数,哪肯定要将sum作为随机数种子通过srand传给rand;
如果去掉那段代码,应该怎样理解。谢谢


[ 本帖最后由 梦幻尘 于 2012-9-27 11:59 编辑 ]
9 回复
#2
眼底星空2012-09-26 13:18
问题出在if(sum=mypoint),始终为True了,应是 ==
要细心
#3
qunxingw2012-09-26 15:30
如果当初C语言设计者们考虑人们使用习惯,把双等号定为赋值符多好啊!当初理解赋值多费劲。
#4
梦幻尘2012-09-27 08:44
还有问题,希望大家帮忙
#5
lz10919149992012-09-27 12:26
没明白LZ的意思,你能再简要阐述一下吗?
#6
lz10919149992012-09-27 13:20
回复 3楼 qunxingw
当初他们设计C时,就是考虑了才使用'='作赋值"=="作等于比较的。在BASIC里,'='充当着赋值和等于比较两种运算,当然这在BASIC里并不会产生混淆,因为'='在BASIC的if里代表等于比较,而在其它地方就是赋值。但是在C里面可能会有这样的代码:int b = 1 == 2; 现在b里就存放着一个1 == 2的比较结果,0或非0。由于C的灵活性,所以BASIC这样的方案是不可行的。但是这样的灵活性下面会产生一些错误,比如:
if (a = 1)
    /* ... */
程序员的原意可能是如果a的值等于1则执行注释那段代码,但是由于粗心,"==" 写成了 '=',导致这个判断始终为真,因为a的值始终是1。
如何避免这样的错误呢?也很简单,只要大家养成这样一个习惯:把常量或枚举放在"=="的左边,也就是这样:
if (1 == a)
    /* ... */
就算粗心把"==" 写成了 '='也不会有问题:
if (1 = a)
    /* ... */
编译器会告诉你:在赋值中一个常量不能作为l-value(左值)。
好了,这样就能及时的发现错误并改正。
当然如果是两个变量进行比较,情况就变得比较棘手了:
if (a = b)
    /* ... */
交换位置是没用的,这就必须靠程序员的严谨,而且现在有一些编译器也能发现这个错误并警告。
Java和C#在这方面就做得比较好,因为true和false是它们支持的一种类型,if的表达式里面必须是布尔值,所以上面这样的错误不会在Java\C#里出现。而C则由非0和0来判断真假,所以只能靠自己。
#7
梦幻尘2012-09-27 21:10
回复 6楼 lz1091914999
你可以再看下我的程序,有一段代码是用/*...*/注释掉的,我不明白的地方就在那里
下面就是我认为那段代码需要的理由。可书上那段却是没有的,


还有一个问题,/*...*/之间的一段代码要不要都是正确的,虽然运行结果不同。
当然/*...*/中是我加上的;我的理解为:
既然如果第一轮胜负未分,且是将第一轮点数和sum作为下轮游戏的点数,哪肯定要将sum作为随机数种子通过srand传给rand;
如果去掉那段代码,应该怎样理解。谢谢
#8
lz10919149992012-09-28 13:01
书上没要那段代码是正确的,因为你加的代码是多余的。
1、sum在下面那个while里面总会被赋值一次,不管以前的值是多少都会被覆盖,所以之后的if是判断的是新值,而跟以前的无关。
2、种子只需要由用户设置一次就好,不要以为第一次调用rand()和第二次调用rand()它们的结果会肯定一样。而设置不同的种子在调用rand()之后产生不一样的结果的几率会更大。其实更好的方法是用srand(time(0));来设置种子,因为时间总是在变化的,这样就可以保证与上次设置的种子不一样。
3、else那部分也不需要,因为进入while里,它的值一直都是PLAYING,除非进入了上面的两个if。

这些都是很简单的逻辑问题,相信LZ应该能明白。
#9
梦幻尘2012-09-29 08:43
回复 8楼 lz1091914999
谢谢,是我还没理清题目的意思,刚开始还准备反驳你的,但想着想着才理清意思,题目意思是如果第一轮没分胜负,则将第一轮所得的点数和作为自己的点数,继续下去,此点数应该是不会变的。我理解为要将其作为下轮随机数种子,用其所得的点数和与随机数种子比较了,此时点数就会变化;
如果按我的理解代码应该不多余吧。不知理解是否有误,请解答。
#10
lz10919149992012-09-30 00:45
回复 9楼 梦幻尘
每次生成点数的时候都可以设置一次种子,但设不设置我觉得都可以,因为rand()总会返回一个随机数。
1