[考试专用]24点小游戏完整不超纲代码

最近在问答里面看见有人问这个问题,本着助人为乐的一贯原则,把代码发出来,祝大家顺利过关~!

原题目是:
`
1) 随机给出 4 个数字(1~9),要求只用加减乘除判断是否能够算出 24,如果能够算出,需要给出计算过程(需要加括号的地方必须加上括号),如果没有解,则显示“无解!”;

2) 也可以实现用户输入计算表达式,由程序来验证的功能,如果正确,则显示“你真棒!”的结果,否则,显示“输入错误,请重试!”;

3) 程序具有检错功能;

4) 编写菜单系统;
`

代码基于Visual Studio 2019环境调试通过,其他环境请自行调整一下,我只能帮你到这里了。

#define _CRT_SECURE_NO_WARNINGS
#include <time.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

int const NUMBERCOUNT = 4;
float const RESULT = 24;
bool isHit = false;
bool showanswer = true;

char* ExpressPool;
int PoolIdx;
int MAX_RESULT = 1500;


enum OPT {
	PLU,//加
	MIN,//减
	MINBY,//被减
	MUL,//乘
	DIV,//除
	DIVBY//被除
};


float cal(int ncount, float* nums, char* exps)
{

	float a, b;
	if (ncount == 2)
	{
		a = nums[0];
		b = nums[1];

		OPT opt;
		float result = 0.0f;

		for (opt = PLU; opt <= DIVBY; opt = (OPT)(opt + 1))
		{
			switch (opt)
			{
			case PLU:
				result = a + b;
				if (result == RESULT)
				{
					sprintf(ExpressPool + PoolIdx * 32, "%s+%s", exps, exps + 32);
					PoolIdx++;
					sprintf(ExpressPool + PoolIdx * 32, "%s+%s", exps + 32, exps);
					PoolIdx++;
					isHit = true;
				}
				break;
			case MIN:
				result = a - b;
				if (result == RESULT)
				{
					sprintf(ExpressPool + PoolIdx * 32, "%s-%s", exps, exps + 32);
					PoolIdx++;
					isHit = true;
				}
				break;
			case MINBY:
				result = b - a;
				if (result == RESULT)
				{
					sprintf(ExpressPool + PoolIdx * 32, "%s-%s", exps + 32, exps);
					PoolIdx++;
					isHit = true;
				}
				break;
			case MUL:
				result = a * b;
				if (result == RESULT)
				{
					sprintf(ExpressPool + PoolIdx * 32, "%s*%s", exps, exps + 32);
					PoolIdx++;
					sprintf(ExpressPool + PoolIdx * 32, "%s*%s", exps + 32, exps);
					PoolIdx++;
					isHit = true;
				}
				break;
			case DIV:
				if (b == 0)continue;
				result = a / b;
				if (result == RESULT)
				{
					sprintf(ExpressPool + PoolIdx * 32, "%s/%s", exps, exps + 32);
					PoolIdx++;
					isHit = true;
				}
				break;
			case DIVBY:
				if (a)continue;
				result = b / a;
				if (result == RESULT)
				{
					sprintf(ExpressPool + PoolIdx * 32, "%s/%s", exps + 32, exps);
					PoolIdx++;
					isHit = true;
				}
				break;
			}
		}

	}
	else
	{
		for (int i = 0; i < ncount; i++)
		{
			for (int j = 0; j < ncount; j++)
			{
				if (i != j)
				{
					int newcount = ncount - 1;
					float* num = new float[newcount];
					char* newexps = (char*)malloc(32 * newcount);
					memset(newexps, 0, 32 * newcount);
					int idx = 1;
					for (int m = 0; m < ncount; m++)
					{
						if (m != i && m != j)
						{
							num[idx] = nums[m];
							strcpy(newexps + idx * 32, exps + m * 32);
							idx++;
						}
					}
					OPT opt;
					for (opt = PLU; opt <= DIVBY; opt = (OPT)(opt + 1))
					{
						switch (opt)
						{
						case PLU:
							num[0] = nums[i] + nums[j];
							sprintf(newexps, "(%s+%s)", exps + i * 32, exps + j * 32);
							break;
						case MIN:
							num[0] = nums[i] - nums[j];
							sprintf(newexps, "(%s-%s)", exps + i * 32, exps + j * 32);
							break;
						case MINBY:
							num[0] = nums[j] - nums[i];
							sprintf(newexps, "(%s-%s)", exps + j * 32, exps + i * 32);
							break;
						case MUL:
							num[0] = nums[i] * nums[j];
							sprintf(newexps, "(%s*%s)", exps + i * 32, exps + j * 32);
							break;
						case DIV:
							if (nums[j] == 0)continue;
							num[0] = nums[i] / nums[j];
							sprintf(newexps, "(%s/%s)", exps + i * 32, exps + j * 32);
							break;
						case DIVBY:
							if (nums[i] == 0)continue;
							num[0] = nums[j] / nums[i];
							sprintf(newexps, "(%s/%s)", exps + j * 32, exps + i * 32);
							break;
						}
						cal(newcount, num, newexps);
					}
					free(newexps);
					delete(num);
				}
			}
		}
	}

	return 0;
}

int autoanswer(float* num)
{
	int ret = 0;	
	ExpressPool = (char*)malloc(MAX_RESULT * 32);
	memset(ExpressPool, 0, MAX_RESULT * 32);
	PoolIdx = 0;
	char* exps = (char*)malloc(32 * NUMBERCOUNT);
	memset(exps, 0, 32 * NUMBERCOUNT);
	for (int i = 0; i < NUMBERCOUNT; i++)
	{
		if ((exps + i * 32) != 0)
			sprintf(exps + i * 32, "%d", (int)num[i]);
	}
	isHit = false;
	cal(NUMBERCOUNT, num, exps);
	free(exps);	
	if (!isHit)
	{
		if (showanswer)
		{
			printf("无解!\n");
		}
	}
	else
	{

		for (int i = 0; i < MAX_RESULT; i++)
		{
			char firstchar = *(ExpressPool + i * 32);
			if (firstchar != '\0')
			{
				if (showanswer)
				{
					printf("%s = %d\n", ExpressPool + i * 32, (int)RESULT);
				}
				ret++;
				for (int j = i + 1; j < MAX_RESULT; j++)
				{
					char newfirstchar = *(ExpressPool + j * 32);
					if (newfirstchar != '\0')
					{
						char* str1 = (char*)(ExpressPool + i * 32);
						char* str2 = (char*)(ExpressPool + j * 32);
						int cmpresult = strcmp(ExpressPool + i * 32, ExpressPool + j * 32);
						if (cmpresult == 0)
						{
							memset(ExpressPool + j * 32, '\0', 32);
						}
					}
				}
			}
		}
	}
	free(ExpressPool);
	return ret;
}


int main() {

	float num[NUMBERCOUNT];
	
	srand((unsigned int)(time(NULL)));
	char c;
	printf("\n\n");
	printf("**********************************************************\n");
	printf("*                                                        *\n");
	printf("*                        计算24游戏                      *\n");
	printf("*                                                        *\n");
	printf("*    随机产生4个(0-9)的数字,判断是否能通过+-*/得到24    *\n");
	printf("*                                                        *\n");
	printf("*                        茂大叔提供                      *\n");
	printf("*                                                        *\n");
	printf("**********************************************************\n\n");
	printf("[enter]=随机计算;a=用户答题;q=退出\n");
	printf("请输入命令:");
	c = getchar();
	while (c != 'q') {
		showanswer = true;
		printf("备选数字为:");
		for (int i = 0; i < NUMBERCOUNT; i++)
		{
			num[i] = (float)(rand() % 9 + 1);
			printf(" %d", (int)num[i]);
		}

		if (c == 'a')
		{
			bool correct = false;
			showanswer = false;
			char ans[32] = "null";
			int ret = autoanswer(num);
			while (!correct)
			{
				printf("\n请输入你的答案(除最后一步外,每一个步骤均须用括号包围,输入0代表无解,输入q代表放弃):\n");
				scanf("%s", ans);
				getchar();
				if (ans[0] == 'q')
				{
					free(ExpressPool);
					showanswer = true;
					printf("正确答案可以为:\n");
					autoanswer(num);
					printf("共计 %d 条:\n", ret);
					break;
				}
				else
				{

					if (!isHit && ans[0] == '0')
					{
						correct = true;
					}
					else
					{
						for (int i = 0; i < 100; i++)
						{
							char firstchar = *(ExpressPool + i * 32);
							if (firstchar != '\0')
							{
								char* str1 = (char*)(ExpressPool + i * 32);

								int cmpresult = strcmp(ExpressPool + i * 32, ans);
								if (cmpresult == 0)
								{
									correct = true;
								}
							}
						}
					}
					if (correct)
					{
						printf("\n你真棒!\n");
					}
					else
					{
						printf("\n输入错误,请重试!\n");
					}
				}
			}
		}
		if (c == '\n')
		{
			printf("\n不尝试自己做一做么?回车看答案!\n");
			getchar();
			printf("答案可以为:\n");
			int ret = autoanswer(num);
			printf("共计 %d 条:\n", ret);
			
		}
		if (c == 'm')
		{

			for (int n1 = 1; n1 < 10; n1++)
				for (int n2 = 1; n2 < 10; n2++)
					for (int n3 = 1; n3 < 10; n3++)
						for (int n4 = 1; n4 < 10; n4++)
						{
							printf("\n备选数:%d %d %d %d\n======================\n", n1, n2, n3, n4);
							num[0] = (float)n1;
							num[1] = (float)n2;
							num[2] = (float)n3;
							num[3] = (float)n4;
							int ret = autoanswer(num);
							printf("共计 %d 条:\n", ret);
						}
		}
		printf("\n[enter]=随机计算;a=用户答题;q=退出\n");
		printf("请输入命令:");

		c = getchar();
	}
	printf("再见~!");
	return 0;
}

隐藏彩蛋,输入m可以显示所有题目和答案,耗内存,慎用!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值