当前位置: 首页 > news >正文

武汉微信网站制作网站制作大概多少钱

武汉微信网站制作,网站制作大概多少钱,网站建设软件,msf wordpress🌟 嗨,我是LucianaiB! 🌍 总有人间一两风,填我十万八千梦。 🚀 路漫漫其修远兮,吾将上下而求索。 ​ C语言之斗地主游戏 目录 程序概述程序设计 Card类CardGroup类Player类LastCards类Land…


🌟 嗨,我是LucianaiB!

🌍 总有人间一两风,填我十万八千梦。

🚀 路漫漫其修远兮,吾将上下而求索。


C语言之斗地主游戏

目录

  1. 程序概述
  2. 程序设计
    1. Card类
    2. CardGroup类
    3. Player类
    4. LastCards类
    5. Landlords类
  3. 游戏流程
  4. 特点与功能
    1. 牌型判断
    2. AI提示
    3. 交互性
    4. 随机性
  5. 测试与运行
  6. 总体评价
  7. 附录代码

本文介绍了一个基于C++实现的简单斗地主游戏程序。该程序模拟了斗地主的基本规则和流程,包括发牌、抢地主、出牌以及胜负判定等功能。程序的核心由多个类组成,包括Card(表示单张牌)、CardGroup(表示一组牌)、Player(表示玩家)、LastCards(用于记录上家出的牌)和Landlords(用于管理整个游戏流程)。

程序设计

程序通过Card类定义了牌的基本属性,如牌面值、花色和显示方法。CardGroup类用于管理一组牌,并提供牌型判断和大小比较的功能。Player类则管理玩家手中的牌,并提供出牌和提示功能。LastCards类用于记录上家出的牌,并提供查找可打得过的牌的功能。Landlords类作为游戏的核心,负责初始化游戏、发牌、抢地主、轮流出牌以及判断游戏结束等逻辑。

游戏流程

游戏开始时,程序通过洗牌和分牌将54张牌随机分配给三个玩家,并通过抢地主环节确定地主玩家。地主玩家获得额外的三张底牌后,游戏正式开始。玩家按顺序出牌,每次出牌需要比上家的牌大,或者选择不出。当某个玩家手中的牌全部出完时,游戏结束,程序会判断地主是否获胜。

特点与功能
  1. 牌型判断:程序能够准确判断牌型,如单牌、对子、三带一、炸弹等,并根据牌型和牌的大小进行比较。
  2. AI提示:非地主玩家在出牌时,程序会自动提示可打得过的牌,提高了游戏的流畅性。
  3. 交互性:程序通过控制台输入输出与用户交互,用户可以选择是否抢地主、出牌以及是否继续游戏。
  4. 随机性:通过随机洗牌和抢地主环节,增加了游戏的趣味性和不确定性。
测试与运行

程序在测试中表现出了良好的稳定性和正确性。玩家可以自由选择出牌策略,程序会根据规则判断出牌是否合法,并在游戏结束后输出胜负结果。用户可以通过简单的命令行交互体验完整的斗地主游戏流程。
在这里插入图片描述

总体评价

本文介绍了一个基于C++实现的斗地主游戏程序,模拟了斗地主的基本规则和流程,包括发牌、抢地主、出牌和胜负判定等功能。程序的核心由多个类组成,如Card、CardGroup、Player、LastCards和Landlords,通过面向对象编程的方式实现了游戏的完整逻辑。

在程序设计中,Card类用于定义单张牌的基本属性,如牌面值、花色和显示方法。CardGroup类管理一组牌,并提供牌型判断和大小比较的功能。Player类管理玩家手中的牌,并提供出牌和提示功能。LastCards类用于记录上家出的牌,并提供查找可打得过的牌的功能。Landlords类作为游戏的核心,负责初始化游戏、发牌、抢地主、轮流出牌以及判断游戏结束等逻辑。

游戏流程从洗牌和分牌开始,通过抢地主环节确定地主玩家。地主获得额外三张底牌后,游戏正式开始。玩家按顺序出牌,每次出牌需要比上家的牌大,或者选择不出。当某个玩家手中的牌全部出完时,游戏结束,程序会判断地主是否获胜。
该程序具有以下特点:

牌型判断:能够准确判断牌型,如单牌、对子、三带一、炸弹等,并根据牌型和牌的大小进行比较。

AI提示:非地主玩家在出牌时,程序会自动提示可打得过的牌,提高了游戏的流畅性。

交互性:通过控制台输入输出与用户交互,用户可以选择是否抢地主、出牌以及是否继续游戏。

随机性:通过随机洗牌和抢地主环节,增加了游戏的趣味性和不确定性。

在测试中,程序表现出良好的稳定性和正确性,用户可以通过简单的命令行交互体验完整的斗地主游戏流程。该程序不仅实现了斗地主的基本规则,还通过类的设计和封装展示了面向对象编程的思想。代码结构清晰,易于理解和扩展,适合用于学习和研究C++编程以及游戏开发。

附录代码:
#include <iostream>
#include<vector>
#include<assert.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<time.h>using namespace std;#define PLAYERCOUNT 3
#define CARDSCOUNT 54
#define CURRENTPLAYER 0
#define VALUECOUNT 17
#define ERROR -1
using namespace std;
int scnt=0;
const char toFigure[]="34567890JQKA 2YZ";enum COLOR{  //花色显示ASCII: 3~6
eHEART=3,//红桃
eDIAMOND=4,//方片
eCLUB=5,   //草花
eSPADE=6   //黑桃
};class Card;
class CardsType;
class CardGroup;
class Player;
class Landlords;
class LastCards;
bool makeChoice(string tip);
bool cmp(Card* a,Card* b);
class Card{
public:
char figure;
COLOR color;
int value;
Card(char _figure,COLOR _color){figure=_figure;color=_color;value=calValue();
}
int calValue(){for(int i=0;toFigure[i];i++){if(toFigure[i]==figure){return i;}}return ERROR;
}void print() {assert(value != ERROR);switch (color) {case eHEART:cout << "♥"; // 红桃break;case eDIAMOND:cout << "♦"; // 方片break;case eCLUB:cout << "♣"; // 草花break;case eSPADE:cout << "♠"; // 黑桃break;default:cout << "?"; // 未知花色break;}cout << figure << ' ';}
};
class CardsType{
public:
//为了规范查找对应牌的方法
//统一为3个参数cnt1、isContinuous、cnt2
int typeId;
string typeStr;
int cnt1,cnt2;
bool isContinuous;
CardsType(){typeId=ERROR;
}
bool operator ==(const CardsType& other)const{return this->typeId==other.typeId;
}
void init(char* _typeStr,int _typeId,int _cnt1,bool _isContinuous,int _cnt2){cnt1=_cnt1;isContinuous=_isContinuous;cnt2=_cnt2;typeStr=_typeStr;typeId=_typeId;
}
};
class CardGroup{
public:
vector<Card*> cards;
CardsType type;
void calType(){int i,n=cards.size();//init(typeStr,typeId,cnt1,isContinuous,cnt2)if(n==0){type.init("不出",14,0,0,0);return;}if(n==2&&cards[0]->value==15&&cards[1]->value==14){type.init("王炸",0,0,0,0);return;}//统计同点数牌有多少张int cntFlag[VALUECOUNT]={0};for(i=0;i<n;i++){cntFlag[cards[i]->value]++;}//统计点数最多和最少的牌int maxCnt=0,minCnt=4;for(i=0;i<VALUECOUNT;i++){if(maxCnt<cntFlag[i]){maxCnt=cntFlag[i];}if(cntFlag[i]&&minCnt>cntFlag[i]){minCnt=cntFlag[i];}}if(n==4&&maxCnt==4){type.init("炸弹",1,4,0,0);return;}if(n==1){type.init("单牌",2,1,0,0);return;}if(n==2&&maxCnt==2){type.init("对子",3,2,0,0);return;}if(n==3&&maxCnt==3){type.init("三张 ",4,3,0,0);return;}if(n==4&&maxCnt==3){type.init("三带一",5,3,0,1);return;}if(n==5&&maxCnt==3&&minCnt==2){type.init("三带一对",6,3,0,2);return;}if(n==6&&maxCnt==4){type.init("四带二",7,4,0,1);return;}if(n==8&&maxCnt==4&&minCnt==2){type.init("四带二",8,4,0,2);return;}if(n>=5&&maxCnt==1&&cards[0]->value==cards[n-1]->value+n-1){type.init("顺子",9,1,1,0);return;}if(n>=6&&maxCnt==2&&minCnt==2&&cards[0]->value==cards[n-1]->value+n/2-1){type.init("连对",10,2,1,0);return;}int fjCnt;//统计连续且大于3三张的牌for(i=0;i<VALUECOUNT &&cntFlag[i]<3;i++);for(fjCnt=0;i<VALUECOUNT &&cntFlag[i]>=3;i++,fjCnt++);if(fjCnt>1){if(n==fjCnt*3)type.init("飞机",11,3,1,0);else if(n==fjCnt*4)type.init("飞机",12,3,1,1);else if(n==fjCnt*5&&minCnt==2)type.init("飞机",13,3,1,2);}
}
void init(string inputStr, vector<Card*> &cardsHolded){this->cards.clear();//不出if(inputStr=="N"){this->calType();return;}int i,j;//输入合法性判断for(i=0;i<inputStr.size();i++){bool find=false;for(j=0;toFigure[j];j++){if(inputStr[i]==toFigure[j]){find=true;break;}}if(find==false){//输入字符不在toFigure中return;}}//查找手中有没有这些牌int visitFlag[20]={0};for(i=0;i<inputStr.size();i++){Card *find=NULL;for(j=0;j<cardsHolded.size();j++){if(!visitFlag[j]&&cardsHolded[j]->figure==inputStr[i]){visitFlag[j]=1;find=cardsHolded[j];break;}}if(find){this->cards.push_back(find);}else{cout<<inputStr[i];cout<<"没有找到\t";this->cards.clear();return;}}//end for(i=0;i<inputStr.size();i++)this->arrange();
}
void init(vector<Card*> newCards){this->cards=newCards;this->arrange();
}
bool isCanBeat(CardGroup &cardGroup){if(cardGroup.type.typeStr=="王炸"){return false;}else if(this->type.typeStr=="王炸"){return true;}else if(cardGroup.type==this->type &&this->type.typeStr=="炸弹"){return value()>cardGroup.value();}else if(cardGroup.type.typeStr=="炸弹"){return false;}else if(this->type.typeStr=="炸弹"){return true;}else if(cardGroup.type==this->type &&this->cards.size()==cardGroup.cards.size()){return this->value()>cardGroup.value();}else{return false;}
}
int value(){//计算牌组权值int i;if(type.typeStr=="三带一"||type.typeStr=="三带一对"||type.typeStr=="飞机"){for(i=2;i<cards.size();i++){if(cards[i]->value==cards[i-2]->value){return cards[i]->value;}}}if(type.typeStr=="四带二"){for(i=3;i<cards.size();i++){if(cards[i]->value==cards[i-3]->value){return cards[i]->value;}}}return cards[0]->value;
}
void arrange(){//整理:排序、计算类型// sort(this->cards.begin(),this->cards.end(),cmp);this->calType();
}
};
class LastCards{
static LastCards *lastCards;
public:
Player *player;
CardGroup cardGroup;
static LastCards* inst(){//单例模式if(lastCards==NULL){lastCards=new LastCards();}return lastCards;
}
vector<Card*> findCanBeatFrom(vector<Card*> &cardsHolded){//查找能打得过的牌int i,j,k,n=cardsHolded.size(),m=cardGroup.cards.size();string typeStr=cardGroup.type.typeStr;vector<Card*> ret;if(typeStr=="王炸"||n<m){//打不过,返回空数组return ret;}int value=cardGroup.value();//统计各点牌出现的次数int cntFlag[VALUECOUNT]={0};for(i=0;i<n;i++){cntFlag[cardsHolded[i]->value]++;}int continuousCount=1;if(cardGroup.type.isContinuous){continuousCount=m/(cardGroup.type.cnt1+cardGroup.type.cnt2);}bool findFirstFigure;//cout<<"continuousCount="<<continuousCount<<endl;for(i=value+1;i<VALUECOUNT;i++){findFirstFigure=true;for(j=0;j<continuousCount;j++){if(cntFlag[i-j]<cardGroup.type.cnt1){findFirstFigure=false;break;}}if(findFirstFigure){ret.clear();int firstFigure=i;//cout<<"查找"<<cardGroup.type.cnt1<<"个"<<firstFigure+3<<endl;for(k=0,j=0;k<cardsHolded.size() &&j<continuousCount;k++){if(cardsHolded[k]->value==firstFigure-j){for(int kk=0;j>=0&&kk<cardGroup.type.cnt1;kk++){ret.push_back(cardsHolded[k+kk]);}j++;}}if(cardGroup.type.cnt2>0){int SecondFigures[5];int SecondCount=continuousCount;if(cardGroup.type.typeStr=="四带二")SecondCount=2;bool findSecondFigure=true;for(j=0,k=-1;j<SecondCount &&findSecondFigure;j++){findSecondFigure=false;for(k++;k<VALUECOUNT;k++){SecondFigures[j]=k;if(cntFlag[k]>=cardGroup.type.cnt2 &&cntFlag[k]<cardGroup.type.cnt1){findSecondFigure=true;break;}}}if(findSecondFigure){//cout<<"查找SecondFigure "<<cardGroup.type.cnt2<<"个"<<SecondFigures[0]+3<<endl;//cout<<"SecondCount= "<<SecondCount<<endl;//for(i=0;i<SecondCount;i++)cout<<"SecondFigures["<<i<<"]="<<SecondFigures[i]<<endl;for(i=0;i<SecondCount;i++){for(j=0;j<cardsHolded.size();){if(cardsHolded[j]->value==SecondFigures[i]){for(k=0;k<cardGroup.type.cnt2;k++){//cout<<"添加"<<cardsHolded[j]->value+3<<endl;ret.push_back(cardsHolded[j+k]);}do{j++;}while(j<cardsHolded.size()&&cardsHolded[j]->value==SecondFigures[i]);}else{j++;}}}return ret;}//if(findSecondFigure)}//end if(cardGroup.type.cnt2>0)else{return ret;}}//end if(findFirstFigure)}//end for(i=value+1;i<VALUECOUNT;i++)ret.clear();//没牌打得过时查找有没有炸弹if(typeStr!="炸弹"){for(i=cardsHolded.size()-1;i>=3;i--){if(cardsHolded[i]->value==cardsHolded[i-3]->value){for(j=0;j<4;j++){ret.push_back(cardsHolded[i-j]);}break;}}}return ret;
}//end vector<Card*> findCanBeatFrom()
};
LastCards* LastCards::lastCards = NULL;
class Player{
public:
string name;
vector<Card*> cards;
void arrange(){sort(cards.begin(),cards.end(),cmp);
}
void print(){cout<<this->name<<":\t";for(int i=0;i<cards.size();i++){cards[i]->print();}cout<<"["<<cards.size()<<"]\n";
}
vector<Card*> tip(){//提示功能,使自己最小一张连最长CardGroup ret;string temp;int j,k,m=cards.size();for(j=0;j<m;j++){temp="";for(k=j;k<m;k++){temp+=cards[k]->figure;}ret.init(temp,cards);if(ret.type.typeId!=ERROR){return ret.cards;}}ret.cards.clear();return ret.cards;
}
void chupai(CardGroup &cardGroup){//出牌cout<<this->name<<":\t";cout<<cardGroup.type.typeStr<<' ';for(int i=0;i<cardGroup.cards.size();i++){cardGroup.cards[i]->print();this->cards.erase(find(this->cards.begin(),this->cards.end(),cardGroup.cards[i]));}cout<<"\t["<<this->cards.size()<<"]\n";if(cardGroup.type.typeStr!="不出"){//记录到 LastCards 中LastCards::inst()->player=this;LastCards::inst()->cardGroup.init(cardGroup.cards);}
}
};
class Landlords{
Player *player[PLAYERCOUNT];
bool finished,youWin,landlordWin;
int landlordIndex;
Card *cards[CARDSCOUNT];
public:
Landlords(){int i=0,j=0,k=0;for(i=0;i<PLAYERCOUNT;i++){this->player[i]=new Player();}//54张牌初始化for(k=i=0;i<14;i++){if(toFigure[i]==' '){continue;}for(COLOR color=eHEART;color<=eSPADE;color=(COLOR)(color+1)){this->cards[k++]=new Card(toFigure[i],color);}}this->cards[k++]=new Card('Y',eSPADE);this->cards[k]=new Card('Z',eHEART);
}
~Landlords(){for(int i=0;i<PLAYERCOUNT;i++){delete this->player[i];}for(int i1=0;i1<CARDSCOUNT;i1++){delete this->cards[i1];}
}
void init(){player[CURRENTPLAYER]->name="Bice";player[1]->name="玩家2";player[2]->name="玩家3";finished=false;youWin=false;landlordWin=false;//抢地主landlordIndex=ERROR;while(landlordIndex==ERROR){srand((int)time(0));shuffle();landlordIndex=chooseLandlord();}cout<<player[landlordIndex]->name<<"\t成为地主\n\n";this->add3Cards();LastCards::inst()->player=player[landlordIndex];
}
void startGame(){string inputSrt;CardGroup inputCards;for(int iTurns=landlordIndex;!finished;iTurns++){if(iTurns>=PLAYERCOUNT){iTurns=0;}if(iTurns==CURRENTPLAYER){cout<<endl;player[iTurns]->print();cout<<"输入提示:Z=大王 Y=小王 0=10 N=不要 输入可无序 例如:JKQ0A9\n请出牌:\t";do{cin>>inputSrt;inputCards.init(inputSrt,player[iTurns]->cards);}while(check(&inputCards)==false);}else{if(player[iTurns]==LastCards::inst()->player){//若是上次出牌的是自己,启用提示功能inputCards.init(player[iTurns]->tip());}else{//查找能打得过上家的牌inputCards.init(LastCards::inst()->findCanBeatFrom(player[iTurns]->cards));}}player[iTurns]->chupai(inputCards);//出牌if(player[iTurns]->cards.size()==0){//玩家手中没牌了,游戏结束finished=true;landlordWin=iTurns==landlordIndex;if(landlordWin){youWin=landlordIndex==CURRENTPLAYER;}else{youWin=landlordIndex!=CURRENTPLAYER;}}}cout<<"\n_________________________ "<<(youWin?"You Win!":"You Lose!")<<" _________________________\n\n";
}
void add3Cards(){cout<<"地主3张牌:\t";for(int i=PLAYERCOUNT*17;i<CARDSCOUNT;i++){this->cards[i]->print();player[landlordIndex]->cards.push_back(cards[i]);}cout<<endl;player[landlordIndex]->arrange();
}
int chooseLandlord(){cout<<"\n_________________________ 抢地主 _________________________\n\n";int first=-1,last,cnt=0,i,j=rand()%PLAYERCOUNT;bool decision;for(i=0;i<PLAYERCOUNT;i++,j==2?j=0:j++){if(j==CURRENTPLAYER){decision=makeChoice("是否抢地主?(Y=抢/N=不抢):");}else{decision=rand()%2;}if(decision){cnt++;last=j;if(first==-1){first=j;}cout<<this->player[j]->name<<"\t抢地主\n";}else{cout<<this->player[j]->name<<"\t没有抢\n";}}if(cnt==0){cout<<"没人抢,重新发牌\n";return ERROR;}if(cnt==1){//第一轮只有一人抢地主return first;}else{//最后一次争抢if(first==CURRENTPLAYER){decision=makeChoice("是否抢地主?(Y=抢/N=不抢):");}else{decision=rand()%2;}if(decision){cout<<this->player[first]->name<<"\t抢地主\n";return first;}else{cout<<this->player[first]->name<<"\t没有抢\n";return last;}}
}
void shuffle(){int i,j,k;//洗牌for(i=0;i<CARDSCOUNT;i++){swap(this->cards[i],this->cards[rand()%CARDSCOUNT]);}//分牌for(k=i=0;i<PLAYERCOUNT;i++){this->player[i]->cards.clear();for(j=0;j<17;j++){this->player[i]->cards.push_back(this->cards[k++]);}this->player[i]->arrange();//整理this->player[i]->print();}
}
bool check(CardGroup *cardGroup){if(cardGroup->type.typeId==ERROR){cout<<"出牌错误,重新输入\n";return false;}else if(cardGroup->type.typeStr=="不出"){return true;}else if(LastCards::inst()->player!=player[CURRENTPLAYER]&&!cardGroup->isCanBeat(LastCards::inst()->cardGroup)){cout<<"打不过,重新输入\n";return false;}else{return true;}
}
};
int main(){
Landlords *landlords=new Landlords();
do{landlords->init();//发牌、抢地主landlords->startGame();//游戏开始
}while(makeChoice("\n是否继续游戏?(Y=继续/N=结束): "));
delete landlords;
return 0;
}
bool makeChoice(string tip){
cout<<tip;
string input;
cin>>input;
return input=="Y"||input=="y";
}
bool cmp(Card* a,Card* b){
if(a->value==b->value){return a->color>b->color;
}else{return a->value>b->value;
}
}

嗨,我是[LucianaiB](https://lucianaib.blog.csdn.net/ “LucianaiB”)。如果你觉得我的分享有价值,不妨通过以下方式表达你的支持:👍 点赞来表达你的喜爱,📁 关注以获取我的最新消息,💬 评论与我交流你的见解。我会继续努力,为你带来更多精彩和实用的内容。

点击这里👉[LucianaiB](https://lucianaib.blog.csdn.net/ “LucianaiB”) ,获取最新动态,⚡️ 让信息传递更加迅速。

http://www.hkea.cn/news/566559/

相关文章:

  • 网站尾部分页数字怎么做推广app大全
  • 建筑设计软件有哪些优化网站建设
  • 网站开发 word文件预览医疗器械龙头股
  • 电子商务网站建设花费南宁百度seo排名价格
  • 做公司网站要注意哪些问题真正免费建站网站
  • 在线服务器代理杭州seo网络公司
  • wordpress邮件订阅seo技术外包
  • 深圳营销网站建站公司搜索引擎关键词的工具
  • 做网站如何网站考虑优化游戏推广员是诈骗吗
  • 公众号做视频网站吗关键词排名怎么做上首页
  • 重庆做网站价格优化软件下载
  • 如何做网站镜像今日最火的新闻
  • 水果网站开发所需的成本市场营销实际案例
  • 无锡市新吴区住房和建设交通局网站西安百度关键词包年
  • 网站平台方案设计seo上首页
  • 郑州做网站的联系方式搜狗友链交换
  • 一般建设一个网站多少钱怎么接广告赚钱
  • 计算机专业网站开发方向销售推广方案
  • 上海网站建设公司排名西安百度公司
  • 中国网网址是多少网站推广优化教程
  • 关于加强机关网站建设运营培训
  • dw做的网站怎么让别人看到如何建立一个网站
  • 保险网站建设优缺点seo代码优化步骤
  • 如何快速建网站百度电脑版入口
  • 山东省建设工程信息网站最近最新的新闻
  • 免费网站建设方案锦绣大地seo官网
  • 电子商务的网站建设牛排seo系统
  • 资源收费网站怎么做网站快速优化排名官网
  • 招标网哪个网站信息可靠百度站长工具网站
  • 郑州七七网站建设互联网推广公司