用代码来玩三八二十四扑克牌游戏(C++)

本文介绍了如何用C++实现24点游戏的算法,通过深度优先搜索对扑克牌进行排序,并尝试所有可能的运算符组合,以找到使结果等于24的运算过程。算法包括滚雪球和合并运算两种方式,对于每种排序和运算符组合,检查计算结果是否为24并输出运算过程。当没有解时,输出noans。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.输入输出约定

输入四个字符,分别代表四个扑克牌,约定:0字符为10,JQK分别为11 12 13.

输出运算过程,如果没有无解,输出 no ans.

2.运行截图

(1)有答案的

(2)无答案的

 

3.算法思路步骤

(1)输入四个字符,例如:2 6 J 0

(2)将字符转化为整数,其中0JQK分别转化为10 11 12 13

(3)使用深度优先算法,为4张牌排序

(4)对于每种排序方式,使用不同的运算符相连接,例如2 * 6 + 11- 10

(5)对于每种排序方式的每种运算符连接,分别考察两种计算方式

(6)第一种计算方式为瀑布式,例如:(((2*6)+11)-10)

(7)第二种计算方式为合并式,例如:(2*6)+(11-10)

(8)如果答案等于24,则输出运算过程

4.完整代码

#include<iostream>
#include<stack>
using namespace std;
 
bool isSort[4]; //牌是否使用 
stack<int> mySort; //牌的次序 
stack<int> copySort; //牌的次序的复制 
int haveAns=0; //有多少个解法 
int symbol[3]; //运算符号 
int cardData[4]; //牌的数据 
int ansSum=0; //游戏答案总数 

/*
展示运算过程

type:1 滚雪球运算法,2 分别运算后再运算 
*/
void showAns(int type){
	haveAns++;
	if(type==1){
		cout<<"((( "<<cardData[0]<<" ";
		for(int i=0;i<3;i++){
			if(symbol[i]==0) cout<<"+"<<" ";
			if(symbol[i]==1) cout<<"-"<<" ";
			if(symbol[i]==2) cout<<"*"<<" ";
			if(symbol[i]==3) cout<<"/"<<" ";
			cout<<cardData[i+1]<<" ) ";
		}	
	}
	
	if(type==2){
		cout<<"( "<<cardData[0]<<" ";
		for(int i=0;i<3;i++){
			if(symbol[i]==0) cout<<"+"<<" ";
			if(symbol[i]==1) cout<<"-"<<" ";
			if(symbol[i]==2) cout<<"*"<<" ";
			if(symbol[i]==3) cout<<"/"<<" ";
			if(i==0||i==2) cout<<cardData[i+1]<<" ) ";
			if(i==1) cout<<"( "<<cardData[i+1]<<" ";
		}	
	}
	cout<<endl;
	cout<<endl;
}

/*
计算过程

x:第一个数 
t: 运算符 0+ 1- 2* 3/ 
y:第二个数 

return:答案 
*/
int calculate(int x,int t,int y){
	if(x==-1||y==-1) return -1;
	if(t==0) return x+y;
	if(t==2) return x*y;
	if(t==1){
		if(x-y<0) return -1;
		return x-y;
	} 
	if(t==3){
		if(y==0||x%y!=0) return -1;
		return x/y;
	} 
} 

/*
分支运算法

分别按照运算符算前两个数和后两个数,再将结果运算 
*/
void checkMergeOK(){
	int left,right;
	left=calculate(cardData[0],symbol[0],cardData[1]);
	right=calculate(cardData[2],symbol[2],cardData[3]);
	left=calculate(left,symbol[1],right);
	if(left==24) showAns(2);
}

/*
滚雪球运算法

以第一个数为起点,依次按对应运算符计算 
*/
void checkSnowballOK(){
	int ans=cardData[0];
	for(int i=0;i<3;i++){
		ans=calculate(ans,symbol[i],cardData[i+1]);
	}
	if(ans==24) showAns(1);
}

/*
遍历所有运算符情况 
*/
void checkOK(){
	for(int i=0;i<4*4*4;i++){
		symbol[0]=i/16;
		symbol[1]=(i/4)%4;
		symbol[2]=i%4;
	//	cout<<symbol[0]<<" "<<symbol[1]<<" "<<symbol[2]<<endl;
		copySort=mySort;
		int iIndex=0;
		while(!copySort.empty()){
			cardData[iIndex]=copySort.top();
			iIndex++;
			copySort.pop();
		}
		//cout<<cardData[0]<<" "<<cardData[1]<<" "<<cardData[2]<<" "<<cardData[3]<<endl;
		checkSnowballOK();
		checkMergeOK();
	}
	
	/*if(haveAns>0){
		ansSum++;
		cout<<cardData[0]<<" "<<cardData[1]<<" "<<cardData[2]<<" "<<cardData[3]<<endl;
		haveAns=0;
	}*/
	return;
} 

/*
四个卡牌的次序排序,使用深度优先排序 
*/
void dfsCardSort(int *yyx,int indexP){
	if(indexP==4){
		checkOK();
		return;
	}
	for(int i=0;i<4;i++){
		if(!isSort[i]){
			isSort[i]=true;
			mySort.push(yyx[i]);
		//	cout<<yyx[i]<<endl;
			dfsCardSort(yyx,indexP+1);
			mySort.pop();
			isSort[i]=false;
		}
	}
}

/*
输入四个卡牌卡牌的值,去计算是否可以正确运算 
*/
bool toAns(int q1,int q2,int q3,int q4){
	int yyx[4]={q1,q2,q3,q4};
	dfsCardSort(yyx,0);
	if(haveAns) return true;
	else return false;
}

/*
将卡牌转化为数字,其中0对应10,JQK分别对应11 12 13 
*/
bool toInt(char s1,char s2,char s3,char s4){
	int q1,q2,q3,q4;
	if(s1>'0'&&s1<='9'){
		q1=s1-'0';
	}
	else{
		if(s1=='0') q1=10;
		if(s1=='J') q1=11;
		if(s1=='Q') q1=12;
		if(s1=='K') q1=13;
	}
	
	if(s2>'0'&&s2<='9'){
		q2=s2-'0';
	}
	else{
		if(s2=='0') q2=10;
		if(s2=='J') q2=11;
		if(s2=='Q') q2=12;
		if(s2=='K') q2=13;
	}
	
	if(s3>'0'&&s3<='9'){
		q3=s3-'0';
	}
	else{
		if(s3=='0') q3=10;
		if(s3=='J') q3=11;
		if(s3=='Q') q3=12;
		if(s3=='K') q3=13;
	}
	
	if(s4>'0'&&s4<='9'){
		q4=s4-'0';
	}
	else{
		if(s4=='0') q4=10;
		if(s4=='J') q4=11;
		if(s4=='Q') q4=12;
		if(s4=='K') q4=13;
	}
//	cout<<q1<<" "<<q2<<" "<<q3<<" "<<q4;
	if(!toAns(q1,q2,q3,q4)) return false;
	else return true;
}


int main(){
	char s1,s2,s3,s4;
	while(cin>>s1>>s2>>s3>>s4){
		haveAns=0;
		cout<<endl;
		cout<<"答案为:"<<endl; 
		cout<<endl;
		if(!toInt(s1,s2,s3,s4)) cout<<"no ans"<<endl;
	}
/*	 
	for(int i=0;i<13*13*13*13;i++){
		cardData[0]=i%13+1;
		cardData[1]=(i/13)%13+1;
		cardData[2]=(i/13/13)%13+1;
		cardData[3]=(i/13/13/13)%13+1;
		checkOK();
	}
	cout<<"有多少个解?"<<ansSum;
	*/
	return 0;
}

 -------------------------------------

尊敬的开发者,您好!我是一名初入职场的小小程序员,从事软件开发工作,定期发一些文章来记录自己的学习过程,并分享问题的解决方法。

如果样例代码和文章描述有哪些问题,或者有相关领域想一起讨论,欢迎私信交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值