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

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

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;
}

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

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

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

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,扑克牌游戏是一个经典的纸牌游戏,它需要使用一副牌(通常是52张),由两个或更多的家进行游戏。以下是一个简单的扑克牌游戏C++代码示例: ```cpp #include <iostream> #include <string> #include <vector> #include <algorithm> #include <ctime> using namespace std; // 定义牌面和花色 const string suits[] = {"Hearts", "Diamonds", "Clubs", "Spades"}; const string faces[] = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"}; class Card { public: Card(int face, int suit) : m_Face(face), m_Suit(suit) {} int getFace() const { return m_Face; } int getSuit() const { return m_Suit; } string toString() const { return faces[m_Face] + " of " + suits[m_Suit]; } private: int m_Face, m_Suit; }; class DeckOfCards { public: DeckOfCards() { for (int i = 0; i < 13; ++i) { for (int j = 0; j < 4; ++j) { m_Deck.push_back(Card(i, j)); } } } void shuffle() { random_shuffle(m_Deck.begin(), m_Deck.end()); } Card dealCard() { Card card = m_Deck.back(); m_Deck.pop_back(); return card; } private: vector<Card> m_Deck; }; int main() { srand(static_cast<unsigned int>(time(0))); DeckOfCards myDeck; myDeck.shuffle(); for (int i = 0; i < 52; ++i) { cout << myDeck.dealCard().toString() << endl; } return 0; } ``` 这个代码实现了一个简单的扑克牌游戏,包括了一个Card类表示一张扑克牌,以及一个DeckOfCards类表示一副牌。其中,Card类定义了牌面和花色,并提供了一些方法用于获取和显示这些信息。DeckOfCards类则使用了一个vector来存储52张牌,并提供了shuffle和dealCard方法来洗牌和发牌。在main函数中,我们创建了一副牌并随机洗牌,然后依次发出每张牌并打印出来。 如果您有任何其他关于扑克牌游戏代码的问题,请随时问我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值