24点游戏(c语言)

【作业描述】
24点游戏是经典的纸牌益智游戏。
常见游戏规则:
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
基本要求: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式,用擅长的语言(C/C++/Java或其他均可)实现程序解决问题。
1.程序风格良好(使用自定义注释模板)
2.列出表达式无重复。
提高要求:用户初始生命值为一给定值(比如3),初始分数为0。随机生成4个代表扑克牌牌面的数字或字母,由用户输入包含这4个数字或字母的运算表达式(可包含括号),如果表达式计算结果为24则代表用户赢了此局。
1. 程序风格良好(使用自定义注释模板)
2.使用计时器要求用户在规定时间内输入表达式,如果规定时间内运算正确则加分,超时或运算错误则进入下一题并减少生命值(不扣分)。
3.所有成绩均可记录在TopList.txt文件中。
【设计思路】
构造出四个范围在1到13的随机数作为计算24点中四张扑克牌,再定义出运算符号,用字符串存着,定义计算正确答案的函数,文件保存。再定义判断函数,用一个字符串存着用户输入的计算表达式,再和保存的正确答案对比。错误则扣去生命值,直到生命值扣到零,游戏自动结束。
【代码实现】

/*24点游戏
随机生成四张扑克牌
输入计算式,机器判断是否正确,
可以随机生成三次牌,若三次都回答错误,
则游戏失败 
*/ 
#include
#include
#include
#include
#include 
#include 
int treat(float a,float b,float c,float d,char *s,int *sss);
float myF(int flag,float m,float n);
void myPrint(int type,int i,int j,int k,float a,float b,float c,float d);
void my(int type,int i,int j,int k,float a,float b,float c,float d,char *s,int *sss);
int temp=0;
//发牌函数、产生四个随机数
int Deal(int *a,int *b,int *c,int *d)
{ 
	int i,p;
	srand(time(0));
	int q=0;
	for(i=0;i<4;i++)
	{
		p=rand()%12+1; // 产生的随机数a作为增量,范围1-10
		q=q+p;
		if(i==0) *a=q%13+1;//a,b,c,d代表了发的四个牌
		if(i==1) *b=q%13+1;
		if(i==2) *c=q%13+1;
		if(i==3) *d=q%13+1;
	}
return 0;
}

//计算正确答案的函数
int treat(float a,float b,float c,float d,char *s,int *sss)
{
	int i,j,k;
	float sum1,sum2,sum3;
	for (i=0;i<4;i++)
		for (j=0;j<6;j++)
			for (k=0;k<6;k++)
			{
				if ((!(i==3 && b==0)) && (!(j==3 && c==0)) && (!(k==3 && d==0)))
				{
					sum1=myF(i,a,b);
					sum2=myF(j,sum1,c);
					sum3=myF(k,sum2,d);
					if (fabs(sum3-24)<0.1)
					{
						temp++;
						my(3,i,j,k,a,b,c,d,s,sss);//判断玩家答案正确
						myPrint(1,i,j,k,a,b,c,d);//输出正确答案 
					}
				}
				if (k==2)
				{
					sum1=myF(i,a,b);
					sum2=myF(j,c,d);
					sum3=sum1*sum2;
					if (fabs(sum3-24)<0.1)
					{
						temp++;
						my(3,i,j,k,a,b,c,d,s,sss);//判断玩家答案正确
						myPrint(2,i,j,k,a,b,c,d);//输出正确答案
					}
				}
				if (k==3)
				{
					sum1=myF(i,a,b);
					sum2=myF(j,c,d);
					if (sum2!=0)
					{
						sum3=sum1/sum2;
						if (fabs(sum3-24)<0.1)
						{
							temp++;
							my(3,i,j,k,a,b,c,d,s,sss);//判断玩家答案正确
							myPrint(3,i,j,k,a,b,c,d);//输出正确答案
						}
					}
				}
			}
		if (temp==0)
		return 0;
		else
		return 1;
}

//表达式计算
float myF(int flag,float m,float n)//运算符号 
{
	if (flag==0)
	return (m+n);//定义加 
	if (flag==1)
	return (m-n);//定义减 
	if (flag==2)
	return (m*n);//定义乘 
	if (flag==3)
		if (n==0)
		return 30000;//无穷大 
		else
		return (m/n);//定义除 
	if (flag==4)
	return (n-m);
	if (flag==5)
		if (m==0)
		return 30000;
		else
		return (n/m);
	return 0;
}

//判断玩家答案是否正确的函数
void my(int type,int i,int j,int k,float a,float b,float c,float d,char *s,int *sss)
{
	char sigle[6];
	char ss[20];//保存正确答案
	sigle[0]='+';
	sigle[1]='-';
	sigle[2]='*';
	sigle[3]='/';
	sigle[4]='-';
	sigle[5]='/';
	if (type==1)
	{
		if(j==4 || j==5)
		{
			if (k==4 || k==5)
			{
			sprintf(ss,"(%2.0f%c(%2.0f%c%2.0f))%c%2.0f",c,sigle[j],a,sigle[i],b,sigle[k],d); 
			if(strcmp(ss,s)==0) *sss=1;//判断玩家答案是否正确
			}
			else
			{
			sprintf(ss,"(%2.0f%c(%2.0f%c%2.0f))%c%2.0f",c,sigle[j],a,sigle[i],b,sigle[k],d);
			if(strcmp(ss,s)==0) *sss=1;//判断玩家答案是否正确
			}
		}
		else if (k==4 || k==5)
		{
		sprintf(ss,"%2.0f%c((%2.0f%c%2.0f)%c%2.0f)",d,sigle[k],a,sigle[i],b,sigle[j],c);
		if(strcmp(ss,s)==0) *sss=1;//判断玩家答案是否正确
		}
		else
		{
		sprintf(ss,"((%2.0f%c%2.0f)%c%2.0f)%c%2.0f",a,sigle[i],b,sigle[j],c,sigle[k],d);
		if(strcmp(ss,s)==0) *sss=1;//判断玩家答案是否正确
		}
	}
	if (type==2 || type==3)
	{
	sprintf(ss,"(%2.0f%c%2.0f)%c(%2.0f%c%2.0f)",a,sigle[i],b,sigle[k],c,sigle[j],d);
	if(strcmp(ss,s)==0) *sss=1;//判断玩家答案是否正确
	}
}

//显示正确答案,文件保存正确答案
void myPrint(int type,int i,int j,int k,float a,float b,float c,float d)
{
	FILE *fp;
	if((fp=fopen("data.txt","a+"))==NULL)
	{
	printf("Cannot open file strike any key exit!");
	getchar();
	exit(1);
	}	 
	//追加方式打开文件
	char sigle[6];
	sigle[0]='+';
	sigle[1]='-';
	sigle[2]='*';
	sigle[3]='/';
	sigle[4]='-';
	sigle[5]='/';
	if (type==1)
	{
		if(j==4 || j==5)
		{
			if (k==4 || k==5)
			{			
				printf("%2.0f %c (%2.0f %c (%2.0f %c %2.0f)) =24\n",d,sigle[k],c,sigle[j],a,sigle[i],b);
				fprintf(fp,"%2.0f %c (%2.0f %c (%2.0f %c %2.0f)) =24\n",d,sigle[k],c,sigle[j],a,sigle[i],b);
				//显示正确答案,文件保存正确答案
			}
			else
			{
				printf("(%2.0f %c (%2.0f %c %2.0f)) %c %2.0f =24\n",c,sigle[j],a,sigle[i],b,sigle[k],d);
				fprintf(fp,"(%2.0f %c (%2.0f %c %2.0f)) %c %2.0f =24\n",c,sigle[j],a,sigle[i],b,sigle[k],d);
				//显示正确答案,文件保存正确答案
			}
		}
		else if (k==4 || k==5)
		{
			printf("%2.0f %c ((%2.0f %c %2.0f) %c %2.0f) =24\n",d,sigle[k],a,sigle[i],b,sigle[j],c);
			fprintf(fp,"%2.0f %c ((%2.0f %c %2.0f) %c %2.0f) =24\n",d,sigle[k],a,sigle[i],b,sigle[j],c);
			//显示正确答案,文件保存正确答案
		}
		else
		{
			printf("((%2.0f %c %2.0f) %c %2.0f) %c %2.0f =24\n",a,sigle[i],b,sigle[j],c,sigle[k],d);
			fprintf(fp,"((%2.0f %c %2.0f) %c %2.0f) %c %2.0f =24\n",a,sigle[i],b,sigle[j],c,sigle[k],d);
			//显示正确答案,文件保存正确答案
		}
	}
	if (type==2 || type==3)
	{
		printf("(%2.0f %c %2.0f) %c (%2.0f %c %2.0f) =24\n",a,sigle[i],b,sigle[k],c,sigle[j],d);
		fprintf(fp,"(%2.0f %c %2.0f) %c (%2.0f %c %2.0f) =24\n",a,sigle[i],b,sigle[k],c,sigle[j],d);
		//显示正确答案,文件保存正确答案
	}
	
	fclose(fp);
}

//主函数,整个24点游戏的循环
int main()
{
	int w;
	int z=2;
	printf("***************************************************\n");
	printf("#                欢迎来到24点游戏                 #\n");
	printf("#   1.进入游戏                    2.退出游戏      #\n");
	printf("#                                                 #\n");
	printf("***************************************************\n");
	scanf("%d",&w);//游戏登录界面 
	for(z=2;z>0;z--)
	{
	if(w==1)
	{
		FILE *fp;
		if((fp=fopen("data.txt","w"))==NULL)
		{
			printf("Cannot open file strike any key exit!");
			getchar();
			exit(1);
		}	 
		fclose(fp);//打开文件,清空之前记录,并检查文件是否存在
		int i,j,k,t,again,res,flag;
		float num[4];
		again=1;
		while(again==1)
		{	
			i=0;
			flag=0;
			while (flag==0)
			{
				i++;
				for(i=0;i<4;i++)
				{
					int a,b,c,d;
					Deal(&a,&b,&c,&d);//随机发牌,产生四个数
					if(i==0) 
					{
						num[i]=(float)a; 
						if(a==11)
						printf ("第%d张牌J\n",i+1);
						else if(a==12)
						printf ("第%d张牌Q\n",i+1);
						else if(a==13)
						printf ("第%d张牌K\n",i+1);
						else if(a==1)
						printf ("第%d张牌A\n",i+1);
						else
						printf ("第%d张牌%d\n",i+1,(int)num[i]);
						//将随机发牌,产生的第一个数保存并输出
					}
					if(i==1)
					{
						num[i]=(float)b; 
						if(b==11)
						printf ("第%d张牌J\n",i+1);
						else if(b==12)
						printf ("第%d张牌Q\n",i+1);
						else if(b==13)
						printf ("第%d张牌K\n",i+1);
						else if(b==1)
						printf ("第%d张牌A\n",i+1);
						else
						printf ("第%d张牌%d\n",i+1,(int)num[i]);
						//将随机发牌,产生的第二个数保存并输出
					}
					if(i==2)
					{	
						num[i]=(float)c; 
						if(c==11)
						printf ("第%d张牌J\n",i+1);
						else if(c==12)
						printf ("第%d张牌Q\n",i+1);
						else if(c==13)
						printf ("第%d张牌K\n",i+1);
						else if(c==1)
						printf ("第%d张牌A\n",i+1);
						else
						printf ("第%d张牌%d\n",i+1,(int)num[i]);
						//将随机发牌,产生的第三个数保存并输出
					}
					if(i==3)
					{
						num[i]=(float)d;
						if(d==11)
						printf ("第%d张牌J\n",i+1);
						else if(d==12)
						printf ("第%d张牌Q\n",i+1);
						else if(d==13)
						printf ("第%d张牌K\n",i+1);
						else if(d==1)
						printf ("第%d张牌A\n",i+1);
						else
						printf ("第%d张牌%d\n",i+1,(int)num[i]);
						//将随机发牌,产生的第四个数保存并输出
					}
					if (num[i]<1 || num[i]>13 || num[i]!=int(num[i]))
					flag++;
				}
			if(flag!=0)
			{
				printf ("Error input again\n",i);
				flag=0;
			}
			else
			flag=1;
		} 
		char s[20];//保存玩家输入的结果
		int sss=0;//保存玩家答案是否正确
		printf("请输入一个算式以得到24点:");
		scanf("%s",s);
		int a=1;
		while(a<2)
		{
			printf("正确答案如下:\n");
			for (i=0;i<4;i++)
				for (j=0;j<4;j++)
					if (j!=i)
						for (k=0;k<4;k++)
							if (k!=j && k!=i)
								for (t=0;t<4;t++)
									if (t!=i && t!=j && t!=k)
									{
										res=treat(num[i],num[j],num[k],num[t],s,&sss);
									}
										if (res==0)
										{
											printf ("\n无法算出24点\n");
											break;
										}
										if(a==0)
										{
											if(sss==1)
											{
												printf("恭喜你!您的回答正确\n");
												a++;
											}
											else
											{
												printf("很遗憾!您的回答错误\n");
												int c;
												c=getch();
												if(c=='1') {}
												else if(c=='2') {a++;}
												}
										}
										a++;
										}
										if(z>0)
										{
											printf("您还有%d次机会\n",z);
											z--; 
											printf("按任意键进入下一题!\n");
											getch();
										}
										else
										printf("很遗憾,您已经没有机会了,退出游戏\n"); 
									}																	
								}
							}
						system("pause");
						return 0;	
						}

【经验归纳】
这又是一个数学相关的编程题,我第一次看到题的时候是懵的,因为我自己24点都算不出来,还要告诉计算机怎么算,真的有点为难我,所以我想了很久后,还是选择了去网上查找资料,看了别人的代码,还是明白了一些,最后用了穷举法,所有括号的可能性全部列出,然后再把随机生成的四个随机数,还有六种运算符代入进去,如果可以计算结果为24则结果输出,虽然是这么说,但是for的多重循环还是让我很迷茫。
对于提高要求,因为最近文件写的还是挺多的,在互联网的帮助下,也在我自己的几番尝试下,文件终于可以读写了。判断正确还有点小问题,不过判断错误是没问题的。。而且还是不会用定时器,还不会记录成绩。。。这次的作业依旧让我很惆怅,让我觉得我离了网络就是一条咸鱼了。。。唉,只能再继续好好学习!知道问题就是进步的开始!加油!

你可能感兴趣的:(24点游戏(c语言))