C++课程设计报告
- 格式:doc
- 大小:124.00 KB
- 文档页数:15
信息技术学院计算机科学与技术专业大作业报告课程名称:程序设计语言Ⅱ课程设计题目:“21点”纸牌游戏院系:信息技术学院学号:XX姓名:XXX指导教师:XXX职称:XX2011年 7月 5 日目录1.任务要求 (3)2.设计方案 (3)3.设计内容 (4)3.1.类设计图: (5)3.2 设计步骤: (7)3.3 结果: (7)3.4程序源代源 (8)4.总结 (8)5.参考文献 (8)21点纸牌游戏1.任务要求(1)“21点”是一个古老的扑克牌游戏,游戏规则是:各个参与者设法使自己的牌达到总分21而不超过这个数值。
(2)扑克牌的分值取它们的面值,A充当11分,J,Q,K人头牌都是10分。
(3)庄家对付1~7个玩家。
在一局开始时,包括庄家在内的所有参与者都有两张牌。
玩家可以看到他们的所有牌以及总分,而庄家有一张牌暂时是隐藏的。
(4)计算机作为庄家,1~7个人作为普通玩家参与游戏。
2. 设计方案3.设计内容3.1类设计图:class Rand{public:// 方法声明static void SetRandSeed(){ srand((unsigned)time(NULL)); }// 设置当前时间为随机数种子static int GetRand(int n){ return rand() % n; }// 生成到n-1之间的随机数static int GetRand(){ return rand(); } // 生成~ n-1之间的随机数};bool UserSaysYes(){char ch;//定义了一个变量bool initialResponse=true;//又定义了一个bool变量do{//if...else是用来判断输出形式的if(initialResponse)cout<<"(y,n)?";elsecout<<"用y或n回答:";//这个while和上面的do没关系,只和它下一句有关//是用来判断得到的字符是不是换行符//这个是do...while里嵌套的循环while((ch=getchar())=='\n');initialResponse=false;}while(ch!='y'&&ch!='Y'&&ch!='n'&&ch!='N');//这个while是和do在一起的//这个是另一个循环了,执行下面的if...elsewhile(getchar()!='\n');if(ch=='y'||ch=='Y')return true;else return false;}ostream& operator<<(ostream& outStream,const Card&card){//输出花色if (card.suit == CLUBS)outStream<<"梅花";else if(card.suit == DIAMONDS)outStream<<"方块";else if(card.suit ==HEARTS)outStream<<"红桃";else if(card.suit ==SPADES)outStream<<"黑桃";//输出面值if (card.rank ==ACE)outStream<<"A";else if (card.rank ==JACK)outStream<<"J";else if (card.rank ==QUEEN)outStream<<"Q";else if (card.rank ==KING)outStream<<"K";else cout <<(int)card.rank ; //(int)card.rank为分值return outStream;}class GameOf21Point{private://数据成员:Card deck[52]; //一副扑克牌int dealPos;Card hands[8][21];//hand[0]存储庄家手中的扑克牌,hand[1~7]存储各位玩家手中的扑克牌int numOfCard[8];//庄家(numOfCard[0]及玩家numOfCard[1~7])手中的扑克牌数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);//显示庄家(对应num=0)或玩家(对应num>0)的当前状态Card DealOneCard(){return deck [dealPos++];}//发一张扑克牌public://方法声明:GameOf21Point();//无参数的构造函数virtual ~GameOf21Point(){}; //析构函数void Game(); //运行游戏void Swap(Card a, Card b);};【基本要求】将纸牌面值,游戏分别定义成类Rand,GameOf21Point。
每个类中的私有成员变量需通过类成员函数获取值或设置值。
设计程序入口main()使用各类中的函数实现游戏。
设计运行游戏的代码3.2设计步骤:先设计各类的方法,最后设计main函数让其正常工作。
3.3结果:3.4程序源代码://#include "utility.h"//#include "game_of_21_point.h" //21点游戏#include <iostream>#include <stdlib.h>#include <time.h>#define LEN_OF_MAX_NAME 21 //最大姓名长度using namespace std;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{//扑克牌花色:CLUBS(梅花),DIAMONDS(方块),HEARTS(红桃)和SPADES(黑桃) CLUBS, DIAMONDS, HEARTS, SPADES}SuitType;struct Card{//扑克牌结构体RankType rank; //扑克牌面值SuitType suit; //扑克牌花色class Rand{public:// 方法声明static void SetRandSeed(){ srand((unsigned)time(NULL)); }// 设置当前时间为随机数种子static int GetRand(int n){ return rand() % n; }// 生成0 到 n-1之间的随机数static int GetRand(){ return rand(); } // 生成0 ~ n-1之间的随机数};bool UserSaysYes(){char ch;//定义了一个变量bool initialResponse=true;//又定义了一个bool变量do{//if...else是用来判断输出形式的if(initialResponse)cout<<"(y,n)?";elsecout<<"用y或n回答:";//这个while和上面的do没关系,只和它下一句有关//是用来判断得到的字符是不是换行符//这个是do...while里嵌套的循环while((ch=getchar())=='\n');initialResponse=false;}while(ch!='y'&&ch!='Y'&&ch!='n'&&ch!='N');//这个while是和do在一起的//这个是另一个循环了,执行下面的if...elsewhile(getchar()!='\n');if(ch=='y'||ch=='Y')return true;else return false;}ostream& operator<<(ostream& outStream,const Card&card)//输出花色if (card.suit == CLUBS)outStream<<"梅花";else if(card.suit == DIAMONDS)outStream<<"方块";else if(card.suit ==HEARTS)outStream<<"红桃";else if(card.suit ==SPADES)outStream<<"黑桃";//输出面值if (card.rank ==ACE)outStream<<"A";else if (card.rank ==JACK)outStream<<"J";else if (card.rank ==QUEEN)outStream<<"Q";else if (card.rank ==KING)outStream<<"K";else cout <<(int)card.rank ; //(int)card.rank为分值return outStream;}//21点游戏类GameOf21Point声明class GameOf21Point{private://数据成员:Card deck[52]; //一副扑克牌int dealPos;Card hands[8][21];//hand[0]存储庄家手中的扑克牌,hand[1~7]存储各位玩家手中的扑克牌int numOfCard[8];//庄家(numOfCard[0]及玩家numOfCard[1~7])手中的扑克牌数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);//显示庄家(对应num=0)或玩家(对应num>0)的当前状态Card DealOneCard(){return deck [dealPos++];}//发一张扑克牌public://方法声明:GameOf21Point();//无参数的构造函数virtual ~GameOf21Point(){}; //析构函数void Game(); //运行游戏void Swap(Card a, Card b);};//21点游戏类GameOf21Point的实现部分GameOf21Point::GameOf21Point() //初始化扑克牌,发牌位置,庄家与各玩家手中的扑克牌数{int curPos=0; //当前扑克牌位置for (int suitPos=0;suitPos<4;suitPos++){ //花色for(int rankPos=1;rankPos<=13;rankPos++){//面值deck[curPos].suit=(SuitType)suitPos ; //花色deck[curPos].rank=(RankType)rankPos ; //面值curPos++; //下一个位置}}cout<<"多少人加入游戏?(1~7)?:";cin>>numOfPlayer; //玩家人数while (numOfPlayer<1||numOfPlayer>7){ //限制人数在1~7之间cout<<"人数只能在1~7之间,请重新输入人数:";cin>>numOfPlayer; //玩家人数}dealPos=0; //发牌位置int i; //临时变量for (i=0;i<=numOfPlayer;i++)numOfCard[i]=0; //庄家(numOfCard[0])及玩家(numOfCard[i])手中的扑克牌数strcpy(name[0],"庄家"); //庄家for (i=0;i<=numOfPlayer;i++){ //玩家姓名cout<<"输入第"<<i<<"位玩家的姓名:";cin>>name[i];}cout<<"游戏开始"<<endl;}void GameOf21Point::Shuffle() //洗牌,将扑克牌混在一起以便产生一种随机的排列组合{Rand::SetRandSeed(); //设置当前时间为随机数种子for (int curPos=51;curPos>0;curPos--){ //产生随机的位置为curPos的扑克牌int pos=Rand::GetRand(curPos+1); //生成0~curPos之间的随机数Swap(deck[pos],deck[curPos]); //交换deck[pos]与deck[curPos] }}void GameOf21Point::Swap(Card a, Card b){Card t;t = a;a = b;b = t;}int GameOf21Point::GetTotalScore(Card hand[21],int n) //返回一手扑克牌的总分值{int pos; //临时变量int totalScore=0; //总分值for (pos=0;pos<n;pos++){ //循环求最大分值(A的分值为11)if (hand[pos].rank==ACE)totalScore+=11; //A的分值为11else if (hand[pos].rank>TEN)totalScore+=10; //J,Q,K的分值为10else totalScore+=(int)hand[pos].rank; //TWO~TEN的分值为2~10 }for (pos=0;totalScore>21&&pos<n;pos++){ //分值大于21时,将A的分值改为1if (hand[pos].rank==ACE)totalScore-=10; //A的分值由11分改为1分}return totalScore; //返回总分}void GameOf21Point::ShowStatus(int num,bool hideFirstCardAndTotalScore)//当num=0时,显示庄家当前状态,当num>0时,显示第num个玩家的当前状态,//当hideFirstCardAndTotalScore为真时,将隐藏首张扑克牌与总分,否则将显示首张扑克牌与总分{cout<<name[num]<<":"; //显示庄家或玩家姓名if (hideFirstCardAndTotalScore) cout<<"<隐藏>"; //隐藏首张扑克牌else cout<<hands[num][0]; //显示首张扑克牌for (int i=1;i<numOfCard[num];i++)cout<<hands[num][i]; //显示庄家或玩家手中的扑克牌if(!hideFirstCardAndTotalScore)cout<<"总分值"<<GetTotalScore(hands[num],numOfCard[num]); //显示庄家或玩家总分cout<<endl;if(GetTotalScore(hands[num],numOfCard[num])>21)cout<<name[num]<<"引爆!"<<endl;void GameOf21Point::Game() //运行游戏{Shuffle(); //洗牌,将扑克牌混在一起以便产生一种随机的排列int i,j; //临时变量for (i=0;i<2;i++)hands[0][numOfCard[0]++]=DealOneCard(); //为玩家发两张扑克牌ShowStatus(0,true); //显示庄家状态,隐藏首张扑克牌与总分for(i=1;i<=numOfPlayer;i++){//向各玩家发扑克牌,显示各玩家发扑克牌手中的扑克牌for(j=0;j<2;j++)hands[i][numOfCard[i]++]=DealOneCard(); //为玩家i发两张扑克牌ShowStatus(i); //显示玩家i}cout<<endl;for (i=1;i<=numOfPlayer;i++){ //依次向玩家发额外的牌cout<<name[i]<<",你想再要一张牌吗";if(UserSaysYes()){ //玩家再要一张牌hands[i][numOfCard[i]++]=DealOneCard(); //为玩家i发1张扑克牌ShowStatus(i); //显示玩家i}}ShowStatus(0); //显示庄家while (GetTotalScore(hands[0],numOfCard[0])<=16){ //庄家总分小于等于16,必须再拿牌hands[0][numOfCard[0]++]=DealOneCard(); //为庄家发1张扑克牌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(void) //主函数main(void){do{GameOf21Point objGame; //21点游戏对象objGame.Game(); //运行游戏cout<<"你想再玩一次吗";}while(1); //肯定回答循环,直到得到否定答案为止system("PAUSE"); //调用库函数 system()return 0; //返回值0,返回操作系统}4.总结:通过这次对游戏编程的实践,不仅让我更好的运用了C++的知识,更让我明白知识的力量但是所学有限,有些还是做不了,我需要继续努力。