21点课程设计

 

//utility.h

 

 

 

#ifndef __UTILITY_H__                               // 如果没有定义__UTILITY_H__

 

#define __UTILITY_H__                              // 那么定义__UTILITY_H__

 

 

 

// 实用程序工具包

 

 

 

#ifdef _MSC_VER                                                   // 表示是Visual C++

 

#if _MSC_VER == 1200                                   // 表示Visual C++6.0

 

 

 

// 标准库头文件

 

#include <string.h>                                       // 标准串和操作

 

#include <iostream.h>                                 // 标准流操作

 

#include <limits.h>                                       // 极限

 

#include <math.h>                                           // 数据函数

 

#include <fstream.h>                                      // 文件输入输出

 

#include <ctype.h>                                 // 字符处理

 

#include <time.h>                                       // 日期和时间函数

 

#include <stdlib.h>                                 // 标准库

 

#include <stdio.h>                                        // 标准输入输出

 

#include <iomanip.h>                                      // 输入输出流格式设置

 

#include <stdarg.h>                                       // 支持变长函数参数     

 

#include <assert.h>                                               // 支持断言

 

 

 

#else                                                                              // 其它版本的Visual C++

 

 

 

// ANSI C++标准库头文件

 

#include <string>                                              // 标准串和操作

 

#include <iostream>                                              // 标准流操作

 

#include <limits>                                               // 极限

 

#include <cmath>                                             // 数据函数

 

#include <fstream>                                      // 文件输入输出

 

#include <cctype>                                             // 字符处理

 

#include <ctime>                                           // 日期和时间函数

 

#include <cstdlib>                                         // 标准库

 

#include <cstdio>                                    // 标准输入输出

 

#include <iomanip>                                // 输入输出流格式设置

 

#include <cstdarg>                                         // 支持变长函数参数     

 

#include <cassert>                                 // 支持断言

 

using namespace std;                                     // 标准库包含在命名空间std中

 

 

 

#endif                                                                           // _MSC_VER == 1200

 

#else                                                                             // 非Visual C++

 

 

 

// ANSI C++标准库头文件

 

#include <string>                                             // 标准串操作

 

#include <iostream>                                       // 标准流操作

 

#include <limits>                                              // 极限

 

#include <cmath>                                            // 数据函数

 

#include <fstream>                                // 文件输入输出

 

#include <cctype>                                            // 字符处理

 

#include <ctime>                                     // 日期和时间函数

 

#include <cstdlib>                                         // 标准库

 

#include <cstdio>                                     // 标准输入输出

 

#include <iomanip>                                      // 输入输出流格式设置       

 

#include <cstdarg>                                               // 支持变长函数参数   

 

#include <cassert>                                       // 支持断言

 

using namespace std;                                     // 标准库包含在命名空间std中

 

 

 

#endif                                                                           // _MSC_VER

 

 

 

// 实用函数

 

char GetChar(istream &inStream = cin); // 从输入流inStream中跳过空格及制表符获取一字符

 

bool UserSaysYes();                // 当用户肯定回答(yes)时, 返回true, 用户否定回答(no)时,返回false

 

// 函数模板

 

template <class ElemType >

 

void Swap(ElemType &e1, ElemType &e2);     // 交换e1, e2之值

 

template<class ElemType>

 

void Display(ElemType elem[], int n);       // 显示数组elem的各数据元素值

 

 

 

// 实用类

 

class Timer;                                    // 计时器类Timer

 

class Error;                                     // 通用异常类

 

class Rand;                                            // 随机数类Rand

 

 

 

char GetChar(istream &in)         // 从输入流in中跳过空格及制表一字符

 

{

 

         char ch;                                                    // 临时变量

 

        

 

         while ((ch = in.peek()) != EOF   // 文件结束符(peek()函数从输入流中接受1

 

                   // 字符,流的当前位置不变)

 

                   && ((ch = in.get()) == ' '   // 空格(get()函数从输入流中接受1字符,流

 

                   // 的当前位置向后移1个位置)

 

                   || ch == '\t'));                         // 制表符

 

         return ch;                                                        // 返回字符

 

}

 

bool UserSaysYes() // 当用户肯定回答(yes)时, 返回true, 用户否定回答(no)时,返回false

 

{

 

         char ch;                                                  // 用户回答字符

 

         bool initialResponse = true; // 初始回答

 

        

 

         do

 

         {                                  // 循环直到用户输入恰当的回答为止

 

                   if (initialResponse) cout << "(y, n)?"; // 初始回答

 

                   else cout << "用y或n回答:";                           // 非初始回答

 

                   while ((ch = GetChar()) == '\n');       // 跳过空格,制表符及换行符获取一字符

 

                   initialResponse = false;                                    // 非初始回答

 

         } while (ch != 'y' && ch != 'Y' && ch != 'n' && ch != 'N');

 

         while (GetChar() != '\n');                                // 跳过当前行后面的字符

 

        

 

         if (ch == 'y' || ch == 'Y') return true;         // 肯定回答返回true

 

         else return false;                                                             // 否定回答返回false

 

}

 

template <class ElemType >

 

void Swap(ElemType &e1, ElemType &e2)             // 交换e1, e2之值

 

{

 

         ElemType temp;                                                             // 临时变量

 

         temp = e1; e1 = e2; e2 = temp;                 // 循环赋值实现交换e1, e2

 

}

 

template<class ElemType>

 

void Show(ElemType elem[], int n)            // 显示数组elem的各数据元素值

 

{

 

         for (int i = 0; i < n; i++)

 

         {        // 显示数组elem

 

                   cout << elem[i] << "  ";              // 显示elem[i]

 

         }

 

         cout << endl;                                                    // 换行

 

}

 

// 计时器类Timer

 

class Timer

 

{

 

private:

 

         // 数据成员

 

         clock_t startTime;

 

public:

 

         //  方法声明

 

         Timer(){ startTime = clock(); }                    // 构造函数, 由当前时间作为开始时间构造对象

 

         double ElapsedTime() const                                // 返回已过的时间

 

         {

 

                   clock_t endTime = clock();                                    // 结束时间

 

                   return (double)(endTime - startTime) / (double)CLK_TCK;// 计算已过时间

 

                  

 

         }

 

         void Reset(){ startTime = clock(); }     // 重置开始时间

 

};

 

 

 

#define MAX_ERROR_MESSAGE_LEN 100

 

class Error// 通用异常类Error

 

{

 

private:

 

         // 数据成员

 

         char message[MAX_ERROR_MESSAGE_LEN];        // 异常信息

 

public:

 

         //  方法声明

 

         Error(char mes[] = "一般性异常!"){ strcpy(message, mes); }       

 

         // 构造函数

 

         void Show() const{ cout << message << endl; }                 // 显示异常信息

 

}; 

 

 

 

class Rand// 随机数类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之间的随机数

 

};

 

#endif

 

 

 

 

 

//card.h

 

 

 

#ifndef __CARD_H__

 

#define __CARD_H__

 

 

 

#include<iostream.h>

 

typedef enum//扑克牌面值

 

{

 

         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;//扑克牌花色

 

};

 

 

 

ostream& operator<<(ostream&output,Card&card)

 

{

 

         //输出花色

 

         if(card.suit==CLUBS)

 

                   output<<"梅花";

 

         else if(card.suit==DIAMONDS)

 

                   output<<"方块";

 

         else if(card.suit==HEARTS)

 

                   output<<"红桃";

 

         else if(card.suit==SPADES)

 

                   output<<"黑桃";

 

 

 

         //输出面值

 

         if(card.rank==ACE)

 

                   output<<"A";

 

         else if(card.rank==JACK)

 

                   output<<"J";

 

         else if(card.rank==QUEEN)

 

                   output<<"Q";

 

         else if(card.rank==KING)

 

                   output<<"k";

 

         else

 

                   output<<int(card.rank);

 

         output<<" ";

 

 

 

         return output;

 

}

 

        

 

#endif

 

 

 

 

 

//game_of_21_point.h

 

 

 

#include"card.h"//扑克牌

 

#include"utility.h"

 

#ifndef __GAME_OF_21_POINT_H__

 

#define __GAME_OF_21_POINT_H__

 

 

 

 

 

#define LEN_OF_MAX_NAME 21

 

 

 

class GameOf21Point//21点游戏类

 

{

 

private:

 

         Card deck[52];//一副扑克牌

 

         int dealPos;//发牌位置

 

         Card hands[8][21];//hands[0]存储庄家手中的牌,hands[1-7]玩家

 

         int numOfCard[8];//每位手中的牌数

 

         char name[8][LEN_OF_MAX_NAME];//庄家与玩家姓名

 

         int numOfPlayer;//玩家人数

 

        

 

        

 

 

 

public:

 

         GameOf21Point();

 

         ~GameOf21Point(){}

 

         void Shuffle();//洗牌,将扑克牌混在一起以便产生一种随机的排列

 

         int GetTotalScore(Card hand[21],int n);//还回一手牌的总分值

 

         void ShowStatus(int num,bool hideFirstCardAndTotalScore=false);//显示庄家与玩家的当前状态

 

         Card DealOneCard(){return deck[dealPos++];}//发一张扑克牌

 

         void Game();//运行游戏

 

};

 

 

 

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)

 

         {

 

                   cout<<"人数只能在1-7人之间,请重新输入人数:";

 

                   cin>>numOfPlayer;

 

         }

 

         dealPos=0;//发牌位置

 

         int i;

 

         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::Shuffle()//洗牌,将扑克牌混在一起以便产生一种随机的排列

 

{

 

         Rand::SetRandSeed();//设置当前时间为随机数种子

 

         for(int curPos=51;curPos>0;curPos--)

 

         {

 

                   int pos=Rand::GetRand(curPos+1);//0~curpos之间的随机数

 

                   Swap(deck[pos],deck[curPos]);//交换两张牌

 

         }

 

}

 

 

 

int GameOf21Point::GetTotalScore(Card hands[21],int n)

 

{

 

         int pos;

 

         int totalScore=0;

 

         for(pos=0;pos<n;pos++)

 

         {

 

                   if(hands[pos].rank==ACE)

 

                            totalScore+=11;

 

                   else if(hands[pos].rank>TEN)

 

                            totalScore+=10;

 

                   else

 

                            totalScore+=int(hands[pos].rank);

 

         }

 

 

 

         for(pos=0;totalScore>21&&pos<n;pos++)

 

         {

 

                   if(hands[pos].rank==ACE)//A的分值由11改为1分

 

                            totalScore-=10;

 

         }

 

         return totalScore;

 

}

 

 

 

void GameOf21Point::ShowStatus(int num,bool 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();

 

                   ShowStatus(i);

 

         }

 

         cout<<endl;

 

 

 

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

 

         {

 

                   cout<<name[i]<<",你想再要一张牌吗";

 

                   if(UserSaysYes())

 

                   {

 

                            hands[i][numOfCard[i]++]=DealOneCard();

 

                            ShowStatus(i);//不隐藏第1张牌

 

                   }

 

         }

 

 

 

         ShowStatus(0);

 

         while(GetTotalScore(hands[0],numOfCard[0])<=16)

 

         {

 

                   hands[0][numOfCard[0]++]=DealOneCard();

 

                   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;

                            }

                   }

         }

}

#endif

//main.cpp

#include"game_of_21_point.h"

void main()

{

         system("color 4b");

         do

         {

                   GameOf21Point objGame;

                   objGame.Game();

                   cout<<"你想在玩一次吗";

         }while(UserSaysYes());

         system("pause");

 

}

 

 

 

posted @ 2012-10-07 22:48  ♂咱說 ろ算  阅读(297)  评论(0编辑  收藏  举报