《中国象棋算法设计22914.pdf》由会员分享,可在线阅读,更多相关《中国象棋算法设计22914.pdf(20页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、-1-正文 1、课程设计报告 1.1 问题描述 象棋是一种双方对阵的竞技项目。棋子共有三十二个,分为红黑两组,各有十六个,由对弈的双方各执一组。兵种是一样的,分为七种:红方:红方有帅一个,仕、相、车、马、炮各两个,兵五个。黑方:黑方有将一个,士、象、车、马、炮各两个,卒五个。其中帅与将;仕与士;相与象;兵与卒的作用完全相同,仅仅是为了区别红棋和黑棋而已。棋子活动的场所,叫作棋盘。在长方形的平面上,绘有九条平行的竖线和十条平行的横线相交组成,共有九十个交叉点,棋子就摆在交叉点上。中间部分,也就是棋盘的第五,第六两横线之间末画竖线的空白地带称为“河界”。两端的中间,也就是两端第四条到第六条竖线之间
2、的正方形部位,以斜交叉线构成“米”字方格的地方,叫作“九宫”(它恰好有九个交叉点)。整个棋盘以“河界”分为相等的两部分。为了比赛记录和学习棋谱方便起见,现行规则规定:按九条竖线从右至左用中文数字一-九来表示红方的每条竖线,用阿拉伯数字19来表示黑方的每条竖线。对弈开始之前,红黑双方应该把棋子摆放在规定的位置。任何棋子每 走一步,进就写“进”,退就写“退”,如果像车一样横着走,就写“平”。-2-任何棋子在走动时,如果乙方棋子可以到达的位置有对方的棋子,就可以把对方棋子拿出棋盘(称为吃子)而换上自己的棋子。只有炮的吃子方式与它的走法不同:它和对方棋子之间必须隔一个子(无论是自己的还是对方的),具备
3、此条件才能吃掉人家。一定要注意,中隔一个棋子,这个棋子俗称“炮架子”。帅和将被吃或不能动弹即输棋。下面是具体的界面:1.2 需求分析 1、走棋和吃子 对局时,由执红棋的一方先走,双方轮流各走一着,直至分出胜、负、和,对局即终了。轮到走棋的一方,将某个棋子从一个交叉点走到另一个交叉点,或者吃掉对方的棋子而占领其交叉点,都算走一着。双方各走一着,称为一个回合。2、各种棋子的走法 帅(将):帅和将是棋中的首脑,是双方竭力争夺的目标。它只能在九宫之内活动,可上可下,可左可右,每次走动只能按竖线或横 -3-线走动一格。帅与将不能在同一直线上直接对面,否则走方判负。仕(士):仕(士)是帅(将)的贴身保镖,
4、它也只能在九宫内走动。它的行棋路径只能是九宫内的斜线。相(象):相(象)的主要作用是防守,保护自己的帅(将)。它的走法是每次循对角线走两格,俗称象走田。相(象)的活动范围限于河界以内的本方阵地,不能过河,且如果它走的田字中央有一个棋子,就不能走,俗称塞象眼。车:车在象棋中威力最大,无论横线、竖线均可行走,只要无子阻拦,步数不受限制。因此,一车可以控制十七个点,故有一车十子寒之称。炮:炮在不吃子的时候,走动与车完全相同。炮与被吃子之间必须隔一个棋子,进行跳吃,俗称架炮或炮打隔子。马:马走动的方法是一直一斜,即先横着或直着走一格,然后再斜着走一个对角线,俗称马走日。马一次可走的选择点可以达到四周的
5、八个点,故有八面威风之说。如果在要去的方向有别的棋子挡住,马就无法走过去,俗称蹩马腿。兵(卒):兵(卒)在未过河前,只能向前一步步走,过河以后,除不能后退外,允许左右移动,但也只能一次一步。3、吃子:任何棋子走动时,如果目标位置上有对方的棋子,就可以把对方的棋子拿出棋盘,再换上自己的棋子(即吃子)。-4-1.3 概要设计 首先将棋盘的每一格坐标化,横坐标从 01 开始到 09。纵坐标从 01开始到 10,初始横坐标 01 行上摆放红子棋子,01 放车、02 放马、03 放象、04 放士、05 放帅,06、07、08、09 对称放士、象、马、车。横坐标 03 行 02、08 列放炮,横坐标 04
6、 行 01、03、05、07、09 列放兵。绿子旗子和红子棋子对称放在对面。在这个初始化的坐标上每一个棋子都对应的有一个点,并且对应一个数,红子棋子从车(i=0)开始一直到帅,for(i=0;ix2,x3x1&xx1+1x2+1!=0,则不能走棋,俗称“别相眼”。其它的情况同理。士:若 x36 或 x43,则 不 能 执 行,越 界。fabs(x4-x2-=fabs(x3-x1)=1 可以走,否则不能走。将:若 x36 或 x43,则 不 能 执 行,越 界。-6-fabs(x4-x2)=1&x3-x1=0|fabs(x3-x1)=1&x4-x2=0.如 果 终 止位置有子,若 xx3x420
7、 可以走,否则不能走。炮:从起始到终止位置,若中间有两个棋子,则不能走,没有棋子可以走,有一个棋子的话,判断 xx3x4是否大于 20,大于 20 则可以走,否则不能走。兵:若 x3=4 或 x3=5,则棋子不能左右移动,当 x35 时,棋子可以左右移动,但是当 x4x2 时,不能走棋,即所谓的“兵不能后退”程序流程图如下:-7-1.5 调试分析:输入 03,01,05,03。则马走到 05,03 的位置,该步可以明显的显示。再输入 02,08,05,08,绿子的炮走到 05,08 的位置,继续输入 08,03,05,03 红子的炮走动。输入 05,08,05,04 绿子的炮把红子的中兵吃掉,
8、输入 03,01,01,03 红子的相走到 01,03 的位置。输入 05,04,04,04 绿子的炮走到 04,04 的位置,输入 05,03,05,10 红子的炮吃掉绿子的将,提示为:lv qi shu le.经过测试,该程序可以实现中国象棋中所有棋子的走棋规则。2、源程序#include#include int x1112;void main()int i,j;int x1,y1,x2,y2,rg,gg;/*初始化棋子(开局)*/for(i=1;i=5;i+)xi1=x10-i1=i+10;xi10=x10-i10=i+20;if(i%2=1)xi4=x10-i4=17;xi7=x10-
9、i7=27;x23=x83=16;x28=x88=26;for(i=0;i=9;i+)xi0=i;for(i=1;i=0;j-)-8-for(i=0;i=20|x21|y29|y210|xx2y210|xx2y2=xx1y1;)printf(请输入红子坐标(x1,y1,x2,y2):);scanf(%d,%d,%d,%d,&x1,&y1,&x2,&y2);if(xx1y120)continue;rg=rgo(x1,y1,x2,y2);if(rg=0)continue;else if(xx2y2=25)xx2y2=xx1y1,xx1y1=0;printf(lu qi shu len);else
10、xx2y2=xx1y1,xx1y1=0;printf(S27 制作n=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=n);for(j=10;j=0;j-)for(i=0;i=9;i+)if(i=0)printf(%2d|,xij);continue;if(j=0)printf(0%d,xij);continue;switch(xij)case 0:printf();break;case 11:printf(车);break;case 12:printf(马);break;case 13:printf(相);break;-10-case 14:printf(士)
11、;break;case 15:printf(帅);break;case 16:printf(炮);break;case 17:printf(兵);break;case 21:printf(JU);break;case 22:printf(MA);break;case 23:printf(XN);break;case 24:printf(SH);break;case 25:printf(JN);break;case 26:printf(PO);break;case 27:printf(ZU);break;if(j=1)printf(|n-+-n);else if(j=0)printf(n);el
12、se printf(|n|n);/*绿子走子*/for(gg=0;gg=0;)for(x1=0,y1=0,x2=0,y2=0;xx1y110|x21|y29|y210|xx2y220|xx2y2=xx1y1;)printf(请输入绿子坐标(x1,y1,x2,y2):);scanf(%d,%d,%d,%d,&x1,&y1,&x2,&y2);if(xx1y1=0;j-)for(i=0;i=9;i+)if(i=0)printf(%2d|,xij);continue;if(j=0)printf(0%d,xij);continue;switch(xij)case 0:printf();break;cas
13、e 11:printf(车);break;case 12:printf(马);break;case 13:printf(相);break;case 14:printf(士);break;case 15:printf(帅);break;case 16:printf(炮);break;case 17:printf(兵);break;case 21:printf(JU);break;case 22:printf(MA);break;case 23:printf(XN);break;case 24:printf(SH);break;case 25:printf(JN);break;case 26:pr
14、intf(PO);break;case 27:printf(ZU);break;if(j=1)printf(|n-+-n);else if(j=0)printf(n);else printf(|n|n);-12-/*判定红棋是否有错*/rgo(xa,ya,xb,yb)if(xxaya=11)/*车*/int t;if(xb-xa=0)if(ybya)t=yb,yb=ya,ya=t;for(t=1+ya;tyb;t+)if(xxat!=0&xxat20)return 0;else if(yb-ya=0)if(xbxa)t=xb,xb=xa,xa=t;for(t=1+xa;txb;t+)if(xt
15、ya!=0&xxat0&xxaya+1!=0)return 0;if(yb-ya0&xxaya-1!=0)return 0;if(xxbyb!=0&xxbyb0&xxa+1ya!=0)return 0;if(xb-xa0&xxa-1ya!=0)return 0;if(xxbyb!=0&xxbyb5)return 0;if(fabs(yb-ya)=2&fabs(xb-xa)=2)if(yb-ya0)if(xb-xa0&xxa+1ya+1!=0)return 0;else if(xb-xa0&xxa+1ya-1!=0)return 0;else if(xb-xa0&xxa-1ya-1!=0)ret
16、urn 0;if(xxbyb!=0&xxbyb20)return 0;else return 0;return 1;if(xxaya=14)/*士*/if(xb6|yb3)return 0;if(xxbyb!=0&xxbyb20)return 0;if(fabs(yb-ya)=fabs(xb-xa)=1)return 1;else return 0;if(xxaya=15)/*帅*/if(xb6|yb3)return 0;if(fabs(yb-ya)=1&xb-xa=0)|(fabs(xb-xa)=1&yb-ya=0)return 1;-14-else return 0;if(xxaya=16
17、)/*炮*/int t,k;if(yb-ya=0)if(xbxa+k;k+)if(xxa+kya!=0)t+;if(t1)return 0;else if(t=0)if(xxbyb=0|xxaya=0)return 1;else return 0;else if(t=1)if(xxbyb20)return 1;else return 0;else if(xb-xa=0)if(ybya+k;k+)if(xxaya+k!=0)t+;if(t1)return 0;else if(t=0)if(xxbyb=0|xxaya=0)return 1;else return 0;else if(t=1)-15
18、-if(xxbyb20)return 1;else return 0;else return 0;if(xxaya=17)/*兵*/if(yb=ya&fabs(xb-xa)=1|yb-ya=1&xb=xa)if(ya=4|ya=5)&xb!=xa)return 0;if(xxbyb!=0&xxbyb20)return 0;else return 0;return 1;/*判定绿棋是否有错*/ggo(xa,ya,xb,yb)if(xxaya=21)/*车*/int t;if(xb-xa=0)if(ybya)t=yb,yb=ya,ya=t;for(t=1+ya;t20)return 0;else
19、if(yb-ya=0)if(xbxa)t=xb,xb=xa,xa=t;for(t=1+xa;t20)return 0;else return 0;return 1;-16-if(xxaya=22)/*马*/if(fabs(yb-ya)=2&fabs(xb-xa)=1)if(yb-ya0&xxaya+1!=0)return 0;if(yb-ya20)return 0;else if(fabs(xb-xa)=2&fabs(yb-ya)=1)if(xb-xa0&xxa+1ya!=0)return 0;if(xb-xa20)return 0;else return 0;return 1;if(xxay
20、a=23)/*相*/if(yb0)if(xb-xa0&xxa+1ya+1!=0)return 0;else if(xb-xa0&xxa+1ya-1!=0)return 0;else if(xb-xa20)-17-return 0;else return 0;return 1;if(xxaya=24)/*士*/if(xb6|yb20)return 0;if(fabs(yb-ya)=fabs(xb-xa)=1)return 1;else return 0;if(xxaya=25)/*帅*/if(xb6|yb8)return 0;if(fabs(yb-ya)=1&xb-xa=0)|(fabs(xb-
21、xa)=1&yb-ya=0)return 1;else return 0;if(xxaya=26)/*炮*/int t,k;if(yb-ya=0)if(xbxa+k;k+)if(xxa+kya!=0)t+;if(t1)return 0;else if(t=0)if(xxbyb=0|xxaya=0)return 1;else return 0;else if(t=1)if(xxbyb20)return 1;else return 0;-18-else if(xb-xa=0)if(ybya+k;k+)if(xxaya+k!=0)t+;if(t1)return 0;else if(t=0)if(xx
22、byb=0|xxaya=0)return 1;else return 0;else if(t=1)if(xxbyb20)return 0;else return 0;return 1;3、程序的说明文件 该程序的走棋规则是最为重要的,前面的程序主要是进行棋盘的初始化,后面的程序大部分为走棋规则的判断。例如以(红子为例)马的走棋规则 -19-if(xxaya=12)则判断该马这个棋子走 if(fabs(yb-ya)=2&fabs(xb-xa)=1)马的走棋规则 走“日”子 if(yb-ya0&xxaya+1!=0)判断是否“别马腿”;return 0;是的返回 0;if(yb-ya0&xxaya
23、-1!=0)判断是否“别马腿”;return 0;是的返回 0;if(xxbyb!=0&xxbyb20)判断终止位置是否有棋子,是否是自己方的 return 0;是自己方的不能走;4、课设总结 经过几天的课程设计我们实现了中国象棋的算法,完成了课程设计的要求,这期间我们经历了不少困难,也曾经想放弃过,因为原先以为我们对中国象棋完全没有概念,该如何设计程序,要用到什么数据结构等等都使我们感到该题目的棘手。从网上下载的参考程序也是令人费解。但是,既然老师给出的题目就是一定可以在我们的能力之内的,我们就试着把问题想的简单化,试着修改下载的东西,用数组来实现这个题目,这个过程中我们遇到了不少的困难,比如怎样实现棋子的走动,炮的走棋规则怎样执行等等。但是最终在我们小组整体的努力下,我们把问题一个一个的解决了最终实现了中国象棋的算法,这令我们组感到很振奋,也给了我们自信心,它让我们相信团队的力量是强大的。本次的课设不仅让我们巩固了 C 语言的知识,最重要的是让我们明白了团队合作的力量是强大的,也是必须的,该次课设对我们整组人以后的学习和设计会产生积极的影响,这是我们每个人所坚信的。-20-