本科毕业设计五子棋游戏的设计与实现.docx
《本科毕业设计五子棋游戏的设计与实现.docx》由会员分享,可在线阅读,更多相关《本科毕业设计五子棋游戏的设计与实现.docx(34页珍藏版)》请在冰豆网上搜索。
本科毕业设计五子棋游戏的设计与实现
毕业论文(设计)
题目五子棋游戏的设计与实现
姓名王勇学号**********
所在院(系)数学与计算机科学学院
专业班级信息与计算科学1101班
指导教师拓守恒
完成地点陕西理工学院
2015年5月18日
五子棋游戏的设计与实现
作者:
***
(陕理工学院数学与计算机科学学院信息与计算科学专业1101班,陕西汉中723000)
指导教师:
***
[摘要]五子棋是起源于我国古代的黑白棋种之一,是一种简单的娱乐性较强的大众游戏,深受广大玩家的喜爱,但同时作为比赛,五子棋游戏还有着深奥的技巧。
本系统的实现采用了C语言的模块化的程序设计方式,用VisualC++6.0软件来实现程序的编译运行。
实现黑白两方分别落子,通过棋盘上方的棋盘动态信息提示,轮流落子,本系统中游戏的每一个功能在程序中都是一个相对独立的模块,比如,棋盘模块,棋子模块,选择游戏模式模块,悔棋模块等等在程序中都是独立的,但它们之间通过逻辑关系的链接又构成了一个可以使游戏正常运行的程序。
为实现游戏的双人对战模式和人机对战模式,并使得游戏尽量的简单化,本系统需要达成以下目标:
设计一个简洁的游戏初始界面;制定合法规则,使游戏能公正的进行,并且可以断定胜;支持人机对战模式,可以是电脑通过人工智能和合法规则选出最优落子位置;可以悔棋,在玩家落子落错位置时,可按下悔棋键进行悔棋。
[关键词]五子棋,游戏设计,C语言,双人对战,人机对战,人工智能
Designerandimplementationofgobanggame
Author:
wangyong
(Grade11,Class1,MajorinInformationandcomputingscience,MathematicsandcomputerscienceDept.ShaanxiUniversityofTechnology,Hanzhong723000,Shaanxi)
Tutor:
Tuoshouheng
Abstract:
GobangisoneoftheblackandwhitekindoforiginatedinancientChina,isasimpleandentertainingstrongermassgames,lovedbythemajorityofplayers,butatthesametimeasthegame,gobanggamewithprofoundskills.
TheimplementationofthissystemhasadoptedCofmodularprogramdesignmethod,usingVisualC++6.0softwaretorealizetheprogramcompilerrunning.Implementationofblackandwhitetwopartiesmovelater,respectively,bytheboardatthetopofthedynamicmessageboard,taketurnstomovelater,thisgameinthesystemeachfunctionintheprogramisarelativelyindependentmodules,suchas,theboardmodule,pawnmodule,selectgamemodemodule,backmoduleandsoonintheprogramareindependent,butthelinkthroughthelogicalrelationshipbetweenthemandformacanmakethenormaloperationofthegameprogram.
Inordertorealizethedoublemodeandman-machinegamemode,andmakethegameasfaraspossiblethesimplification,thesystemneedstoachievethefollowinggoals:
designasimplegameofinitialinterface;thelegalrules,canmakethegamefair,andyoucancall;supporttheman-machinemode,canbeacomputerbyartificialintelligenceandlegalrulestoselecttheoptimalmovelater;cantakeback,fallintheplayersmovelaterfaultlocation,canpressthebackbuttontoback.
Keywords:
gobang,Gamedesign,TheCProgrammingLanguage ,Doubleagainst,Theman-machineagainst,Artificialintelligence(AI)
1.绪论
1.1引言
随着社会经济和科学技术的发展,计算机已经深入到人们日常工作和生活的方方面面,各种各样的程序软件也逐渐进入大众的生活,比如在闲暇时间的娱乐生活也开始变得被网络电子游戏等所充斥。
而五子棋则是最受人们欢迎的一款益智类棋局游戏,它的简单性,娱乐性,竞技性注定它是一款火爆的游戏。
1.2研究的背景及意义
1.2.1研究背景
五子棋游戏软件可以分为两种:
一种是网络五子棋游戏软件,另一种是单机五子棋游戏软件。
我设计的是单机版的五子棋游戏软件,这款软件可以供人们在闲暇时间随时随地进行娱乐,并提高自己的棋艺,实用性较强。
游戏的行棋顺序为:
黑先、白后,黑棋第一子从天元开始相互依次落子,任一方先在棋盘上形成横向或竖向或斜向的连续的颜色相同的五个以上(含五个)棋子则该方为胜。
该系统所实现的功能主要有三大功能:
游戏选项、游戏设置、帮助。
1.2.2研究意义
五子棋是起源于中国古代的传统黑白棋种,当今社会在不同的地域对五子棋也有不同的称呼,其也是一种必须动用脑力的益智类游戏,所以五子棋可以增强思维能力,提高智力。
其中蕴含古典哲学的高深学问“阴阳易理”哲理,有利于修身养性,它因为简单易学的特点,所以为人民群众所喜爱,但作为一项高水平的国际比赛,它也有深奥技巧。
1.3基本目标及主要内容
本系统是根据传统五子棋游戏的功能编写,实现了双人对战和人机对战。
主要需实现如下目标:
(1)VisualC++6.0 环境的下的C语言编程
(2)五子棋棋盘的设计
(3)五子棋棋子的设计
(4)黑白双方轮流落子的实现
(5)棋局的悔棋功能
(6)棋局进行时的退出功能
(7)胜负的判定
(8)人工智能算法分析
2.系统开发环境的介绍及选择
2.1C语言
C语言诞生于1972年的美国,在次之前还有A语言(其创造设计者是一位女性)和B语言。
现在C语言成为了世界上使用最广泛的,最流行的高级程序设计语言之一。
随着经济与科技的发展,微型计算机日渐普及,这导致了C语言的版本的多样化,出现了一些不一致的语言特点。
为了改变这种情况,美国国家标准研究所制定推广了一套ANSI标准,作为现行的C语言标准。
常用的编译软件有MicrosoftVisualC++。
C语言绘图能力强,具有很好的可移植性,并具备很强的数据处理能力,因此适于编写系统软件。
它是数值计算的高级语言。
由文献[1-4]可知。
2.2开发及运行环境
编程语言:
C语言
操作系统:
Windows7
开发工具:
MicrosoftVisualC++6.0
3.需求分析
3.1总体需求分析
五子棋游戏是一款很符合现代人的休闲特点的益智类游戏,其是我国古代围棋的的衍生物,本系统主要分为两部分:
双人人对战和人机对战。
双人对战模式实现的功能:
选择双人对战,游戏界面,实现双人轮流落子,棋盘动态信息显示,判断输赢,重新开始游戏。
人机对战模式实现的功能:
选择人机对战,设置先手,实现玩家与电脑轮流落子,棋盘动态信息显示,判断输赢,重新开始游戏。
3.2可行性分析
3.2.1技术可行性分析
计算机硬件和软件技术的飞速发展,为游戏系统的开发提供了设备条件。
当前在网络上有许多的五子棋软件可供参考借鉴,而且我自己也熟练地掌握了C语言在MicrosoftVisualC++6.0环境下的基本应用,因此本游戏的开发技术上是完全可行的。
3.2.2经济可行性分析
该游戏适用于所有人群,开发该游戏的费用主要包括开发阶段的费用以及今后的运行、维护费用。
五子棋游戏简单易学,为人民群众喜闻乐见。
该游戏功能强大,界面简单,用户在使用方面不存在任何障碍。
其开发具有很强的经济性。
3.2.3操作可行性分析
本游戏适用于Windows操作系统之上,对于该游戏的推广使用提供了很好的平台。
该游戏使用C语言编写,具有很强的移植性,使其可以运行很方便。
在操作上主要凭借使用Windows键盘操作,方便简单。
使用前只要对用户进行简单的说明即可。
3.3功能分析
该款游戏主要是由以下五个模块组成:
图3.1游戏功能图
4.概要设计
4.1五子棋特点与规则
五子棋是两方之间进行的竞技活动,专用棋盘为15*15,五连子的方向为横、竖、斜;任一方在棋盘上形成横向、竖向、斜向的连续的相同颜色的五个(含五个以上)时即为该方胜利;在棋盘上以对局双方均不可能形成五连为和棋。
黑白双方依次落子,由黑方先下,由于先下一方在局面上占优,所以五子棋规则分为禁手和无禁手两种。
禁手规则:
禁手是针对先行的黑棋而言,以限制黑棋的先行优势为目的。
对局中如果黑棋违反禁手规则将被判负。
以中国五子棋竞赛规则为例,有三三禁手(黑棋一子落下时同时形成两个或两个以上的活三,此子必须为两个活三共同的构成子)、四四禁手(黑棋一子落下同时形成两个以上的冲四或活四)、长连禁手(黑棋一子落下形成一个或一个以上的长连)。
无禁手指不对黑棋的先行优势做任何限制。
本系统采用的是无禁手规则。
4.2流程图
游戏开始后,运行过程如下图4.1所示:
图4.1游戏运行流程图
当系统运行后,首先看到的是一个选择游戏模式(双人,人机)的界面,根据要求选择后,有两种情况,第一种是双人模式,根据游戏的设定先黑方落子,然后白方落子,而系统此时需要更新棋盘的状态和判断是否产生输赢,若是产生则游戏结束,若没有产生输赢,则判断是否棋盘已经落满棋子,若已经落满棋子,则判定为和棋,否则另一方落子,如此循环,直到产生输赢或和棋;另一种是人机模式,选择该模式后,会看到设置界面,可以选择谁是先手,有两种选择电脑先手、玩家先手,若电脑先手则根据设定,电脑执黑子先下,之后白方落子,此时因为选择了电脑先手,所以电脑落子时优先进攻,只有在进攻的权值小于防守的权值时优先防守,(此处涉及到电脑的人工智能,此部分的设计概要详见本章节的电脑智能落子部分),每当棋盘落子后电脑立即更新棋盘的具体信息并判断是否已经产生输赢若是产生则游戏结束,若没有产生输赢,则判断是否棋盘已经落满棋子,若已经落满棋子,则判定为和棋,否则另一方落子,如此循环,直到产生输赢或和棋,玩家先手,则玩家执黑子先落子,然后电脑落白子,此时电脑落子优先防守,其他部分与电脑先手一样。
4.3双人模式
此模式较为简单是后面实现人机模式的铺垫。
首先用循环语句和制表符画出整个棋盘,然后利用绘图函画出棋子,然后制定自己的落子规则(包含输赢规则),并用循环语句实现黑白子的轮流下子,如此就实现了双人对战的目的。
4.4人机模式
本系统中此功能的实现是在双人模式已经实现的情况下实现,只是把双人模式中的其中一个人换成电脑操作(电脑落子算法参照4.5智能算法),在每次落子之后,调用判断输赢函数判断是否产生输赢或和棋,如果产生则游戏结束,如果没有产生则继续游戏,直到产生输赢或和棋,或退出游戏为止。
4.5智能算法
电脑博弈模仿人类下棋,传统算法使用的是博弈树。
两人游戏,甲有很多位置选择落子,乙也有很多相对应的下法,如果所有的方式列表就构成一棵树,就是搜索树,也被称为博弈树。
树的根节点先手的第一步位置,下面的走棋方法构成树的子节点,直到游戏结束。
此处的五子棋棋盘是15×15的,搜索空间是一个巨大的数字。
博弈算法的任务是在这些呈几何级数上升的子节点中选出最优的节点,从而赢得比赛。
整个算法分为搜索和估值两部分,估值是评估所有可能的落子位置的评价,选择评价最高的位置为最终落子位置。
本系统的估值函数为单点估值函数。
单点估值函数的基本思想是评估当前的静态情况下,遍历棋盘,对棋盘的每个非空的位置的四个方向进行分析评估(横向、竖向、两条对角线),统计每一个棋型的数量(连五型、冲四型、活四型、活三型、死三活二型),不同的棋型根据实际情况中玩游戏时的经验确定一个不同的权重值,最后还有位置分数的加权(不仅要考虑空点对自己的价值,也要考虑其对对方的价值),如此就获得了棋盘上的空点的估值。
单点估值函数只能估计一个空点的价值,对当前的棋局,把所有的空点对己方的有利程度总和和不利程度总和相关就可得出全局价值。
由文献[5.6.14]可知。
本系统中设定了以下几种棋型和相应的权值:
表4.1防守棋型及其相应权值表
棋型
连五型
冲四型
活四型
活三型
死三活二型
权值
200000
1100
6000
240
20
表4.2进攻棋型及其相应权值表
棋型
连五型
冲四型
活四型
活三型
死三活二型
权值
2000000
2000
24000
850
125
根据不同棋型的权值可以计算出棋盘的各点的价值之和,用Vij表示点(i,j)的总价值,用Aij表示点(i,j)的进攻价值,用Dij表示点(i,j)的防守价值,用dt表示防守优先级数,at表示进攻优先级数,其中防守和进攻优先级数是电脑在比较点(i,j)的进攻总价值和防守总价值后赋予的,给总价值大的类型设定优先级数为2,而价值小的则为1。
则点(i,j)的进攻总价值为该点的所有进攻棋型的和,计算方法为:
;
该点的防守总价值为该点的所有防守棋型的和,计算方法为:
。
则该点的总价值为:
。
用此方法就可遍历棋盘上的所有的空点的总价值,然后比较所有总价值的大小,总价值最大的点即为对自己最有利的点。
4.6悔棋流程
悔棋是棋局类游戏的必须的功能,在游戏时,如果有人悔棋时,立即调用悔棋功能函数,本系统中由于棋盘上的所有的交点都有一个二维数组的一组数据与之相对应,而且每次落子后会有一个二维数组记录相应的信息(步数,棋子颜色),因此此功能的实现依靠的是C中的循环函数。
4.7输赢判断
本模块功能的实现依靠的是单点估值函数的思想,即每次落子之后,遍历以该点为坐标原点以5为半径的棋盘的交点,分析原点的四个方向(横向、竖向、两条对角线),判断是否有连五型棋型,若有则产生输赢,若没有则遍历整个棋盘,查看是否棋盘已经下满,若已下满则判定为和棋,否则继续游戏。
5.详细设计
5.1画出游戏界面
本模块是整个游戏系统的平台性模块,之后所有的功能都将依附该模块来体现,主要需实现棋盘的绘制与游戏说明。
本游戏系统选择的是15*15的棋盘,利用制表符字符串打印输出棋盘,并且特别标出天元位置,与四方星位。
游戏的说明主要有棋局动态信息显示,如何移动光标,如何实现落子,如何悔棋以及退出。
利用switch()语句,当光标坐标(x,y)中x=0,y=0则画出棋盘的左上角“┏”,y=14则画出棋盘的右上角“┓”,0棋盘上的交点称为位点(包括交叉点,天元,四方星位,边界交点)。
具体实现如以下程序(仅部分主要代码):
voidprintnode(NODEchessboard[][15],intx,inty)//打印棋盘上的一个点
{textcolor(CHESSBOARD);
if(chessboard[x][y].step==0)
{if(x==cursor.x&&y==cursor.y)
textcolor(CURSOR);//如果光标在这个点,改成光标颜色
switch(x)
{case0:
if(y==0)printf("┏");//左上角
elseif(y==14)printf("┓");//右上角
elseprintf("┯");//上边线
break;
case3:
if(y==0)printf("┠");//左边线
elseif(y==3||y==11)printf("+");//星位
elseif(y==14)printf("┨");//右边线
elseprintf("┼");//交叉点
break;
case7:
if(y==0)printf("┠");//左边线
elseif(y==7)printf("+");//星位
elseif(y==14)printf("┨");//右边线
elseprintf("┼");//交叉点
break;
case11:
if(y==0)printf("┠");//左边线
elseif(y==3||y==11)printf("+");//星位
elseif(y==14)printf("┨");//右边线
elseprintf("┼");//交叉点
break;
case14:
if(y==0)printf("┗");//左下角
elseif(y==14)printf("┛");//右下角
elseprintf("┷");//下边线
break;
default:
if(y==0)printf("┠");//左边线
elseif(y==14)printf("┨");//右边线
elseprintf("┼");//交叉点
}}
}
voidprintchessboard(NODEchessboard[][15])
{//输出整个棋盘
inti,j;
charletter[]={"ABCDEFGHIJKLMNO\n"};
for(i=0;i<15;i++)
{//行
textcolor(TEXTS);//改为文本颜色
printf("%2d",15-i);//打印行坐标
for(j=0;j<15;j++)//列
printnode(chessboard,i,j);//打印棋盘的每一块
textcolor(TEXTS);
printf("\n");}
textcolor(TEXTS);//改为文本颜色
printf("%s",letter);//打印列坐标
printf("移动:
方向键下棋:
ENTER\n悔棋:
U退出:
F12\n");
}
图5.1人机对战玩家先手初始界面
图5.2人机对战电脑先手初始界面
双人对战模式游戏的初始界面与人机对战电脑先手初始界面一样。
5.2画出棋子
本模块是在画出棋盘的基础下实现的,要求依次轮流画出黑白两种颜色的棋子,且位置必须在棋盘的位点之上,并且要求必须先画黑棋,位置为棋盘的天元位。
根据棋盘上光标所在位置来下棋,如果当前光标所在位置上有棋子,则不能在此处落子,则需按下键盘上的方向键来移动光标到没有棋子,且有利于局势的位置按下Enter(回车键)落子[7]。
具体实现如以下程序(仅部分主要代码):
elseif(chessboard[x][y].color==0)
{//如果是白棋
if(x==cursor.x&&y==cursor.y)
textcolor(SELECTEDWHITE);//被选中的白棋
elsetextcolor(WHITECHESS);//未被选中的黑棋
printf("●");
}//打印棋子
else
{if(x==cursor.x&&y==cursor.y)
textcolor(SELECTEDBLACK);//被选中的黑棋
elsetextcolor(BLACKCHESS);//未被选中的黑棋
printf("●");}//打印棋子
光标的移动(实现在棋盘上任意位置落子):
boolgetmove(NODEchessboard[][15])
{//获取光标移动,并响应
//当按下悔棋、下子、退出热键时,返回true
charc;for(;;)
{c=getch();
if(c==-32)
switch(getch())
{
case72:
//上
cursor.x--;
if(cursor.x<0)cursor.x=0;
renew(chessboard,cursor.x+1,cursor.y);
renew(chessboard,cursor.x,cursor.y);break;
case80:
//下
cursor.x++;
if(cursor.x>14)cursor.x=14;
renew(chessboard,cursor.x-1,cursor.y);
renew(chessboard,cursor.x,cursor.y);break;
case75:
//左
cursor.y--;
if(cursor.y<0)cursor.y=0;
renew(chessboard,cursor.x,cursor.y+1);
renew(chessboard,cursor.x,cursor.y);b