标题:[原创]猜数字游戏重写版
只看楼主
andyzhshg
Rank: 2
等 级:论坛游民
帖 子:111
专家分:20
注 册:2007-9-1
 问题点数:0 回复次数:13 
[原创]猜数字游戏重写版

*/ --------------------------------------------------------------------------------------
*/ 出自: 编程中国 http://www.bc-cn.net
*/ 作者: andyzhshg
*/ 时间: 2007-9-1 编程论坛首发
*/ 声明: 尊重作者劳动,转载请保留本段文字
*/ --------------------------------------------------------------------------------------
我对前不久在这里发表的猜数字游戏进行了重写,对语句进行了精简,对结构作了一些优化。
虽然说还是很幼稚,但比原作有了不少进步(自夸一下(:)。大家可以同时参考下原作,以做一下对比,
并希望大家继续给我提出意见,以期写出比较完美的程序。

其实这个程序算法上很简单,我之所以写得很长是想实现一个好的人机交互,这可以在creatDialog()
的众多语句中看出来。
此外我改动了以前的随机数生成函数,并对原数和输入数得比较函数的格式完全重写(其实算法大致一样,执行效率不一定能提高,不过代码长度大大减少)。
不足之处还望大家不吝赐教。

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

struct right_place {int right; int place;};

int main (void)
{
int creatDialog (int x, int *p );

void rndProduce (int numDft[]);
struct right_place numCompare (int numDft[], int numIn[]);

int dialog, quitOrContinue, allQuit;
int numDft[4], numIn[4], result[2];
struct right_place compareBack;

creatDialog (1, NULL);

allQuit = 1;
while (allQuit == 1)
{
creatDialog (7, NULL);
rndProduce (numDft);
quitOrContinue = 1;
while (quitOrContinue == 1)
{
dialog = 2;
while (dialog == 2)
{
creatDialog (2, numIn);
dialog = creatDialog (3, numIn);
}
compareBack = numCompare (numDft, numIn);
result[0] = compareBack.right ;
result[1] = compareBack.place ;
quitOrContinue = creatDialog (4, result);
}
if (quitOrContinue == 2)
allQuit = creatDialog (5, numDft);
if (quitOrContinue == 3)
allQuit = 1;
if (quitOrContinue == 4)
allQuit = 2;
}

if (allQuit == 2)
creatDialog (6, NULL);

getchar ();
return 0;
}

int creatDialog (int x, int *p)
{
int back;
int i;
switch (x)
{
case 0:
printf ("************************************************************************\n");
break;
case 1:
creatDialog (0, NULL);
printf ("欢迎玩猜数字游戏!\n版本2.0\n作者:andyzhshg\n制作日期:2007.9.1\n");
creatDialog (0, NULL);
printf ("在本游戏中,你需要输入四个数字,\n然后电脑会给出你猜测的正确情况。");
printf ("电脑会用它之前生成的\n四位数与之你的输入比较,然后告诉你");
printf ("你猜对了几个数字,包\n括数值和顺序的信息.\n");
break;
case 2:
creatDialog (0, NULL);
printf ("请输入你猜测的四位数字(用空格、回车、或Tab隔开):\n");
for (i = 0; i < 4; i++, p++)
scanf ("%i", p);
break;
case 3:
creatDialog (0, NULL);
printf ("你输入的数字是:%i %i %i %i ,确认请输入“1”,重新输入按“2”。\n", *p, *(p + 1), *(p + 2), *(p + 3));
scanf ("%i", &back);
return back;
break;
case 4:
creatDialog (0, NULL);
printf ("你输入的数字中:\n数值和位置都正确的有%i个,\n数值正确但位置不正确的有%i个.\n", *p, *(p+1));
if ((*p) == 4)
{
printf ("恭喜你,答对了!\n");
printf ("继续游戏吗?继续请输入“1”,退出游戏请输入“2”。\n");
scanf ("%i", &back);
if (back == 1)
return 3;
if (back == 2)
return 4;
}
else
{
printf ("继续吗?继续请输入“1”,显示正确答案请输入“2”。\n");
scanf ("%i", &back);
return back;
}
break;
case 5:
creatDialog (0, NULL);
printf ("正确答案是:%i %i %i %i,再接再厉啊!\n", *p, *(p + 1), *(p + 2), *(p + 3));
printf ("继续游戏吗?继续请输入“1”,退出游戏请输入“2”。\n");
scanf ("%i", &back);
return back;
break;
case 6:
creatDialog (0, NULL);
printf ("感谢你玩本游戏,再见!\n按任意键退出\n");
break;
case 7:
creatDialog (0, NULL);
printf ("新的游戏开始了!GOOD LUCK!\n");
break;
default:
break;
}
}

void rndProduce (int numDft[])
{
int i;
srand( (unsigned)time( NULL ) ) ;
for ( i = 0; i < 4; i++)
numDft[i] = rand () % 10;
//printf ("%i %i %i %i\n", numDft[0], numDft[1], numDft[2], numDft[3]);
}

struct right_place numCompare (int numDft[], int numIn[])
{
int i, j;
struct {int Dft; int In;} flag[4] = { 1, 1, 1 ,1 ,1, 1, 1, 1 };
struct right_place result = { 0, 0 };
for (i = 0; i < 4; i++)
if (numDft[i] == numIn[i])
{
(result.right)++;
flag[i].Dft = 0;
flag[i].In = 0;
}
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
if (flag[i].Dft && flag[j].In && numDft[i] == numIn[j])
{
(result.place)++;
flag[i].Dft = 0;
flag[j].In = 0;
}
return result;
}

Fz62cWt8.rar (181.31 KB) [原创]猜数字游戏重写版


搜索更多相关主题的帖子: 数字游戏 重写 中国 原作 
2007-09-01 23:32
雨中飞燕
Rank: 3Rank: 3
等 级:禁止访问
威 望:8
帖 子:2200
专家分:0
注 册:2007-8-9
得分:0 
Good~~~~~~~~的确进步了,加油~~~~~



by 雨中飞燕 QQ:78803110 QQ讨论群:5305909

[url=http://bbs.bc-cn.net/viewthread.php?tid=163571]请大家不要用TC来学习C语言,点击此处查看原因[/url]
C/C++算法习题(OnlineJudge):[url]http://yzfy.org/[/url]
2007-09-01 23:39
Knocker
Rank: 8Rank: 8
等 级:贵宾
威 望:47
帖 子:10454
专家分:603
注 册:2004-6-1
得分:0 
换个思路,反之行事,让电脑猜,看看你的算法能不能做到6次以内猜测到全部数字(4位数).

九洲方除百尺冰,映秀又遭蛮牛耕。汽笛嘶鸣国旗半,哀伤尽处是重生。     -老K
治国就是治吏。礼义廉耻,国之四维。四维不张,国之不国。   -毛泽东
2007-09-02 08:44
xieyu123
Rank: 1
等 级:新手上路
帖 子:17
专家分:0
注 册:2007-8-24
得分:0 
请问你是用的哪个编译器,实现exe文件显示中文的呀???

2007-09-10 12:07
andyzhshg
Rank: 2
等 级:论坛游民
帖 子:111
专家分:20
注 册:2007-9-1
得分:0 
我是在VC6.0下编译的,用C++Builder下也可以通过。

编程并快乐着
2007-09-10 21:05
zrgong
Rank: 1
等 级:新手上路
帖 子:95
专家分:0
注 册:2007-6-26
得分:0 
3楼好提议

2007-09-10 23:34
Eastsun
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:32
帖 子:802
专家分:0
注 册:2006-12-14
得分:0 
确保6步内猜对貌似不太可能.
我写的AI在平均意义下5.15步猜对(随机运行10000次),但最坏的情况要8步.


C:\Documents and Settings\Eastsun\桌面>java -jar GameTest.jar StatAI 10000
Step 1: 1 0.010%
Step 2: 17 0.170%
Step 3: 212 2.120%
Step 4: 1647 16.470%
Step 5: 4788 47.880%
Step 6: 3009 30.090%
Step 7: 324 3.240%
Step 8: 2 0.020%
Step 9: 0 0.000%
Total : 51537 Times : 10000 Avage :5.1537
Use time: 4191984ms

My BlogClick Me
2007-10-10 19:32
freeforever
Rank: 4
等 级:业余侠客
威 望:3
帖 子:368
专家分:201
注 册:2005-11-2
得分:0 

#include <iostream.h>
#include <cstdlib>
int A,B,datacnt=0;
struct data
{
char num[4];
int del;
}mydata[5040];

void compare(char *num)//数据筛选
{
int aa,bb,i,j,k;
for(i=0;i<datacnt;++i)
{//处理所有数据
aa=0;bb=0;
if(mydata[i].del!=1)
{//未被淘汰的数做比较
for(j=0;j<4;++j)
for(k=0;k<4;++k)
if(num[j]==mydata[i].num[k])
if(j==k)++aa;else ++bb;
if(aa==A && bb==B)continue;
else mydata[i].del=1;
}
}
}

int main()
{
int i,j,k,l;
//------------赋值------------------
for(i=0;i<10;++i)
for(j=0;j<10;++j)
for(k=0;k<10;++k)
for(l=0;l<10;++l)
if(i!=j && i!=k && i!=l && j!=k && j!=l && k!=l)
{
mydata[datacnt].num[0] =i+48;
mydata[datacnt].num[1] =j+48;
mydata[datacnt].num[2] =k+48;
mydata[datacnt].num[3] =l+48;
mydata[datacnt].del=0;datacnt++;
}
//------------------------------------
do
{
for(i=0;i<=datacnt;++i)
{
if(i==datacnt)
{ //等于时没有正确答案,用户输入错
cout<<"\nNo asnwer or input error!";
system("pause");exit(0);
}
if(mydata[i].del!=1)
{
cout<<mydata[i].num<<endl;//输出第一个未淘汰的数
cout<<"Input A:";cin>>A;
cout<<"Input B:";cin>>B;
compare(mydata[i].num);
break;
}
}
}while(A<5&&A>=0&&B<5&&B>=0&&A!=4&&A+B<5);
if(A==4&&B==0){cout<<"\nComplete!";cin.get();}
else{cout<<"\nInput error!";cin.get();}
system("pause");
}

OFPTj0pF.rar (7.47 KB)

[此贴子已经被作者于2007-10-10 20:48:59编辑过]



GeRbbuNG.rar (7.47 KB) [原创]猜数字游戏重写版


其实我也很无聊!
2007-10-10 20:43
freeforever
Rank: 4
等 级:业余侠客
威 望:3
帖 子:368
专家分:201
注 册:2005-11-2
得分:0 

忘了说明了,上面的程序是电脑来猜的.

附件里的是GUI界面的EXE文件,用的是随机选数,不好做统计.

下面的代码是对上面代码的效率统计:

#include "stdio.h"
int A,B,datacnt=0;
struct data
{
char num[4];
int del;
}mydata[5040];

void compare(char *num)//数据筛选
{
int aa,bb,i,j,k;
for(i=0;i<datacnt;++i)
{//处理所有数据
aa=0;bb=0;
if(mydata[i].del!=1)
{//未被淘汰的数做比较
for(j=0;j<4;++j)
for(k=0;k<4;++k)
if(num[j]==mydata[i].num[k])
if(j==k)++aa;else ++bb;
if(aa==A && bb==B)continue;
else mydata[i].del=1;
}
}
}

int main()
{
int i,j,k,l,m,times=0,next,res[100];
char ans[4],guess[4];FILE *fp; float step=1.0;
printf("Working.....,please wait for a moment!\n");

fp=fopen("Output.txt","w");fputs("Data list:\n",fp);
for(i=0;i<100;++i)res[i]=0;//初始化统计结果
//------------生成所有合法数----------------
for(i=0;i<10;++i)
for(j=0;j<10;++j)
for(k=0;k<10;++k)
for(l=0;l<10;++l)
if(i!=j && i!=k && i!=l && j!=k && j!=l && k!=l)
{
mydata[datacnt].num[0] =i+48;
mydata[datacnt].num[1] =j+48;
mydata[datacnt].num[2] =k+48;
mydata[datacnt].num[3] =l+48;
datacnt++;
}
//------------------------------------------
for(i=datacnt-1;i>=0;--i)//用循环对合法数中每一个数都取一次值做被猜数
{
printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%4.2f",(step*datacnt-i)/datacnt*100);
putchar('%');printf(" to Complete!");
ans=mydata[i].num; ans[4]=0;//对被猜数赋值
fprintf(fp,"\nGuess Times:%-4d Answer:%s",datacnt-i,ans);//显示第几次猜数
for(j=0;j<datacnt;++j)
mydata[j].del=0;//初始化合法数
do//一次完整的猜数过程
{
times=0;
for(j=0;j<=datacnt;++j)
if(mydata[j].del!=1)//取一个合法数做答
{
fprintf(fp,"\n\tStep:%d Guess:%s",times+1,mydata[j].num);//输出猜测数
next=0; //假设回答正确
for(k=0;k<4;++k)//与答案比较
if(ans[k]!=mydata[j].num[k])//答错
{
next=1; //答错
A=0;B=0; //本次猜数结果初始化
times++; //计数
for(l=0;l<4;++l) //计算出新的A,B值
for(m=0;m<4;++m)
if(mydata[j].num[l]==ans[m])
if(l==m)A++;else B++;
fprintf(fp,"\tA:%d B:%d",A,B); //用猜测数与答案对比做答
compare(mydata[j].num);//刷掉合法数中与答案不匹配的数
break;
}
if(next==0)
{
res[times]++;//答对时统计结果
fprintf(fp,"\tRight!!!");
break;
}
}
}while(next==1);
}
fprintf(fp,"\n\nResult statistic:");
for(i=0;i<100;++i)//输出统计结果
if(res[i]!=0)
{
fprintf(fp,"\n\tTimes[%d]:%-8d\t%4.2f",i+1,res[i],res[i]*step/datacnt*100);
fputc('%',fp);
}
fclose(fp);
printf("\nOK, the result is written in \"Output.txt\"!");
}


其实我也很无聊!
2007-10-10 20:53
nightman
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2007-10-10
得分:0 
好强啊
2007-10-11 23:09



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-167090-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020026 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved