单机版斗地主的游戏算法的设计毕业设计论文.docx
- 文档编号:3923172
- 上传时间:2022-11-26
- 格式:DOCX
- 页数:26
- 大小:126.77KB
单机版斗地主的游戏算法的设计毕业设计论文.docx
《单机版斗地主的游戏算法的设计毕业设计论文.docx》由会员分享,可在线阅读,更多相关《单机版斗地主的游戏算法的设计毕业设计论文.docx(26页珍藏版)》请在冰豆网上搜索。
单机版斗地主的游戏算法的设计毕业设计论文
摘 要
随着科技的进步,计算机已经普及每个家庭,而计算机游戏也随之越来越多,越来越丰富。
网络游戏、单机游戏等休闲游戏让众多人喜欢,而斗地主也受广大群众的追捧。
本设计以一副牌规则为准,将整个游戏按照发牌,叫牌,拆牌,以及出牌的流程划分为4个部分,开始时由系统调用发牌函数每人随机分到17张牌,留存3张底牌,然后电脑AI根据自己手上牌值与牌型结合给定权值决定是否叫三张底牌当地主。
一旦叫牌成功,剩下两玩家就是农民,联合“斗地主”。
双方以是否出完牌来决定胜负。
如果地主的20张牌都出完了,则地主一方胜;如果两个农民中任何一人手中的17张牌出完了,则农民一方胜出。
本论文主要讲述了单机版斗地主的游戏算法的设计,以VisualC++语言编译的一个应用程序。
使用者可以简单方便的实现斗地主游戏。
本程序界面友好,操作简单,比较实用。
本程序在详细设计时不断地修正和完善,经过测试阶段反复调试和验证,最终形成达到设计要求的可行系统。
关键词:
斗地主;纸牌;VisualC++;游戏核心算法
Abstract
Withtheprogressofscienceandtechnology,computershaveuniversaleveryfamily,andwithmoreandmorecomputergames,increasinglyrich.Thenetworkgame,LANgameandothercasualgamesformanypeoplelikeit,butLandlordalsoaffectedbythebroadmassesinbothhands.
Thisdesignwillbesubjecttorulesofadeckofcards,theentiregameinaccordancewiththelicensing,call,cards,aswellastheprocessisdividedintofourparts.Licensingfunctioniscalledbythesystematthebeginning,then17cardsarerandomlyassignedtoeachpersonandthreecardsarealsoretained.Afterthat,thecomputerAIdecideswhethertocallcardsbasedonit'sowncardsvalueandthecardstypewhichallhaveaparticularweight.Oncethecallissuccessful,theremainingtwoplayersisfarmers,jointing"Landlords".Whetherthetwosidesfinishcardsdeterminethewinner.Ifthelandlord's20cardsarefinished,thelandlordsidewin;Ifanyoneofthetwofarmersfinishes17cards,thefarmerswin.
Thispapertellsthestand-aloneLandlordgamealgorithmisdesignedtoVisualc++languagecompiledanapplication.UserscansimpletorealizeFighttheLandlordgame.Thisprocedurefriendlyinterface,theoperationissimple,ismorepractical.
Thisprocedureinthedetaileddesignconstantlycorrectionandperfectwhen,aftertestingphaserepeatedcommissioningandvalidation,andfinallyformthefeasiblesystemtomeetthedesignrequirements.
KeyWords:
Fightthelandlord;Cards;VisualC++;Gamecorealgorithm
1绪论
1绪论
1.1课题背景
“斗地主”起源于湖北,据传是一位叫吴修全的年轻人,根据当地流行的扑克玩法“跑的快”改编的。
由于其游戏规则简单、娱乐性强、老少皆宜,如今已风靡整个中国,并流行于互联网上。
具体规则为:
由三人玩一副牌,其中一方作为地主,另外两方联合作为农民向地主对抗。
开始时每人随机分到17张牌,然后各玩家根据自己手上牌的好坏决定是否叫三张底牌当地主。
一旦叫牌成功,剩下两玩家就是农民,联合“斗地主”。
双方以是否出完牌来决定胜负。
如果地主的20张牌都出完了,则地主一方胜;如果两个农民中任何一人手中的17张牌出完了,则农民一方胜出。
1.2研究现状
随着电脑软硬件技术和互联网的飞速发展,电脑游戏也突飞猛进,成功游戏不断涌现。
比较成熟的大型游戏主要有:
反恐精英(CS)、星际争霸、魔兽争霸2、FIFA2003、帝国时代、FIFA2004等等。
这时也出现了越来越多的网络小游戏,休闲类项目包括网络围棋、中国象棋、四国军棋、桥牌、麻将、拱猪、拖拉机、斗地主等。
各式各样的游戏给我们的生活带来了无限的乐趣,但同时也出现了一些问题。
虽然计算机电脑已经普及绝大多数家庭,但有些偏远的地方却无法正常的接受到网络信号,这就给一部分人带来了有电脑不能上网休闲的烦恼。
因此,一些单机游戏更受到了人们的追捧。
本设计的目的是用简单的C语言设计出一个斗地主的小游戏,使用者只要运行该程序,就可以轻松的玩游戏了。
1.3研究项目及意义
“斗地主”属于不完全知识博弈,意思是指参与的三方一开始都不清楚对手手中有什么牌。
作为全国广泛流传且具有中国特色的一个牌类游戏,被当做计算机技术的研究对象却是不常见的。
本设计旨在分析“斗地主”AI程序的各个必要部分,以“斗地主”的游戏规则为基础,给出各部分的初级探讨,给出一个较有效的“斗地主”AI程序。
重点研究拆牌算法,并做出相应的分析、设计和实现。
1.4本文的结构安排
结合引言部分,参看各节的标题可以知道,本论文是由引言、本论、结论三部分组成。
而本轮部分是沿着实际游戏流程一步步论述的。
这样的布局,更容易被接受。
1.5系统开发工具及其介绍
1.5.1开发工具的选择
古语云:
工欲善其事,必先利其器。
利用一系列高效的、具有良好可视化的编程工具去开发各种数据库软件,从而达到事半功倍的效果,所以开发工具的选择显得非常重要。
随着计算机技术不断发展,各种编程工具也随着发展,但是现在市面上的数据库编程工具门类众多,优良不齐,比如VB、PB、DELPHI、C++Builder、VC、JAVA等。
我们先来了解一下各类开发工具。
VB,全称VisualBasic,它是以Basic语言作为其基本语言的一种可视化编程工具。
VB开发效率高,代码执行效率一般,但是入门和学习速度快,有较好的学习氛围和帮助书籍和帮助文档。
但是随着微软的.NET技术的推广,VB将会逐渐退出历史舞台。
PB,全称PowerBuilder,是开发MIS系统和各类数据库跨平台的首选,使用简单,容易学习,容易掌握,在代码执行效率上也有相当出色的表现。
但是PB的高级编程书籍的缺乏和基础语言PowerScript的普及程度对PB的明天有一定的限制。
DELPHI/C++Builder它们都是基于VCL库的可视化开发工具,它们在组件技术的支持、数据库支持、系统底层开发支持、网络开发支持、面向对象特性等各方面都有相当不错的表现,并且学习使用较为容易,充分提现了所见即所得的可视化开发方法,开发效率高。
,它们所作的最大不足之处就是他们的帮助系统在众多的编程工具中是属于比较差的。
JAVA工具,目前比较出名的是Borland出的JBuilder和IBM出的VisualAgeforJava,两种工具。
适用于开发除了系统软件、驱动程序、高性能实时系统、大规模图像处理以外所有的应用。
在一般的管理信息系统中和一般的数据库开发中,很少有人会选择JAVA。
但是JAVA的强大网络功能和真正的面向对象特性决定了JAVA的未来,JAVA将在一个较为长期的时段里可以与微软家族抗衡。
VisualC++,是基于MFC库的可视化的开发工具,从总体上说它是一个功能强大但是不便使用的一种工具。
它在网络开发和多媒体开发都具有不俗的表现,帮助系统也做得非常不错(Microsoft在细节方面的处理往往都让人觉得亲切),从功能上讲除了跨平台应用外什么都可开发;从开发效率角度讲只局限于开发windows系统应用、可重用组件及驱动程序。
又因为有微软的支持,其自身的基础语言的普及程度高,以及其代码的执行效率高等特性、VC自带强大帮助文档和大量优质教材,VC在开发工具中始终可以稳住阵角。
1.6VisualC++编程特点
1.6.1C++语言的发展
C++语言发展大概可以分为三个阶段:
第一阶段从80年代到1995年,C++语言基本上是传统类型上的面向对象语言,并且凭借着接近C语言的效率,在工业界使用的开发语言中占据了相当大份额;
第二阶段从1995年到2000年,这一阶段由于标准模板库(STL)和后来的Boost等程序库的出现,泛型程序设计在C++中占据了越来越多的比重性。
当然,同时由于Java、C#等语言的出现和硬件价格的大规模下降,C++受到了一定的冲击;
第三阶段从2000年至今,由于以Loki、MPL等程序库为代表的产生式编程和模板元编程的出现,C++出现了发展历史上又一个新的高峰,这些新技术的出现以及和原有技术的融合,使C++已经成为当今主流程序设计语言中最复杂的一员。
C++是由C语言发展而来,是面向对象程序设计语言之一。
C++语言是一种应用较广的面向对象的程序设计语言,使用它可以实现面向对象的程序设计。
面向对象的设计与面向过程的设计是有很大区别的,面向对象的程序设计是在面向过程的程序设计的基础上一个质的飞跃。
1.6.2VisualC++6.0简介
VisualC++是Microsoft公司的VisualStudio开发工具箱中的一个C++程序开发包。
VisualStudio提供了一整套开发Internet和Windows应用程序的工具,包括VisualC++,VisualBasic,VisualFoxpro,VisualInterDev,VisualJ++以及其他辅助工具,如代码管理工具VisualSourceSafe和联机帮助系统MSDN。
VisualC++包中除包括C++编译器外,还包括所有的库、例子和为创建Windows应用程序所需要的文档。
VisualC++作为一个主流的开发平台一直深受编程爱好者的喜爱,但是很多人却对它的入门感到难于上青天,究其原因主要是大家对他错误的认识造成的,严格的来说VisualC++不是门语言,虽然它和VisualC++之间有密切的关系,如果形象点比喻的话,可以VisualC++看作为一种“工业标准”,而VVisualC++则是某种操作系统平台下的“厂商标准”,而“厂商标准”是在遵循”工业标准”的前提下扩展而来的。
从最早期的1.0版本,发展到最新的6.0版本,VisualC++已经有了很大的变化,在界面、功能、库支持方面都有许多的增强。
最新的6.0版本在编译器、MFC类库、编辑器以及联机帮助系统等方面都比以前的版本做了较大改进。
VisualC++的优点是界面简洁,占用资源少,操作方便。
1.6.3VisualC++6.0的开发环境
VisualC++6.0是一个Windows应用程序,启动后显示一个标准窗口,包括窗口框架、标题栏、菜单栏、工具栏、项目工作区、状态栏等,在这个窗口中可完成程序创建工程、编辑编译文件、资源编辑、程序调试、链接生成可执行文件等工作,是一个集成化开发环境。
应用程序的大部分命令是通过菜单发出的,在使用一个开发工具之前,了解其菜单功能是非常重要的。
VisualC++6.0的主菜单包含File、Edit、View、Insert、Projec、Build、Tools、Windows、Help等项。
图1.1VisualC++6.0的标准窗口
File菜单:
New选项的新建文件中可以选择创建新的C++源文件,头文件等
图1.2创建新的头文件和源文件界面
Edit菜单:
包含对源文件进行编辑的命令,有许多与Word编辑命令相同,另外还包含一些针对方便源文件录入的辅助工具。
Build菜单:
对程序代码进行调试和生成可执行程序。
2斗地主基本知识
2.1斗地主规则
1.发牌
一副牌54张,一人17张,留3张做底牌,在确定地主之前玩家不能看底牌。
2.叫牌
叫牌按出牌的顺序轮流进行,叫牌时可以选择“叫地主”、“不叫”。
如果有玩家选择“叫地主”则立即结束叫牌,该玩家为地主;如果都“不叫”,则重新发牌,重新叫牌,直到有人“叫地主”为止。
3.牌型
“斗地主”的牌型丰富多彩,根据QQ游戏提供的说明,牌型定义如下:
火箭:
即双王(大王和小王),最大的牌;
炸弹:
四张同数值牌(如四个7);
单牌:
单个牌(如红桃5);
对牌:
数值相同的两张牌(如梅花4+方块4);
三张牌:
数值相同的三张牌(如三个J);
三带一:
数值相同的三张牌+一张单牌或一对牌,如:
333+6或444+99;
单顺:
五张或更多的连续单牌(如:
45678或78910JQK),不包括2点和双王;
双顺:
三对或更多的连续对牌(如:
334455、7788991010JJ),不包括2点和双王;
三顺:
二个或更多的连续三张牌(如:
333444、555666777888),不包括2点和双王;
飞机带翅膀:
三顺+同数量的单牌(或同数量的对牌),如:
444555+79或333444555+7799JJ;
四带
(一)二:
四张牌+
(一)两手牌(四带
(一)二不是炸弹),如:
5555+3+8或4444+55+77。
4.牌型大小
各牌型的大小定义如下:
火箭最大,可以打任意其它的牌;
炸弹比火箭小,比其它牌大,都是炸弹时按牌的分值比大小;
除火箭和炸弹外,其它牌必须牌型相同且总张数相同才能比大小;
单牌按分值比大小,依次是大王>小王>2>A>K>Q>J>10>9>8>7>6>5>4>3,不分花色;
对牌、三张牌都按分值比大小;
顺牌按最大的一张牌的分值来比大小;
飞机带翅膀和四带二按其中的三顺和四张部分来比,带的牌不影响大小。
2.2游戏流程框架
图2.1游戏流程框架图
3主要模块
3.1发牌
3.1.1第一发牌方案
由于调试和实际应用需要,对于既定牌局的出牌方案,需要手动输入。
然而手动输入手中持牌是远远不够的。
如果是开局,除了输入手中持牌,在程序处理方面,应该将剩下的牌随机分配且均匀分配给另外两家,最终剩余三张底牌。
如果是已经叫了地主,剩余的三张底牌也是公开的,仅有34张需要随机分配给剩余两家。
如果是进行到一半,需要将牌池中的牌型以及出牌玩家和出牌顺序记录下来,供程序分析,调用算牌程序,从而推导出优化出牌方案。
图3.1手动输入牌值运行界面
3.1.2第二发牌方案
由于调试和权值确定的需要,对于不确定的牌局,需要机器随机分配。
对于长篇代码的修改,为了省时并且测试意想不到的数据可能效果,通常是一个循环,连续多次不断分配,直至强行退出DOS程序运行界面。
对于权值确定方面,主要功能是统计不通牌型和牌值出现的概率。
将这些硬数据作为权值确定的参数基础。
图3.2系统自动发牌界面
3.1.3发牌算法的代码实现
intGetCards(PLAYERplayer[],inthide_cards[])//发牌算法
{
intnumCards[16]={0},i,j,k=0;
boolfenpei=false;
for(i=1;i<=15;i++)
{
if(i==15||i==14)
numCards[i]=1;
elsenumCards[i]=4;//到此时numCard数组里面是0444...411
for(j=0;j<3;j++)
player[j].numCards[i]=0;//到此每个player的numcard里面都是000...000
}
srand((unsignedint)time(NULL));
//发牌过程
for(i=0;i<17;i++)//发17轮牌3个do-while为一轮发牌
{
for(k=0;k<3;k++)
{
do{
j=rand()%15+1;//随机发牌
if(numCards[j]>0)
{
player[k].numCards[j]++;
numCards[j]--;
fenpei=true;
}
}while(!
fenpei);//如果fenpei为false说明此次分配未成功,继续循环
fenpei=false;
}
}
for(i=1,j=0;i<=15;i++){//剩余牌提出做底牌
while(numCards[i]){
hide_cards[j]=i;
j++;
numCards[i]--;}
}
return1;
}
3.2叫牌
3.2.1是否叫牌
初始模型是直接根据每种牌型的权值给出的,然而仅仅用权值是无法刻画出真实的是否叫牌的决断的,有时甚至还会产生笑话。
由此,给出除了权值的另外一种刻画方式:
手数。
手数是指将手中的牌按规则出完所需要轮过的次数。
然而,不同的拆牌方式将导致手数的不同。
由于牌型的变化极其复杂,所以从众多的拆牌方式中选出手数最少的一种是比较困难的,这是本文源码实例的重点,也是本章的主要内容。
3.2.2牌型估值
1,牌型的价值评估
牌型的价值评估,简单地说就是评估牌型的可以算一手味的权值。
一手味是指可以在一轮牌中压倒另外两家。
初步的方法是直接给出各种牌型的值,牌型的权值KindValue=(CardNumber*CardValue),其中,KindValue是指牌型的权值,CardNumber指该牌型的牌所具有的牌的张数,CardValue指单张时候牌的权值。
仅仅这样简单的评估,显然是不符合实际需要的。
原因是对于牌型的权值评估,往往还跟其它因素有关。
例如,当三方手上的牌较少时,长顺子的权值会更高。
这就需要动态地设计权值了。
2.牌型关系的评估
牌型间的关系也是估值的重要内容之一,可以将某个牌型很有可能被敌方压住看成是一个不利因素。
例如手中持有34567的顺子,但是没有顺子回手,这时可以根据该顺子的权值与恶劣的牌型关系导致的负值之和来刻画。
牌型关系的评估应该考虑到该谁出牌和地主农民的座次问题。
如果自己是农民,且是地主的下家,恶劣的牌型关系比较轻;如果是地主的上家或者是地主,牌型关系更加恶劣。
3.编写统计程序,实时更改相应参数
针对每局的拆牌分析和对剩余两家的算牌分析,分别存入拆牌牌型数目统计表和预测牌型统计表。
前者用于确定权值的硬指标参数。
例如:
在没有复杂牌型,且不考虑王和2的情况下,三无且不考虑王、2和三张底牌,有每把各牌型出现次数如下:
一张的:
4.145,两张的:
3.245,三张的:
1.135,四张的:
0.133。
而4.145×1+3.245×2+1.135×3+0.133×4=4.145+6.590+3.405+0.532=14.672≈15(期望值),绝对误差0.338,相对误差0.338/15≈2.253%。
这四个参数可以用来描述这四种牌型的相互关系。
而牌型内部关系可以根据牌值的不同和方差来确定。
由于根据参考文献[7]的随机方法来预测是不现实的,因为变数太多,情况极其复杂,在现有的水平内无法实现加法和乘法、条件概率以及先验概率的多重严格的数学分析。
故可以通过预测牌型统计表的后验法来统计正确率,并根据正确率的不同调整预测参数。
例如:
在A出了777+5的时候,参看自己手上没有7,这样的情形下,原本猜测C方有一个7的可信度为1。
可是在经过几局的后验之后,可能出现A有含7的顺子,而C没有7的情形。
从而可根据这种情形在总局数中的比例,适当调整这个可信度。
boolJiaopai(PLAYER&player)
{
//拆分之后,复原player.numCards数组的值,以便后续分析
vector
:
iteratorit;
//七种牌型的顺序:
一张、两张、三张、四张、顺子、连子、飞机
doublefangcha[7]={0},middle[7]={0};//方差:
用来描述照应关系,越大越好;中值
doublequan_sum=0,quan_dandu=0,quan[7]={0};//总权,七种牌型的分权{不包括王、2}
inti,num[7]={0};//num用来记录各种对应牌型的数目
for(it=player.paixing.begin();it!
=player.paixing.end();it++)
{
if((*it).kind==1)//单张
{
player.numCards[(*it).start]++;
middle[0]+=(*it).start;
num[0]++;
}
if((*it).kind==2)//对子
{
player.numCards[(*it).start]+=2;
middle[1]+=(*it).start;
num[1]++;
}
if((*it).kind==3)//3张
{
player.numCards[(*it).start]+=3;
middle[2]+=(*it).start;
num[2]++;
}
if((*it).kind==4)//炸弹
{
player.numCards[(*it).start]+=4;
middle[3]+=(*it).start;
num[3]++;
}
//顺子连子飞机的权值确定方法:
由各个相应牌型的长度和数目决定
if((*it).kind==5)//单顺
{
for(i=(*it).start;i>=(*it).start-(*it).length+1;i--)
player.numCards[i]++;
num[4]++;
}
if((
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单机 地主 游戏 算法 设计 毕业设计 论文