1期末作业:21点纸牌网络游戏开发课程名称:网络游戏开发学院:信息工程与自动化学院专业:计算机科学与技术班级:2012级2班学生姓名:邹华宇学号:201210405204任课教师:钱谦日期:2015年12月28日1摘要21点,又名黑杰克(BlackJack),最受欢迎的扑克牌游戏,起源于法国,现已流传到世界各地。现在在世界各地的赌场中都可以看到21点,随着互联网的发展,二十一点开始走向网络时代。该游戏由2到6个人玩,使用除大小王之外的52张牌,游戏者的目标是使手中的牌的点数之和不超过21点且尽量大。有着悠久的历史。21点游戏本为赌博游戏,并不值得推荐,但其游戏性和娱乐性却很强,而且作为一款数字牌类游戏能一定程度上锻炼逻辑思维和运算能力,本着这种想法,开发者想把这款传统的赌博游戏制作成适合各类人群休闲娱乐的小游戏,同时通过实践更加掌握网络游戏设计的开发过程。本文通过C++高级语言进行编程,设计了简单明了的操作界面。简单的界面能给用户更好的操作体验,更直接而充分的掌握本程序的一些应用和功能。通过直观的方式,最终实现C++设计的应用程序21点纸牌游戏。关键词:21点纸牌游戏;网络游戏设计;C++2目录摘要..............................................................1绪论..............................................................3第1章系统设计.....................................................41.1课程设计描述.................................................41.2程序的网络实现...............................................41.3数据类型设计.................................................41.4游戏引擎类设计...............................................51.5程序功能结构图...............................................41.6流程图.......................................................5第2章详细设计....................................................112.1游戏引擎....................................................112.2“21点”程序................................................162.3套接字的实现—服务器端......................................242.4套接字的实现—客服端........................................26第3章测试运行....................................................28总结体会...........................................................31参考文献...........................................................323绪论21点有着悠久的历史。1700年左右法国赌场就有这种21点的纸牌游戏。1931年,当美国内华达州宣布赌博为合法活动时,21点游戏第一次公开出现在内华达州的赌场俱乐部。15年内,它取代掷骰子游戏,而一举成为非常流行的赌场庄家参与的赌博游戏。出现在亚洲是1957年在香港第一次出现,而后迅速的发展起来,五年不到的时间发展的与牌九,麻将一同成为中国人最喜欢的三大游戏。拥有最高点数的玩家获胜,其点数必须等于或低于21点;超过21点的玩家称为爆牌。2点至10点的牌以牌面的点数计算,J、Q、K每张为10点。A可记为1点或为11点,若玩家会因A而爆牌则A可算为1点。设计一个显示层和游戏引擎层分离的21点扑克牌程序。网络部分采用基于消息的异步流式套接字实现,同一个客户端既可以作为Server等待其他客户端的连接,也可以作为Client主动连接到其他客户端。建立连接之后,游戏能够由任意一方开始,开始的一方负责洗牌并给双方玩家发一张牌,然后发送扑克牌数组信息到对方进行数据同步处理。然后双方玩家轮流选择要牌还是不要牌,选择之后需要发送行动信息到对方进行数据同步处理,一旦选择不要牌则需要等待对方玩家进行多次行动直到对方玩家爆牌或者不要牌,双方都力争使自己接近21点且不“爆牌”,即“不超过21点”。4第1章系统设计本程序采用C++语言进行程序设计,设计之前先确定总体设计思路,通过文件处理的方式,然后根据程序的功能和需求画出系统流程图。1.1课程设计描述本次课程设计是模拟古老的21点扑克牌游戏,实现一对一的人机大战。要求游戏过程中任意一方牌的点数之和超过21点,则自动出局;在不超过21点的情况下,玩家下注由电脑随机发牌与庄家比累积牌的点数的大小,大者为赢家。1.2程序网络的实现1、游戏开始之前需要建立TCP网络连接,某一玩家充当Server,等待连接,另一玩家充当Client,进行连接;2、游戏开始时Server端初始化数据并发送数据到Client端进行同步;3、当前玩家完成行动后需发送行动类型到对方玩家,然后等待对方玩家的行动;4、如果当前玩家选择不要牌,则需要等待对方玩家进行多次行动,直到对方玩家爆牌或者选择不要牌为止。1.3数据类型设计扑克牌类分值花色玩家类姓名:人类玩家,电脑玩家玩家的已分配的扑克牌数组当前局的得分状态标志:正常,爆牌,不要牌总得分5数据同步结构体初始扑克牌数组:52张待分配的扑克牌玩家的行动类型:-1游戏开始;0要牌;1不要牌1.4游戏引擎类设计数据成员:扑克牌数组,保存52张待分配的扑克牌人类玩家和对方玩家当前应发扑克牌的编号游戏进行状态游戏进行中人类玩家爆牌电脑玩家爆牌人类玩家获胜电脑玩家获胜平局等待对方行动Server:已获取网络连接;Client:已建立网络连接套接字:侦听套接字,连接套接字(游戏数据发送)对外接口和方法:开始游戏人类玩家要牌人类玩家不要牌侦听:初始化,等待连接连接:初始化,建立连接网络消息处理FD_ACCEPTFD_CONNECTFD_READ三种消息类型:游戏初始化;玩家要牌;玩家不要牌61.5程序功能结构图1.6流程图1.6.1侦听71.6.2连接1.6.3开始游戏81.6.4人类玩家要牌91.6.5人类玩家不要牌101.6.6网络消息处理11第2章详细设计2.1游戏引擎封装头的文件,及源文件GameEngine.h#pragmaonce#includestdafx.hclassPuker{public:intnum;//1-13intset;//1-4};classPlayer{public:TCHARname[16];Pukerpk[11];intsum;intflag;//1,不要牌intsign;//1,爆牌};classGameEngine{public:conststaticintGAME_NOT_END=0;conststaticintGAME_PLAYER_OVER=1;conststaticintGAME_COMPUTER_OVER=2;conststaticintGAME_PlAYER_WIN=3;conststaticintGAME_COMPUTER_WIN=4;conststaticintGAME_DRAW=5;//平局//typedefenumpoint{ace=1,two,three,four,five,six,seven,eight,nine,ten,jack,queen,king}point;public:Pukerpuker[52];Playercomputer,people;intiCount;//当前将要发的牌在puker中的顺序private:12voidInitial(void);//初始化玩家/*洗牌,随机抽取两张牌,交换位置,执行1000次*/voidShuffle(void);//洗牌voidDistribute(Player*a);//发牌voidComputerPlay(void);//电脑玩牌voidPeoplePlay(BOOLbPass);//玩家玩牌public:intStartGame(void);//开始游戏,发第一张牌intGetCard(void);//玩家要牌intPass(void);//玩家不要牌private:intEnd(void);//当两方都没爆牌且都不要牌时计分};GameEngine.cpp#includestdafx.h#includeGameEngine.h#includetime.hvoidGameEngine::Initial(void)//初始化玩家{inti;intj=0;intk=1;for(i=0;i52;i++){j++;if(j13){j=1;k++;}13puker[i].num=j;puker[i].set=k;}for(i=0;i11;i++){computer.pk[i].num=0;computer.pk[i].set=0;people.pk[i].num=0;people.pk[i].set=0;}_tcscpy(computer.name,_T(computer));_tcscpy(people.name,_T(people));computer.sum=0;computer.flag=0;computer.sign=0;people.sum=0;people.flag=0;people.sign=0;}/*洗牌,随机抽取两张牌,交换位置,执行1000次*/voidGameEngine::Shuffle()//洗牌{srand((unsigned)time(NULL));inti,j,k;Pukertemp;for(i=0;i1000;i++){//j=rand()%52;//k=rand()%52;j=(double)rand()/(RAND_MAX+1)*(52-0)+0;k=(double)rand()/(RAND_MAX+1)*(52-0)+0;temp=puker[j];puker[j]=puker[k];puker[k]=temp;}iCount=0;}voidGameEngine::Distribute(Player*a)//发牌{intm;for(m=0;m11;m++)14{if(a-pk[m].num==0){a-pk[m]=puker[iCount];a-sum+=a-pk[m].num;break;}}iCount++;//发一张牌后,指向后面的一张牌}voidGameEngine::ComputerPlay()//电脑玩牌{if(computer.flag==0)//电脑目前还未决定是否继续要牌{intk;//k=(100*(21-computer.sum)/21+rand()%50);//产生随机数,计算是否要牌k=(100*(21-computer.sum)/21+(double)rand()/(RAND_MAX+1)*(50-0)+0);if(k=50){//computer要牌Distribute(&computer);if(computer.sum21){computer.sign=1;return;}}elseif(k