C++ 21点纸牌游戏

发布时间: 更新时间: 总字数:1872 阅读时间:4m 作者: IP上海 分享 网址

本程序为大学时,C++课程设计报告,实现21点纸牌游戏。21点是一个古老的扑克牌游戏,游戏规则是:各个参与者设法使自己的牌达到总分21而不超过这个数值。

需求

21点是一个古老的扑克牌游戏,游戏规则是:各个参与者设法使自己的牌达到总分21而不超过这个数值。扑克牌的分值取它们的面值,A充当1分或者11分(由玩家自己选择一种分值),J、Q和K人头牌都是10分。庄家对付1~7个玩家。在一局开始时,包括庄家在内的所有参与者都有两张牌。玩家可以看到它们的所有牌以及总分,而专家有一张牌暂时是隐藏的。接下来,只要愿意,各个玩家都有机会依次再拿一张牌。如果某个玩家的总分超过了21(称为“引爆”),那么这个玩家就输了。在所有玩家都拿了额外的牌后,庄家将显示隐藏的牌。只有庄家的总分等于或小于16,那么他就必须再拿牌。如果庄家引爆了,那么还没有引爆的所有玩家都将获胜,引爆的玩家打成平局。否则,将余下的各玩家的总分与庄家的总分做比较,如果玩家的总分大于庄家的总分,则玩家获胜。如果二者的总分相同,则玩家与庄家打成平局。

代码

#include<iostream.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>

#define LEN_OF_MAX_NAME 21

typedef enum
{
	//扑克牌面值:ACE(A),TWO(2)~TEN(10),JACK(J),QUEEN(Q),KING(K)
	ACE=1, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING
}RankType;

typedef enum
{
	//扑克牌的花色:CAUBS(梅花),DIAMONDS(方块),HEARTS(红桃),SPADES(黑桃)
	CLUBS, DIAMONDS, HEARTS, SPADES
}SuitType;

struct Card
{
	RankType rank;
	SuitType suit;
};

ostream &operator<<(ostream &o,const Card &c)
{
	if(c.suit==CLUBS)
		o<<"梅花";
	else if(c.suit==DIAMONDS)
		o<<"方块";
	else if(c.suit==HEARTS)
		o<<"红桃";
	else if(c.suit==SPADES)
		o<<"KING";

	if(c.rank==ACE)
		o<<"A";
	else if(c.rank==JACK)
		o<<"J";
	else if(c.rank==QUEEN)
		o<<"Q";
	else if(c.rank==KING)
		o<<"K";
	else cout<<(int)c.rank;

	return o;
}

class GameOf21Point
{
private:
	Card d[52];
	int dealPos;
	Card hands[8][21];
	int numOfCard[8];
	char name[8][LEN_OF_MAX_NAME];
	int numOfPlayer;

	void Shuffle();

	int GetTotalScore(Card hand[21], int n);

	void ShowStatus(int num,bool hideFirstCardAndTotalScore=false);

	Card DealOneCard()
	{
		return d[dealPos++];
	}

public:
	GameOf21Point();
	virtual~GameOf21Point()
	{
	};
	void Game();
};

void GameOf21Point::Shuffle()
{
	srand(time(NULL));

	for(int i=51;i>0;i--)
	{
		int pos=rand()%(i+1);
		Card t;
		t=d[pos];
		d[pos]=d[i];
		d[i]=t;
	}
}

int GameOf21Point::GetTotalScore(Card hand[21], int n)
{
	int p;
	int totalScore=0;

	for(p=0;p<n;p++)
	{
		if(hand[p].rank==ACE)
			totalScore+=1;
		else if(hand[p].rank>TEN)
			totalScore+=10;
		else
			totalScore+=(int)hand[p].rank;
	}

	for(p=0;p<n && totalScore>21;p++)
		if(hand[p].rank==ACE)
			totalScore-=10;

		return totalScore;
}

void GameOf21Point::ShowStatus(int n,bool hideFirstCardAndTotalScore)
{
	cout<<name[n]<<":";
	if(hideFirstCardAndTotalScore)
		cout<<" <隐藏>";
	else
	{
		if(hands[n][0].suit==CLUBS)
			cout<<" 梅花";
		else if(hands[n][0].suit==DIAMONDS)
			cout<<" 方块";
		else if(hands[n][0].suit==HEARTS)
			cout<<" 红桃";
		else if(hands[n][0].suit==SPADES)
			cout<<" 黑桃";

		if(hands[n][0].rank==ACE)
			cout<<"A";
		else if(hands[n][0].rank==JACK)
			cout<<"J";
		else if(hands[n][0].rank==QUEEN)
			cout<<"Q";
		else if(hands[n][0].rank==KING)
			cout<<"K";
		else
			cout<<(int)hands[n][0].rank;
	}


	for(int i=1;i<numOfCard[n];i++)
	{
		if(hands[n][i].suit==CLUBS)
			cout<<" 梅花";
		else if(hands[n][i].suit==DIAMONDS)
			cout<<" 方块";
		else if(hands[n][i].suit==HEARTS)
			cout<<" 红桃";
		else if(hands[n][i].suit==SPADES)
			cout<<" 黑桃";

		if(hands[n][i].rank==ACE)
			cout<<"A";
		else if(hands[n][i].rank==JACK)
			cout<<"J";
		else if(hands[n][i].rank==QUEEN)
			cout<<"Q";
		else if(hands[n][0].rank==KING)
			cout<<"K";
		else
			cout<<(int)hands[n][i].rank;
	}

	if(!hideFirstCardAndTotalScore)
		cout<<" 总分数"<<GetTotalScore(hands[n],numOfCard[n]);
	cout<<endl;

	if(GetTotalScore(hands[n],numOfCard[n])>21)
		cout<<name[n]<<"引爆!"<<endl;
}

GameOf21Point::GameOf21Point()
{
	int curPos=0;
	dealPos=0;
	int i=0;

	for(int suitpos=0;suitpos<4;suitpos++)
	{
		for(int rankPos=1;rankPos<=13;rankPos++)
		{
			d[curPos].suit=(SuitType)suitpos;
			d[curPos].rank=(RankType)rankPos;
			curPos++;
		}
	}


	cout<<"多少人加入游戏?<1~7>:";
	cin>>numOfPlayer;
	while(numOfPlayer<1||numOfPlayer>7)
	{
		cout<<"玩家人数限定在1~7人,请重新输入人数<1~7>:";
		cin>>numOfPlayer;
	}

	for(i=0;i<=numOfPlayer;i++)
		numOfCard[i]=0;

	strcpy(name[0],"庄家");
	for(i=1;i<=numOfPlayer;i++)
	{
		cout<<"输入第"<<i<<"位玩家的姓名:";
		cin>>name[i];
	}

	cout<<"游戏开始"<<endl;
}

void GameOf21Point::Game()
{
	int i,j;

	Shuffle();

	for(i=1;i<=2;i++)
	{
		hands[0][numOfCard[0]]=DealOneCard();
		numOfCard[0]++;
	}

	ShowStatus(0,true);

	for(i=1;i<=numOfPlayer;i++)
		for(j=0;j<2;j++)
		{
			hands[i][numOfCard[i]]=DealOneCard();
			numOfCard[i]++;
		}

		for(i=1;i<=numOfPlayer;i++)
			ShowStatus(i);

		cout<<endl;

		for(i=1;i<=numOfPlayer;i++)
		{
			char ch;
			cout<<name[i]<<",你想有一张牌吗<y, n>?";
			cin>>ch;

			while(ch!='y'&&ch!='n')
			{
				cout<<name[i]<<",你输入错误,请重新输入<y, n>?";
				cin>>ch;
			}

			while(GetTotalScore(hands[i],numOfCard[i])<=21&&ch=='y')
			{
				hands[i][numOfCard[i]]=DealOneCard();
				numOfCard[i]++;
				ShowStatus(i);

				if(GetTotalScore(hands[i],numOfCard[i])>21)
					break;
				cout<<name[i]<<",你还想再要一张牌吗<y, n>?";
				cin>>ch;
			}
		}

		ShowStatus(0);
		while(GetTotalScore(hands[0],numOfCard[0])<=16)
		{
			hands[0][numOfCard[0]]=DealOneCard();
			numOfCard[0]++;
			ShowStatus(0);
		}
		cout<<endl;

		if(GetTotalScore(hands[0],numOfCard[0])>21)
		{
			for(i=1;i<=numOfPlayer;i++)
			{
				if(GetTotalScore(hands[i],numOfCard[i])<=21)
					cout<<name[i]<<",恭喜你,你赢了!"<<endl;
				else cout<<name[i]<<",你们打成了平局。"<<endl;
			}
		}
		else
		{
			for(i=1;i<=numOfPlayer;i++)
			{
				if(GetTotalScore(hands[i],numOfCard[i])<=21 && GetTotalScore(hands[i],numOfCard[i])>GetTotalScore(hands[0],numOfCard[0]))
					cout<<name[i]<<",恭喜你,你赢了!"<<endl;
				else if(GetTotalScore(hands[i],numOfCard[i])==GetTotalScore(hands[0],numOfCard[0]))
					cout<<name[i]<<",你们打成了平局。"<<endl;
				else
					cout<<name[i]<<",对不起,你输了。"<<endl;
			}
		}
}

int main()
{
	char ch;
	ch='y';
	while(ch=='y')
	{
		GameOf21Point game;
		game.Game();
		cout<<endl<<endl<<"您想在玩一次吗<y, n>?";
		cin>>ch;
	}

	return 0;
}

参考

  1. 源码地址
  2. https://pan.baidu.com/share/link?shareid=62566&uk=1930577918
Home Archives Categories Tags Statistics
本文总阅读量 次 本站总访问量 次 本站总访客数