基于JAVA语言的中国象棋设计与实现毕业设计_第1页
基于JAVA语言的中国象棋设计与实现毕业设计_第2页
基于JAVA语言的中国象棋设计与实现毕业设计_第3页
基于JAVA语言的中国象棋设计与实现毕业设计_第4页
基于JAVA语言的中国象棋设计与实现毕业设计_第5页
已阅读5页,还剩65页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、题目:基于java语言的中国象棋设计与实现毕业设计(论文)原创性声明和使用授权说明原创性声明本人郑重承诺:所呈交的毕业设计(论文),是我个人在指导教师的指导下进行的研究工作及取得的成果。尽我所知,除文中特别加以标注和致谢的地方外,不包含其他人或组织已经发表或公布过的研究成果,也不包含我为获得 及其它教育机构的学位或学历而使用过的材料。对本研究提供过帮助和做出过贡献的个人或集体,均已在文中作了明确的说明并表示了谢意。作 者 签 名: 日 期: 指导教师签名: 日期: 使用授权说明本人完全了解 大学关于收集、保存、使用毕业设计(论文)的规定,即:按照学校要求提交毕业设计(论文)的印刷本和电子版本;

2、学校有权保存毕业设计(论文)的印刷本和电子版,并提供目录检索与阅览服务;学校可以采用影印、缩印、数字化或其它复制手段保存论文;在不以赢利为目的前提下,学校可以公布论文的部分或全部内容。作者签名: 日 期: 【摘要】电脑在中国象棋上的运用还刚刚起步,尽管国内涌现出一大批中国象棋的专业网站和专业软件,但是由于缺乏必要的基础工作,电脑技术在中国象棋上的应用优势还无法体现出来,随着人工智能及计算机硬件的发展,计算机象棋程序的水平也不断地得到提高。本文通过研究中国象棋的国内外研究现状、分析中国象棋的需求和用java语言设计中国象棋程序的可行性,同时根据国际象棋程序设计的一些成功经验,主要借鉴了位棋盘、z

3、obrist键值等,针对中国象棋程序设计的一系列问题,总结出一些中国象棋程序的设计方法。根据该方法设计出了符合中国象棋行棋和吃子规则,能够判断胜负,能够实现悔棋、重新开始等多种功能,而且界面十分美观的中国象棋程序,并给出了java语言的实现方法。关 键 词:中国象棋,位棋盘,zobrist键值,着发生成【abstract】the implement of playing chinese chess on computer has just started. although large numbers of professional websites and professional ches

4、s 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 improved.this paper

5、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, zobrist keys, etc. c

6、hinese 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 application gives the impl

7、ementation method in java language and beautiful interface. keywords: chinese chess, bit board, zobrist keys目 录1绪论11.1研究背景11.2研究意义11.3预期目标12分析32.1需求分析32.2可行性分析32.3功能分析32.4硬件环境42.4.1开发环境42.4.2运行环境43界面设计框架53.1程序的框架53.2.基本数据结构位棋盘53.2.1 什么是位棋盘53.2.2 位棋盘的作用63.2.3 位棋盘的基本运算63.2.4 java中位棋盘的实现63.3.基本数据结构zobr

8、ist键值93.3.1 比较局面的方法93.3.2 zobrist键值的工作原理93.3.3 zobrist键值的实现方法103.3.4 java中实现zobrist键值104系统实现124.1着法生成124.1.1伪合法着法的生成124.1.2 合法着法的生成174.2算法实现204.2.1 行棋规则算法实现204.2.2界面功能算法实现235结论26参考文献27附录28附录1算法主程序28附录2程序截图53外文文献与翻译54致 谢631绪论1.1研究背景计算机现在已经成为每天工作和生活必不可少的一部分,电子游戏在计算机产业的带动下也逐步深入我们每个人的娱乐活动中,棋牌游戏作为休闲类电子游戏

9、,相对于角色扮演类游戏和即时战略类游戏等其它游戏,具有上手快、游戏时间短的特点,更利于用户进行放松休闲,为人们所喜爱,特别是棋类游戏,方便、快捷、操作简单,在休闲娱乐中占主要位置。棋类运动的推广和发展是需要靠信息技术来推动的,时下盛行的国际象棋有两个很好的范例,一个是象棋棋谱编辑和对弈程序的公共平台winboard平台,另一个是商业的国际象棋数据库和对弈软件chessbase,他们为国际象棋爱好者和研究者提供了极大的便利,也极大的促进了国际象棋的发展。国际象棋软件有着成功的商业运作,已发展成一种产业。在设计中国象棋软件过程中,国际象棋软件有很多值得借鉴的成功经验和优秀的思想。1.2研究意义我国

10、现在正处于飞速发展的阶段,想要提高我国的国际地位、让世界更好的了解我国,不仅要依靠经济和政治的影响,更要注重文化传播的作用。中国象棋是我国起源最早(最早出现于战国时期)、也是我国保存最为完整的棋类运动之一,他的行棋规则和棋子、棋盘的设计都蕴函着丰富的中国文化。中国象棋的艺术和棋理折射着以儒家思想为正统的东方民族文化精神,深为我国各阶层人民喜爱。但是中国象棋在国际上的普及率仍然很低,并因此未被入选2010年广州亚运会的竞赛项目。想要提高中国象棋的知名度和普及率,就必须要有一个大众化的中国象棋游戏平台,电脑游戏无疑是最佳选择。然而,电脑在中国象棋上的运用还刚刚起步,尽管国内涌现出一大批中国象棋的专

11、业网站和专业软件,但是由于缺乏必要的基础工作,电脑技术在中国象棋上的应用优势还无法体现出来。因此,我们迫切的需要一个更加基础、更加实用的中国象棋对战平台。1.3预期目标首先进行理论的研究,研究java编程的基础,包括java编成的主要步骤及所需要的工具和软件,熟悉编程软件后,开始着手进行研究,设计出论文的主要框架和具体实现的步骤、目标。其次具体的实现。设计出一个基于java语言的中国象棋对战平台,由于中国象棋比较复杂,所以主要设计出一个人、人对战的平台,这个平台必须符合中国象棋规则(包括胜负、走棋、悔棋、吃子、判断胜负等主要功能,各棋子按象棋规则走动),如果时间允许,可进一步实现一些附加功能,

12、包括美观的界面、对战双方交流、添加背景音乐等。最后,依据框架和目标编写代码,实现主要功能并且进行测试,直至程序运行成功。最终在深入研究理论的基础上,实现基于java语言设计的中国象棋,做出预期的完整游戏。2分析2.1需求分析现在全球超过十亿台计算机正在被使用,并且这个数目还在逐渐增加,计算机已经深入到我们生活的各个方面。而我们使用计算机时,游戏所占的比重很大。棋类游戏作为一种简单易学的休闲游戏,一直深受广大群众的喜爱。java作为一种程序编写的语言,在软件市场的影响力快速提高,潜力巨大。因此用java编写的中国象棋游戏有着很大的开发潜力。与网络游戏相比,单机游戏有着不可匹敌的简约性。人们可以随

13、心所欲的选择任何时间进行游戏,而且人人对战还可以实现对战双方的直接交流,尤其随着笔记本电脑的普及,基本上可以随时随地都把它们带在身边,在人们离开家或者想玩的时候,可以不受任何时间地点限制地玩自己选择的游戏。2.2可行性分析随着计算机的普及和应用,电子游戏已经深入到我们生活的各个方面,利用电子游戏推广我国文化、增加我国传统游戏的市场占有率,是将我国文化推向世界的比较便捷的一种方式。中国象棋作为我国保存最完整、最能代表我国古代文化的游戏之一,它的推广能够让世界更加了解中国。java与c+语言非常相近,但java比c+简单,它抛弃了c+中的一些非必要的功能。用java编写的中国象棋程序实现了人与人的

14、对弈,符合中国象棋的行棋规则,界面美观,能够激起玩家的兴趣,同时单机游戏对计算机的环境要求十分简单、易于实现。2.3功能分析打开游戏,鼠标所在的功能键会突出显示,点开新游戏后,原本的“欢迎使用象棋对弈系统”会变成提示“红棋走棋”或“黑棋走棋”。单击选中的棋子时,该棋子会不停闪烁,如果符合规则,则可以移动到指定位置。在进行人与人之间对战时,按照红先黑后的顺序进行,并把下棋的每一步过程记录下来,在对战时能进行悔棋功能,对悔棋次数没有限定,玩家可以再玩之前自己约定,增加了游戏的灵活性。在行棋时依照“马走日,象走田,车、炮走直线、士在框内走斜线,卒未过河是上下走、过河可左右行走且不能回头,将、帅只能在

15、框内行走”等行走规则,且按照“炮必须隔一个棋子才能吃棋子,其他棋子按棋子行走规则的位置实现吃子”的规则,完全符合象棋的行棋规则。2.4硬件环境2.4.1开发环境1、硬件环境cpu:amd turion(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程序的框架从程序的结构上讲,大体上可以将引擎部分划分为四大块:棋局表示;着法生成;搜索算法;

16、局面评估。程序的大概的思想是:首先使用一个数据结构来描述棋局信息,对某一特定的棋局信息由着法生成器生成当前下棋方所有合法的着法并依次存入着法队列。然后通过搜索算法来逐一读取着法并调用局面评估函数对该着法所产生的后继局面进行评估打分,从中选出一个最有可能导致走棋方取胜的着法。在搜索的过程中还可以采用一些辅助手段来提高搜索的效率。其过程如下所示(图1):图1 着法生成3.2.基本数据结构位棋盘3.2.1 什么是位棋盘在中国象棋中,棋盘有90个交叉点。位棋盘其实就是一个长度为90位的变量,每个位对应一个交叉点,用来记录棋盘上的某些布尔值。在java中,用3 个int类型数据(每个32位,共96位多余

17、的6位不用)表示一个位棋盘。3.2.2 位棋盘的作用 记录所有棋子位置的位棋盘allpieces。allpieces告诉我们棋盘上哪些格子有棋子,哪些没有。当棋子处于最初位置的时候,“allpieces”看上去是这个样子的(以下描述中,格子的下标从0开始):(hi,89,a9)111111111 000000000 101010101 000000000 000000000 101010101 000000000 010000010 000000000 111111111(low,0,i0) 其最高位对应第89格(a9格,左上角),最低位对应第0格(a8格,右下角)。有子的位对应1,没有子的位

18、对应0。这样显示位棋盘可能更形象一点: 黑棋111111111000000000010000010101010101000000000000000000101010101000000000010000010000000000111111111红棋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

19、个int型的数据表示,最高六位不用。java中“与、或、非、异或、左位移,右位移(注意,位棋盘的右位移是无符号位移)”分别是“&、|、”。代码摘要(详细代码见附件)及相关说明如下:public 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)

20、 /位棋盘的“与”操作,保存结果。int low=arg1.low & arg2.low;int mid=arg1.mid & arg2.mid;int hi=arg1.hi & 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 coun

21、t(bitboard arg) /计算位棋盘中非零位的个数 public static bitboard duplicate(int arg) /复制位棋盘 public 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 stat

22、ic int lsb(bitboard arg) /位棋盘最低非0位的位置(从0开始计数)public static int msb(bitboard arg) /位棋盘最高非0位的位置(从0开始计数)public static boolean notzero(bitboard arg) /是否非“0”。当90位中有非0位时返回true。3.2.4.2 位棋盘的初始化某些位棋盘从程序开始运行到结束都不会改变。例如上面所述的那个位棋盘数组“knight90”。(他实际上记录了当“马”在任意格子上时,它下一步可以走的格子。)这个数组将在程序开始执行的时候被初始化并且不再改变。其余的位棋盘将不断变化

23、。例如“allpieces”位棋盘。当中国象棋棋盘变化时,它也跟着变化。然而,他们的初始化方式相同。对于诸如knight90这样不变化的位棋盘的初始化,将在“伪着法生成”章节详述。此处叙述走棋过程中随棋局变化的诸多位棋盘的初始化及相关操作。首先,初始化“bitboard bitmask90”数组:bitboard b = new bitboard(0,0,1); for (int c = 0; c 90; c +) maskc = bitboard.leftshift(b,c); 其次,用一个叫 chessposition类记录棋盘上某一状态的所有有用信息。它包含了一个整型数组 int pie

24、ce_in_square90,还包含了一些位棋盘。 public class chessposition int piece_in_square90; int player; /轮到哪方走棋,2:红方走,1:黑方走bitboard allpieces;bitboard redking;/红帅bitboard blackking;/黑将bitboard redrooks;/红车bitboard blackrooks;/黑车bitboard redknights;/红马bitboard blackknights;/黑马bitboard redcannon;/红炮bitboard redcannon

25、;/黑炮bitboard redbishops;/红相bitboard blackbishops;/黑象bitboard redadvisor;/红仕bitboard blackadvisor;/黑士bitboard redpawns;/红兵bitboard blackpawns;/黑卒bitboard redpieces;/所有红棋子bitboard blackpieces;/所有黑棋子;初始化“piece_in_square”数组。 piece_in_square0 = red_rook; piece_in_square1 = red_knight;piece_in_square2 = r

26、ed_bishop; piece_in_square89 = black_rook; 现在初始化其他一些位棋盘:for (c = 0; c 90; c +) switch (piece_in_squarec) case : red_rookposition.redpieces = bitboard.opor(position.redpieces,bitmaskc); position.redrooksbitboard.opor(position.redrooks,bitmaskc);break; 3.2.4.3 位棋盘的更新当棋盘局面变动后,某些位棋盘就需要被更新。例如记录白子所在位置的“wh

27、itepieces”位棋盘。假如我们把h2格的红炮移动到h9格(炮二进七),吃掉黑棋的一个马,需要更新如下位棋盘:allpiecesredpieces redcannonsblackpiecesblackknights首先,要把redpieces,redcannons位棋盘的“h2”位清零,然后把他们的“h9”位置1。/* clear a bit with the xor operation */ position.allpieces = bitboard.opxor(position.allpieces,bitmaskh2;position.redpieces = bitboard.opxo

28、r(position.redpieces,bitmaskh2); position.redcannons = bitboard.opxor(position.redcannons,bitmaskh2; /* set a bit with the or operation */ position.redpieces = bitboard.opor(position.redpieces,bitmaskh9); position.redcannons = bitboard.opor(position.redcannons,bitmaskh9); 现在我们要将blackpieces和blackknig

29、hts位棋盘的h9位清除,因为那里的黑马被吃掉了。/* clear the captured piece */ position.blackpieces = bitboard.opxor(position.blackpieces,bitmaskh9); position.blackknight = bitboard.opxor(position.blackpieces,bitmaskh93.3.基本数据结构zobrist键值3.3.1 比较局面的方法在写中国象棋程序时,需要比较两个局面看它们是否相同。如果比较每个棋子的位置,或许不需要花很多时间,但是实战中每秒种需要做成千上万次比较,因此这样会

30、使比较操作变成瓶颈的。另外,需要比较的局面数量多得惊人,要存储每个棋子的位置,需要占用非常大的空间。一个解决方案是建立一个标签,通常是64位。由于64位不足以区别每个局面,所以仍然存在冲突的标签,但实战中这种情况非常罕见。3.3.2 zobrist键值的工作原理3.3.2.1 zobrist键值的工作原理用zobrist技术产生的键值,表面上与局面没什么关系。如果一个棋子动过了,就会得到完全不同的键值,所以这两个键值不会挤在一块儿或者冲突。当把它们用作散列表键值的时候会非常有效。 另一个优点在于,键值的产生是可以逐步进行的。例如,红马在e5格,那么键值里一定异或过一个“zobristknigh

31、trede5”。如果再次异或这个值,那么根据异或的工作原理,这个“马”就从键值里删除了。 这就是说,如果有当前局面的键值,并且需要把红马从e5移到f7,你只要异或一个“红马在e5”的键值,把马从e5格移走,并且异或一个“红马在f7”的键值,把红马放在f7上。比起从头开始一个个棋子去异或,这样做可以得到同样的键值。如果要改变着子的一方,只要异或一个“改变着子方”的键值就可以了。用这种方法,可以在搜索根结点的时候构造一个zobrist键值,在搜索时通过走子函数“makemove()”来更新键值,一直让它保持和当前局面同步。 3.3.3 zobrist键值的实现方法实现zobrist必须从多维的64

32、位数组开始,每个数组含有一个随机数。在java中,“rand.nextlong()”函数返回一个64位的随机数值。这个函数用来填满一个long型(64位)的三维数组:棋子的类型、棋子的颜色和棋子的位置:long zobristpcmaxcomaxsqmax; 程序启动时就把这个数组用随机数填满。要为一个局面产生zobrist键值,首先把键值设成零,然后找棋盘上的每个子,并且让键值跟“zobristpccosq”做异或(通过“”运算符)运算。 如果局面由红方走,那么别去动它,如果是黑方走,你还要在键值上异或一个64位的随机常数。3.3.4 java中实现zobrist键值本系统使用一个key和一

33、个lock结合来区分每个局面,这样发生冲突(即两个局面对应的key和lock一样)的概率几乎为0。示例代码及相关说明如下3.3.4.1填充数组上述的三维数组现在改变为二维(将颜色与棋子兵种类型合并)public static long zobristkeyplayer;/改变走子方的keypublic static long zobristlockplayer;/改变走子方的lockpublic static long zobristkeytable = new long1490;public static long zobristlocktable = new long1490;static

34、zobristgen();public static void zobristgen() int i, j;random rand = new random();long randseed;randseed = 1;rand.setseed(randseed);zobristkeyplayer = rand.nextlong();for (i = 0; i 14; i +) /0:红帅1:红仕2:红相3:红马4:红车5:红炮6:红兵/7:黑将8:黑士9:黑象10:黑马11:黑车12:黑炮13:黑卒for (j = 0; j 90; j +) zobristkeytableij = rand.n

35、extlong();zobristlockplayer = rand.nextlong();for (i = 0; i 14; i +) for (j = 0; j 90; j +) zobristlocktableij = rand.nextlong();3.3.4.2移子函数当移动(添加、删除)一个棋子时,将当前局面的zobrist键值与键值表中该棋子的键值进行异或操作,同时也与改变走子方的键值进行异或操作。public class chesspositionlong zobristkey, zobristlock;/当前局面的zobrist键值public chesspositionzo

36、bristkey=0;/初始化为0zobristlock=0;public void makemove(int square, int piece, boolean isadd) zobristkey=zobristkeytablepiecetypesquare;zobristlock=zobristlocktablepiecetypesquare;zobristkey = zobristkeyplayer;/改变走子方zobristlock = zobristlockplayer;4系统实现4.1着法生成着法生成在不同的象棋引擎中差异较大。我选择使用位棋盘生成着法的基本原理。之所以用这种方式

37、生成着法,是因为生成着法耗费一定的时间。如果引擎在检查了一部分着法后发现了必须走的棋,那它就无需生成余下的棋步了。因此,可能先生成所有吃子的着法,如果没有满意的棋再生成余下的着法。国际象棋引擎crafty(其作者是robert hyatt博士)使用三个着法生成函数。一个用来生成所有伪合法吃子着法,一个生成所有伪合法不吃子着法,最后一个生成所有摆脱被将军状态的着法。注意前两个函数生成的是伪合法的着法。中国象棋的着法生成与此类似,先生成所有伪合法的着法,存入静态数组中。在对局中可以用“查表”的方式查找生成的伪着法,并对其合法性作出判断。这样可以节省大量的时间。4.1.1伪合法着法的生成4.1.1.

38、1伪合法着法包含几类:1、各兵种的不吃子着法;2、各兵种的吃子着法;3、“将”和摆脱“将”的着法。其中,马、相(象)、兵、帅(将)、仕(士)的吃子着法与其对应的不吃子着法规则相同。(伪合法着法并不考虑被吃的棋子的颜色该棋子是对方的棋子还是己方的棋子,也不考虑该子是否能动,例如动了该子,双方的帅将会面。)炮和车的不吃子着法规则相同,但分为纵向横向行走两类。炮的吃子着法分为纵向和横向两类,车的吃子着法也分为纵向和横向两类。马和象的着法要考虑蹩马腿和塞象眼。将军的着法单独作为一类。本程序使用静态数组存储生成的伪合法着法,先对其作一些说明。4.1.1.2数组及其下标的含义:1、保存帅(将)、仕(士)、

39、相(相)、马、兵的伪合法静态数组如下:public static final int kingmoves=new int908;public static final int advisormoves=new int908;public static final int bishopmoves=new int908;public static final int elephanteyes=new int904;public static final int knightmoves=new int9012;public static final int horselegs=new int908;

40、public static final int pawnmoves=new int9024;第一个下标说明棋子所在的格,第二个下标含义不尽相同。帅(将)在某个位置最多有4种走法,例如kingmoves130=12表示帅在13格(e1格)时可以走到12格(当然,也可以走到14、4、22格,保存到其他几个数组元素中)。第5种(如果前面只有3种着法,则此处是第4种)保存的是非法着法即kingmoves134=-1,其作用作为查询算法的“哨兵”,提高查询算法的速度。为了速度(以位移运算取代除法运算),第2个坐标值用2的整次方幂。(在后面所讲的开局库和置换表的大小设置是2的整次方幂也是这个道理。)兵的走

41、棋规则需要分颜色,红色的垂直走棋方向和黑色的垂直走棋方向是相反的。兵最多有三种走棋方法。advisormoves908保存的是士的着法。bishopmoves908保存的是相(象)的着法,elephaneyes904保存的是相(象)着法对应的塞象眼的位置。knightmoves和horselegs是马的着法和蹩马腿的位置。2、车、炮的伪合法着法静态数组如下:public static final int filenoncapmoves=new int10102412;/共十条横线,filenoncapmovesybitwordyindex=newy,进 public static final

42、int filerookcapmoves=new int1010244;public static final int filecannoncapmoves=new int1010244;public static final int ranknoncapmoves=new int951212;/ranknoncapmovesxbitwordxindex=newx,平public static final int rankrookcapmoves=new int95124;public static final int rankcannoncapmoves=new int95124;publi

43、c static final int filenoncapmax=new int101024;/filenoncapmaxybitwordy=maxy/进退public static final int filenoncapmin=new int101024;/filenoncapmaxybitwordy=minypublic static final int filerookcapmax=new int101024;public static final int filerookcapmin=new int101024;public static final int filecannonca

44、pmax=new int101024;public static final int filecannoncapmin=new int101024;public static final int ranknoncapmax=new int9512;/平public static final int ranknoncapmin=new int9512;public static final int rankrookcapmax=new int9512;public static final int rankrookcapmin=new int9512;public static final in

45、t rankcannoncapmax=new int9512;public static final int rankcannoncapmin=new int9512;车、炮吃子着法与它们的不吃子着法规则不同,因此需要分开保存。再将着法分为水平和垂直两种(也就是进、退与平)。车炮的不吃子着法是相同的,因此,分别保存到filenoncapmoves10102412和ranknoncapmoves951212中。棋盘的横线合纵线分别有10条和9条,这就是数组第一个下标10和9的含义,用来指示车炮在哪条横线或纵线上。第二个坐标的含义,以横线走法示例如下:例如,第二条横线上的棋子如下(有棋子的用1表示

46、,炮或车的位置用x表示,实际上x也是1):001100x01那么,ranknoncapmoves21010=-1ranknoncapmoves21011=1ranknoncapmoves21012=2ranknoncapmoves21013=0上面的下标101就是001100101对应的二进制值,数组元素的值-1、1、2表示可行走格子的增量。rankrookcapmoves21010=-2rankrookcapmoves21011=3rankrookcapmoves21012=0以上是车吃子的走法。下面是炮吃子的着法:rankcannoncapmoves21010=-2rankcannonca

47、pmoves21011=4rankcannoncapmoves21012=0;下面是最大的位移量和最小的位移量,用来生成合法着法时初步判断着法的合法性:ranknoncapmax2101=2 /不吃子着法中最大的格子增量ranknoncapmin2101=-1 /不吃子着法中最小的格子增量rankrookcapmax2101=3/车吃子着法中最大的格子增量rankrookcapmin2101=-2/车吃子着法中最小的格子增量rankcannoncapmax2101=4/炮吃子着法中最大的格子增量rankcannoncapmin2101=-2/炮吃子着法中最小的格子增量以上是横向(平)着法的静态

48、数组,纵向着法的表示与此类似,在此不再赘述。3、“照将”着法public static final bitboard checklegs=new bitboard18;/帅将每个位置蹩马腿的位棋盘public static final bitboard knightpincheck=new bitboard18256;/除去蹩腿位置有子的将军位置public static final bitboard filerookcheck=new bitboard181024;/车纵线照将public static final bitboard filecannoncheck=new bitboard1

49、81024;/炮纵线照将public static final bitboard rankrookcheck=new bitboard18512;/车横线照将public static final bitboard rankcannoncheck=new bitboard18512;/炮纵线照将public static final bitboard pawncheck=new bitboard18;/兵照将帅、将的位置共有18个,每个位置有一个编号,从0到17,对应数组的第一个下标。knightpincheck是马“照将”的着法,checklegs是马“照将”蹩马腿的位棋盘。算法示例车炮的伪合法着法生成:以下是车炮横线纵移(横线定位,纵向移动)的算法:/ generate filepremove for rooks and cannonsfor (i = 0; i 10; i +) /10条横线for (j = 0; j 1024; j +) /一条纵线位棋盘的二进制值index = 0;/着法种类下标filenoncapmaxij = i;for (k = i + 1; k = 9; k +) if (j & (1 = 0; k -) if (j & (1 k)!=0) break;filenoncapmovesijindex =

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论