1、基于java语言的中国象棋设计与实现题目:基于JAVA语言的中国象棋设计与实现毕业设计(论文)原创性声明和使用授权说明原创性声明本人郑重承诺:所呈交的毕业设计(论文),是我个人在指导教师的指导下进行的研究工作及取得的成果。尽我所知,除文中特别加以标注和致谢的地方外,不包含其他人或组织已经发表或公布过的研究成果,也不包含我为获得 及其它教育机构的学位或学历而使用过的材料。对本研究提供过帮助和做出过贡献的个人或集体,均已在文中作了明确的说明并表示了谢意。作 者 签 名: 日 期: 指导教师签名: 日期: 使用授权说明本人完全了解 大学关于收集、保存、使用毕业设计(论文)的规定,即:按照学校要求提交
2、毕业设计(论文)的印刷本和电子版本;学校有权保存毕业设计(论文)的印刷本和电子版,并提供目录检索与阅览服务;学校可以采用影印、缩印、数字化或其它复制手段保存论文;在不以赢利为目的前提下,学校可以公布论文的部分或全部内容。作者签名: 日 期: 【摘要】电脑在中国象棋上的运用还刚刚起步,尽管国内涌现出一大批中国象棋的专业网站和专业软件,但是由于缺乏必要的基础工作,电脑技术在中国象棋上的应用优势还无法体现出来,随着人工智能及计算机硬件的发展,计算机象棋程序的水平也不断地得到提高。本文通过研究中国象棋的国内外研究现状、分析中国象棋的需求和用JAVA语言设计中国象棋程序的可行性,同时根据国际象棋程序设计
3、的一些成功经验,主要借鉴了位棋盘、Zobrist键值等,针对中国象棋程序设计的一系列问题,总结出一些中国象棋程序的设计方法。根据该方法设计出了符合中国象棋行棋和吃子规则,能够判断胜负,能够实现悔棋、重新开始等多种功能,而且界面十分美观的中国象棋程序,并给出了JAVA语言的实现方法。关 键 词:中国象棋,位棋盘,Zobrist键值,着发生成【Abstract】The implement of playing Chinese Chess on computer has just started. Although large numbers of professional websites and
4、 professional chess software arised in domestic, the lack of necessary basic work causes the advantage of computer technology applications in Chinese chess cant be reflected. With the development of artificial intelligence and computer hardware, the level of computer chess program continues to be im
5、proved.This paper studies the research status of Chinese chess, analyzes the demand of Chinese chess, and learns the feasibility of Chinese chess that is designed by Java language. At the same time, the function is designed with the successful experience of chess program, such as the place board, Zo
6、brist keys, etc. Chinese chess program is summarized some ways to design Chinese chess program for solve a range of issues. Follow this ways, it designs all the rules and funtions which adapt to the requirement of Chinese chess, including of movement, judgement, undo, re-start and so on.The applicat
7、ion gives the implementation method in JAVA language and beautiful interface. Keywords: Chinese Chess, bit board, zobrist keys1绪论1.1研究背景计算机现在已经成为每天工作和生活必不可少的一部分,电子游戏在计算机产业的带动下也逐步深入我们每个人的娱乐活动中,棋牌游戏作为休闲类电子游戏,相对于角色扮演类游戏和即时战略类游戏等其它游戏,具有上手快、游戏时间短的特点,更利于用户进行放松休闲,为人们所喜爱,特别是棋类游戏,方便、快捷、操作简单,在休闲娱乐中占主要位置。棋类运动的
8、推广和发展是需要靠信息技术来推动的,时下盛行的国际象棋有两个很好的范例,一个是象棋棋谱编辑和对弈程序的公共平台WinBoard平台,另一个是商业的国际象棋数据库和对弈软件ChessBase,他们为国际象棋爱好者和研究者提供了极大的便利,也极大的促进了国际象棋的发展。国际象棋软件有着成功的商业运作,已发展成一种产业。在设计中国象棋软件过程中,国际象棋软件有很多值得借鉴的成功经验和优秀的思想。1.2研究意义我国现在正处于飞速发展的阶段,想要提高我国的国际地位、让世界更好的了解我国,不仅要依靠经济和政治的影响,更要注重文化传播的作用。中国象棋是我国起源最早(最早出现于战国时期)、也是我国保存最为完整
9、的棋类运动之一,他的行棋规则和棋子、棋盘的设计都蕴函着丰富的中国文化。中国象棋的艺术和棋理折射着以儒家思想为正统的东方民族文化精神,深为我国各阶层人民喜爱。但是中国象棋在国际上的普及率仍然很低,并因此未被入选2010年广州亚运会的竞赛项目。想要提高中国象棋的知名度和普及率,就必须要有一个大众化的中国象棋游戏平台,电脑游戏无疑是最佳选择。然而,电脑在中国象棋上的运用还刚刚起步,尽管国内涌现出一大批中国象棋的专业网站和专业软件,但是由于缺乏必要的基础工作,电脑技术在中国象棋上的应用优势还无法体现出来。因此,我们迫切的需要一个更加基础、更加实用的中国象棋对战平台。1.3预期目标首先进行理论的研究,研
10、究JAVA编程的基础,包括JAVA编成的主要步骤及所需要的工具和软件,熟悉编程软件后,开始着手进行研究,设计出论文的主要框架和具体实现的步骤、目标。其次具体的实现。设计出一个基于JAVA语言的中国象棋对战平台,由于中国象棋比较复杂,所以主要设计出一个人、人对战的平台,这个平台必须符合中国象棋规则(包括胜负、走棋、悔棋、吃子、判断胜负等主要功能,各棋子按象棋规则走动),如果时间允许,可进一步实现一些附加功能,包括美观的界面、对战双方交流、添加背景音乐等。最后,依据框架和目标编写代码,实现主要功能并且进行测试,直至程序运行成功。最终在深入研究理论的基础上,实现基于JAVA语言设计的中国象棋,做出预
11、期的完整游戏。2分析2.1需求分析现在全球超过十亿台计算机正在被使用,并且这个数目还在逐渐增加,计算机已经深入到我们生活的各个方面。而我们使用计算机时,游戏所占的比重很大。棋类游戏作为一种简单易学的休闲游戏,一直深受广大群众的喜爱。JAVA作为一种程序编写的语言,在软件市场的影响力快速提高,潜力巨大。因此用JAVA编写的中国象棋游戏有着很大的开发潜力。与网络游戏相比,单机游戏有着不可匹敌的简约性。人们可以随心所欲的选择任何时间进行游戏,而且人人对战还可以实现对战双方的直接交流,尤其随着笔记本电脑的普及,基本上可以随时随地都把它们带在身边,在人们离开家或者想玩的时候,可以不受任何时间地点限制地玩
12、自己选择的游戏。2.2可行性分析随着计算机的普及和应用,电子游戏已经深入到我们生活的各个方面,利用电子游戏推广我国文化、增加我国传统游戏的市场占有率,是将我国文化推向世界的比较便捷的一种方式。中国象棋作为我国保存最完整、最能代表我国古代文化的游戏之一,它的推广能够让世界更加了解中国。JAVA与C+语言非常相近,但JAVA比C+简单,它抛弃了C+中的一些非必要的功能。用JAVA编写的中国象棋程序实现了人与人的对弈,符合中国象棋的行棋规则,界面美观,能够激起玩家的兴趣,同时单机游戏对计算机的环境要求十分简单、易于实现。2.3功能分析打开游戏,鼠标所在的功能键会突出显示,点开新游戏后,原本的“欢迎使
13、用象棋对弈系统”会变成提示“红棋走棋”或“黑棋走棋”。单击选中的棋子时,该棋子会不停闪烁,如果符合规则,则可以移动到指定位置。在进行人与人之间对战时,按照红先黑后的顺序进行,并把下棋的每一步过程记录下来,在对战时能进行悔棋功能,对悔棋次数没有限定,玩家可以再玩之前自己约定,增加了游戏的灵活性。在行棋时依照“马走日,象走田,车、炮走直线、士在框内走斜线,卒未过河是上下走、过河可左右行走且不能回头,将、帅只能在框内行走”等行走规则,且按照“炮必须隔一个棋子才能吃棋子,其他棋子按棋子行走规则的位置实现吃子”的规则,完全符合象棋的行棋规则。2.4硬件环境2.4.1开发环境1、硬件环境CPU:AMD T
14、urion(tm)64*2 1.80GH内存:DDR 1.5G 硬盘:80G2、软件环境操作系统:WINDOWS XP开发语言:JAVA2.4.2运行环境1、32M以上内存,4G以上硬盘。2、Microsoft Windows 9X/NT/vista操作系统。3、800*600或以上的屏幕分辨率。3界面设计框架3.1程序的框架从程序的结构上讲,大体上可以将引擎部分划分为四大块:棋局表示;着法生成;搜索算法;局面评估。程序的大概的思想是:首先使用一个数据结构来描述棋局信息,对某一特定的棋局信息由着法生成器生成当前下棋方所有合法的着法并依次存入着法队列。然后通过搜索算法来逐一读取着法并调用局面评估
15、函数对该着法所产生的后继局面进行评估打分,从中选出一个最有可能导致走棋方取胜的着法。在搜索的过程中还可以采用一些辅助手段来提高搜索的效率。其过程如下所示(图1):图1 着法生成3.2.基本数据结构位棋盘3.2.1 什么是位棋盘在中国象棋中,棋盘有90个交叉点。位棋盘其实就是一个长度为90位的变量,每个位对应一个交叉点,用来记录棋盘上的某些布尔值。在Java中,用3 个int类型数据(每个32位,共96位多余的6位不用)表示一个位棋盘。3.2.2 位棋盘的作用 记录所有棋子位置的位棋盘AllPieces。AllPieces告诉我们棋盘上哪些格子有棋子,哪些没有。当棋子处于最初位置的时候,“All
16、Pieces”看上去是这个样子的(以下描述中,格子的下标从0开始):(Hi,89,a9)111111111 000000000 101010101 000000000 000000000 101010101 000000000 010000010 000000000 111111111(Low,0,i0) 其最高位对应第89格(a9格,左上角),最低位对应第0格(a8格,右下角)。有子的位对应1,没有子的位对应0。这样显示位棋盘可能更形象一点: 黑棋1111111110000000000100000101010101010000000000000000001010101010000000000
17、10000010000000000111111111红棋3.2.3 位棋盘的基本运算 1、与(&) 0 1 0 1 1 0 0 1 0 0 0 1 2、或(|) 0 1 0 1 1 0 0 1 1 1 0 1 3、异或() 0 1 0 1 1 0 0 1 1 1 0 0 4、取补() a = 0001,a = 1110。 3.2.4 Java中位棋盘的实现3.2.4.1 位棋盘类的实现Java中,位棋盘用3个int型的数据表示,最高六位不用。Java中“与、或、非、异或、左位移,右位移(注意,位棋盘的右位移是无符号位移)”分别是“&、|、”。代码摘要(详细代码见附件)及相关说明如下:publi
18、c class BitBoardprivate int Low,Mid,Hi/用3个int字段表示位棋盘,最高位Hi的高/6位不用 public BitBoard(int Arg1, int Arg2, int Arg3) /构造函数 Low = Arg1; Mid = Arg2; Hi = Arg3; public static BitBoard opAnd(BitBoard arg1,BitBoard arg2) /位棋盘的“与”操作,保存结果。 int low=arg1.Low & arg2.Low; int mid=arg1.Mid & arg2.Mid; int hi=arg1.Hi
19、 & arg2.Hi; return new BitBoard(low,mid,hi);public static BitBoard opOr(BitBoard arg1,BitBoard arg2) /位棋盘的“或”操作,保存结果。public static BitBoard opXor(BitBoard arg1,BitBoard arg2) /位棋盘的“异或”操作,保存结果。public static int count(BitBoard arg) /计算位棋盘中非零位的个数 public static BitBoard duplicate(int arg) /复制位棋盘 public
20、static boolean equals(BitBoard arg1,BitBoard arg2) /位棋盘是否相等(所有90位对应的位相同即/为相等) public static BitBoard leftShift(BitBoard arg,int num) /位棋盘arg左位移num位 public static rightShift(BitBoard,int num) /位棋盘右位移num位 public static int LSB(BitBoard Arg) /位棋盘最低非0位的位置(从0开始计数)public static int MSB(BitBoard Arg) /位棋盘最
21、高非0位的位置(从0开始计数)public static boolean notZero(BitBoard Arg) /是否非“0”。当90位中有非0位时返回true。3.2.4.2 位棋盘的初始化某些位棋盘从程序开始运行到结束都不会改变。例如上面所述的那个位棋盘数组“knight90”。(他实际上记录了当“马”在任意格子上时,它下一步可以走的格子。)这个数组将在程序开始执行的时候被初始化并且不再改变。其余的位棋盘将不断变化。例如“AllPieces”位棋盘。当中国象棋棋盘变化时,它也跟着变化。然而,他们的初始化方式相同。对于诸如knight90这样不变化的位棋盘的初始化,将在“伪着法生成”章
22、节详述。此处叙述走棋过程中随棋局变化的诸多位棋盘的初始化及相关操作。首先,初始化“BitBoard bitMask90”数组:BitBoard b = new BitBoard(0,0,1); for (int c = 0; c 90; c +) maskc = BitBoard.leftShift(b,c); 其次,用一个叫 ChessPosition类记录棋盘上某一状态的所有有用信息。它包含了一个整型数组 int piece_in_square90,还包含了一些位棋盘。 public class ChessPosition int piece_in_square90; int player
23、; /轮到哪方走棋,2:红方走,1:黑方走BitBoard allPieces;BitBoard redKing;/红帅BitBoard blackKing;/黑将BitBoard redRooks;/红车BitBoard blackRooks;/黑车BitBoard redKnights;/红马BitBoard blackKnights;/黑马BitBoard redCannon;/红炮BitBoard redCannon;/黑炮BitBoard redBishops;/红相BitBoard blackBishops;/黑象BitBoard redAdvisor;/红仕BitBoard bl
24、ackAdvisor;/黑士BitBoard redPawns;/红兵BitBoard blackPawns;/黑卒BitBoard redPieces;/所有红棋子BitBoard blackPieces;/所有黑棋子;初始化“piece_in_square”数组。 piece_in_square0 = RED_ROOK; piece_in_square1 = RED_KNIGHT;piece_in_square2 = RED_BISHOP; piece_in_square89 = BLACK_ROOK; 现在初始化其他一些位棋盘:for (c = 0; c 90; c +) switch
25、(piece_in_squarec) case : RED_ROOKposition.redPieces = BitBoard.opOr(position.redPieces,bitMaskc); position.redRooksBitBoard.opOr(position.redRooks,bitMaskc);break; 3.2.4.3 位棋盘的更新当棋盘局面变动后,某些位棋盘就需要被更新。例如记录白子所在位置的“WhitePieces”位棋盘。假如我们把h2格的红炮移动到h9格(炮二进七),吃掉黑棋的一个马,需要更新如下位棋盘:allPiecesredPieces redCannons
26、blackpiecesblackKnights首先,要把redPieces,redCannons位棋盘的“h2”位清零,然后把他们的“h9”位置1。/* clear a bit with the XOR operation */ position.allPieces = BitBoard.opXor(position.allPieces,bitMaskh2;position.redPieces = BitBoard.opXor(position.redPieces,bitMaskh2); position.redCannons = BitBoard.opXor(position.redCann
27、ons,bitMaskh2; /* set a bit with the OR operation */ position.redPieces = BitBoard.opOr(position.redPieces,bitMaskh9); position.redCannons = BitBoard.opOr(position.redCannons,bitMaskh9); 现在我们要将blackPieces和blackKnights位棋盘的h9位清除,因为那里的黑马被吃掉了。/* clear the captured piece */ position.blackPieces = BitBoar
28、d.opXor(position.blackPieces,bitMaskh9); position.blackKnight = BitBoard.opXor(position.blackPieces,bitMaskh93.3.基本数据结构Zobrist键值3.3.1 比较局面的方法在写中国象棋程序时,需要比较两个局面看它们是否相同。如果比较每个棋子的位置,或许不需要花很多时间,但是实战中每秒种需要做成千上万次比较,因此这样会使比较操作变成瓶颈的。另外,需要比较的局面数量多得惊人,要存储每个棋子的位置,需要占用非常大的空间。一个解决方案是建立一个标签,通常是64位。由于64位不足以区别每个局面,
29、所以仍然存在冲突的标签,但实战中这种情况非常罕见。3.3.2 Zobrist键值的工作原理3.3.2.1 Zobrist键值的工作原理用Zobrist技术产生的键值,表面上与局面没什么关系。如果一个棋子动过了,就会得到完全不同的键值,所以这两个键值不会挤在一块儿或者冲突。当把它们用作散列表键值的时候会非常有效。 另一个优点在于,键值的产生是可以逐步进行的。例如,红马在e5格,那么键值里一定异或过一个“zobristKNIGHTREDE5”。如果再次异或这个值,那么根据异或的工作原理,这个“马”就从键值里删除了。 这就是说,如果有当前局面的键值,并且需要把红马从e5移到f7,你只要异或一个“红马
30、在e5”的键值,把马从e5格移走,并且异或一个“红马在f7”的键值,把红马放在f7上。比起从头开始一个个棋子去异或,这样做可以得到同样的键值。如果要改变着子的一方,只要异或一个“改变着子方”的键值就可以了。用这种方法,可以在搜索根结点的时候构造一个Zobrist键值,在搜索时通过走子函数“MakeMove()”来更新键值,一直让它保持和当前局面同步。 3.3.3 Zobrist键值的实现方法实现Zobrist必须从多维的64位数组开始,每个数组含有一个随机数。在Java中,“rand.nextLong()”函数返回一个64位的随机数值。这个函数用来填满一个long型(64位)的三维数组:棋子的
31、类型、棋子的颜色和棋子的位置:long zobristpcMAXcoMAXsqMAX; 程序启动时就把这个数组用随机数填满。要为一个局面产生Zobrist键值,首先把键值设成零,然后找棋盘上的每个子,并且让键值跟“zobristpccosq”做异或(通过“”运算符)运算。 如果局面由红方走,那么别去动它,如果是黑方走,你还要在键值上异或一个64位的随机常数。3.3.4 Java中实现Zobrist键值本系统使用一个key和一个lock结合来区分每个局面,这样发生冲突(即两个局面对应的key和lock一样)的概率几乎为0。示例代码及相关说明如下3.3.4.1填充数组上述的三维数组现在改变为二维(将颜色与棋子
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1