数据结构中国象棋实验报告.docx
- 文档编号:9726930
- 上传时间:2023-02-06
- 格式:DOCX
- 页数:72
- 大小:396.53KB
数据结构中国象棋实验报告.docx
《数据结构中国象棋实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构中国象棋实验报告.docx(72页珍藏版)》请在冰豆网上搜索。
数据结构中国象棋实验报告
数据结构课程设计报告——中国象棋
姓名:
林泽全学号:
*********班级:
09网络工程
一、问题描述
1.象棋概述
象棋,又称中国象棋(英文现译作chess)。
在中国有着悠久的历史,属于二人对抗性游戏的一种,由于用具简单,趣味性强,成为流行极为广泛的棋艺活动。
中国象棋是我国正式开展的78个体育运动项目之一,为促进该项目在世界范围内的普及和推广,现将“中国象棋”项目名称更改为“象棋”。
此外,高材质的象棋也具有收藏价值,如:
高档木材、玉石等为材料的象棋。
更有文人墨客为象棋谱写了诗篇,使象棋更具有一种文化色彩。
2.棋子的初始棋位
整个棋盘以“河界”分为相等的两部分。
为了比赛记录和学习棋谱方便起见,现行规则规定:
按九条竖线从右至左用中文数字一至九来表示红方的每条竖线,用阿拉伯数字1只至9来表示黑方的每条竖线。
己方的棋子始终使用己方的线路编号,无论棋子是否“过河”。
对弈开始之前,红黑双方应该把棋子摆放在规定的位置。
任何棋子每走一步,进就写“进”,退就写“退”,如果像车一样横着走,就写“平”。
3.象棋棋子
象棋是一种双方对阵的竞技项目。
棋子共有三十二个,分为红黑两组,各有十六个,由对弈的双方各执一组。
棋子种类说明如下表:
红方名称
黑方名称
每方棋子数
可以到达的范围
帅
将
1
己方九宫内
车
车
2
全盘任何位置
炮
炮
2
全盘任何位置
马
马
2
全盘任何位置
相
象
2
己方区域内(实际上是7个特殊棋位)
仕
士
2
己方九宫内(实际上是5个特殊棋位)
兵
卒
5
起始位置及向前一步的位置,敌方所有棋位
帅与将;仕与士;相与象;兵与卒的作用完全相同,仅仅是为了区别红棋和黑棋而已。
4.棋子的走法
Ø帅(将)
帅(将)是棋中的首脑,是双方竭力争夺的目标。
它只能在九宫之内活动,可上可下,可左可右,每次走动只能按竖线或横线走动一格。
帅与将不能在同一直线上直接对面,否则走方判负。
Ø仕(士)
仕(士)是将(帅)的贴身保镖,它也只能在九宫内走动。
它的行棋路径只有九宫内的斜线。
Ø相(象)
相(象)的主要作用是防守,保护自己的帅(将)。
它的走法是每次循对角线走两格,俗称“象飞田”。
相(象)的活动范围限于河界以内的本方阵地,不能过河,且如果它走的田字中央有一个棋子,就不能走,俗称“塞象眼”。
Ø车
车在象棋中威力最大,无论横线、竖线均可行走,只要无子阻拦,步数不受限制。
因此,一车可以控制十七个点,故有“一车十子寒”之称。
Ø炮(炮)
炮(炮)在不吃子的时候,移动与车完全相同。
当吃子时,己方和对方的棋子中间必须间隔1个棋子(无论对方或己方棋子),炮是象棋中唯一可以越子的棋种。
Ø马
马走动的方法是一直一斜,即先横着或直着走一格,然后再斜着走一个对角线,俗称“马走日”。
马一次可走的选择点可以达到四周的八个点,故有八面威风之说。
如果在要去的方向有别的棋子挡住,马就无法走过去,俗称“蹩马腿”。
Ø兵(卒)
兵(卒)在未过河前,只能向前一步步走,过河以后,除不能后退外,允许左右移动,但也只能一次一步,即使这样,兵(卒)的威力也大大增强,故有“过河的卒子顶半个车”之说。
5.胜负的判定
1)当棋局中出现一下情况判负,对方取胜:
a.帅(将)被“将死”——另一方走一步棋之后试图吃掉一方的帅(将),但该方的帅(将)却不能躲避;
b.困毙——轮到一方行棋,但按规定,己方无棋可走;
c.由于子力悬殊,继续抵抗毫无意义的主动认输;
d.长打(即长捉、长将、长杀、或一将一要杀)的一方通常判负;
e.行棋违规、违纪、超时等情况判负。
2)当棋局中出现一下情况作和:
a.双方理论上无法取胜的简单局面;
b.符合“六十回合规定”——从任意一步开始,六十回合内双方均无损失一子;
c.一方提和,另一方同意和棋;
d.长跟、长兑、长拦、长献、一捉一闲、或一将一闲,循环三回合后可判和。
6.棋子的子力价值
Ø车:
象棋中实力最强的棋子,由于可以在棋盘线上飞快的移动,不论吃子与移动都十分方便,因此在全盘的价值都很高,其实力相当于双马、双炮、马炮,为其评估10分。
其近、中、远程作战都适用。
Ø炮:
由于其“炮打隔子”因此中远程作战,其多用于牵制,和各子(主要是车)配合都很容易。
在残局要依靠仕相的力量攻守(俗称“残局炮还家”)。
开、中局由于子多,他的“炮架子”也多,实力略高于马,此时为他打5分。
残局“炮架子”少,实力也相应减弱,但其依靠仕相防守力强于马(如单车可胜马双仕却难胜炮双仕),因此“求和易留炮”,此时为其打4.5分。
其实力等于一马、双仕、双相、一仕一相。
Ø马:
中距离作战兵器。
与炮相反,由于“蹩腿”,子力少时,实力较炮强。
由于此性质,它易往开阔处跳,戍边反而不利。
其实力相当于一炮、双相、双仕、一仕一相。
Ø兵(卒):
开局时由于只能向前,几乎无攻击力,但有限疏通我方马路兼限制敌方马路的作用,为其打0.5分。
过河后可以转弯,当靠近敌方九宫时威力大增,故有“小兵过河顶大车”、“过河卒子半个车”等说法。
残局时,双方子力较少,兵的作用显现出来,过河的高兵,价值倍增为其打3分;低兵价值2分;因为底兵只对一楼的老将有威胁,所以底兵价值1分。
过河的兵相当于一仕、一相。
注意兵轻易不要沉底。
Ø仕(士)、相(象):
属于防守的棋子,一仕等于一相。
开局阶段,老将不易受攻击为其打2分,正因为如此,开局人们不爱用马(炮)兑仕相。
中、残局时矛头直指老将,此时急需仕相守卫,同时仕相还可配合炮攻防或走闲着以防困毙,因此不占便宜就不要轻易丢弃仕相,此时为其打3分。
切记:
缺仕宜兑车,缺相宜兑炮。
花士象可防车,中联仕相可防炮。
仕相宜中联,相不轻易散边。
Ø帅(将):
全盘棋子争夺的目标,需要我方棋子保护。
开局时不宜乱动免得自找麻烦。
中、残局安全时可出帅助攻,如“铁门栓”。
二、基本要求
程序的用户作为玩者的角色,计算机是对手。
计算机可以实现简单地人机对战。
三、工具/准备工作
需要一台计算机,其中安装有VisualC++6.0集成开发环境软件。
四、分析与实现
Ø首先是根据中国象棋的走法,规定各个棋子的走法。
其具体实现方法用函数CanGo实现,
BOOLCanGo(intmanmap[11][12],intman,constPOINT&from,constPOINT&to)
{
staticinti,j;
if(!
IsNormal(ManToType[man],to))//这个棋子不能放在目标位置
{
//如果不是将/帅(将/帅可以“照相”)
if(ManToType[man]!
=RED_K&&ManToType[man]!
=BLACK_K)
returnFALSE;
elseif(ManToType[man]==RED_K&&//走的是帅
ManToType[manmap[to.x][to.y]]==BLACK_K)//目标是将
{
BOOLflag=FALSE;
for(j=from.y-1;j>0;j--)
{
if(manmap[from.x][j]!
=32)
{
if(ManToType[manmap[from.x][j]]==BLACK_K)//照相
flag=TRUE;
break;
}
}
if(flag)
returnTRUE;
else
returnFALSE;
}
elseif(ManToType[manmap[to.x][to.y]]==RED_K)//走的是将,目标是帅
{
BOOLflag=FALSE;
for(j=from.y+1;j<11;j++)
{
if(manmap[from.x][j]!
=32)
{
if(ManToType[manmap[from.x][j]]==RED_K)//照相
flag=TRUE;
break;
}
}
if(flag)
returnTRUE;
else
returnFALSE;
}
else
returnFALSE;
}
//下面几行判断目标点是否己方的棋子
if(SideOfMan[man]==0)
{
if(manmap[to.x][to.y]!
=32&&SideOfMan[manmap[to.x][to.y]]==0)
returnFALSE;
}
elseif(SideOfMan[man]==1)
{
if(manmap[to.x][to.y]!
=32&&SideOfMan[manmap[to.x][to.y]]==1)
returnFALSE;
}
//以下是各棋子的规则
switch(ManToType[man])
{
caseRED_B:
//兵不回头
if(to.y>from.y)
returnFALSE;
//兵只走一步直线
if(from.y-to.y+abs(to.x-from.x)>1)
returnFALSE;
break;
caseBLACK_B:
//卒不回头
if(to.y returnFALSE; //卒只走一步直线 if(to.y-from.y+abs(to.x-from.x)>1) returnFALSE; break; caseRED_S: caseBLACK_S: //士走斜线一步 if(abs(from.y-to.y)>1||abs(to.x-from.x)>1) returnFALSE; break; caseRED_X: caseBLACK_X: //象走田 if(abs(from.x-to.x)! =2||abs(from.y-to.y)! =2) returnFALSE; //象心 if(manmap[(from.x+to.x)/2][(from.y+to.y)/2]! =32) returnFALSE; break; caseRED_K: caseBLACK_K: //将帅只走一步直线 if(abs(from.y-to.y)+abs(to.x-from.x)>1) returnFALSE; break; caseRED_J: caseBLACK_J: //车只能走直线 if(from.y! =to.y&&from.x! =to.x) returnFALSE; //车经过的路线不能有棋子 if(from.y==to.y) { if(from.x { for(i=from.x+1;i if(manmap[i][from.y]! =32) returnFALSE; } else { for(i=to.x+1;i if(manmap[i][from.y]! =32) returnFALSE; } } else { if(from.y { for(j=from.y+1;j if(manmap[from.x][j]! =32) returnFALSE; } else { for(j=to.y+1;j if(manmap[from.x][j]! =32) returnFALSE; } } break; caseRED_P: caseBLACK_P: //炮只能走直线 if(from.y! =to.y&&from.x! =to.x) returnFALSE; //炮不吃子时经过的路线不能有棋子 if(manmap[to.x][to.y]==32) { if(from.y==to.y) { if(from.x { for(i=from.x+1;i if(manmap[i][from.y]! =32) returnFALSE; } else { for(i=to.x+1;i if(manmap[i][from.y]! =32) returnFALSE; } } else { if(from.y { for(j=from.y+1;j if(manmap[from.x][j]! =32) returnFALSE; } else { for(j=to.y+1;j if(manmap[from.x][j]! =32) returnFALSE; } } } else//吃子时 { intcount=0; if(from.y==to.y) { if(from.x { for(i=from.x+1;i { if(manmap[i][from.y]! =32) count++; } if(count! =1) returnFALSE; } else { for(i=to.x+1;i { if(manmap[i][from.y]! =32) count++; } if(count! =1) returnFALSE; } } else { if(from.y { for(j=from.y+1;j { if(manmap[from.x][j]! =32) count++; } if(count! =1) returnFALSE; } else { for(j=to.y+1;j { if(manmap[from.x][j]! =32) count++; } if(count! =1) returnFALSE; } } } break; caseRED_M: caseBLACK_M: //马走日 if(! ((abs(to.x-from.x)==1&&abs(to.y-from.y)==2) ||(abs(to.x-from.x)==2&&abs(to.y-from.y)==1))) returnFALSE; //找马脚 if(to.x-from.x==2){i=from.x+1;j=from.y;} elseif(from.x-to.x==2){i=from.x-1;j=from.y;} elseif(to.y-from.y==2){i=from.x;j=from.y+1;} elseif(from.y-to.y==2){i=from.x;j=from.y-1;} //绊马脚 if(manmap[i][j]! =32) returnFALSE; break; default: break; } returnTRUE; } Ø判断棋子的位置是不是合法,用函数IsNormal实现。 具体是实现如下: BOOLIsNormal(constint&mantype,constPOINT&point) { if(point.x<1||point.x>9||point.y<1||point.y>10) returnFALSE; switch(mantype) { caseRED_K: //帅不能在红方宫外 if(point.x>6||point.x<4||point.y<8) returnFALSE; break; caseRED_S: //士只能在宫内特定点 if(! ( (point.x==4&&point.y==10)|| (point.x==4&&point.y==8)|| (point.x==5&&point.y==9)|| (point.x==6&&point.y==10)|| (point.x==6&&point.y==8) )) returnFALSE; break; caseRED_X: //七个相位 if(! ( (point.x==1&&point.y==8)|| (point.x==3&&point.y==10)|| (point.x==3&&point.y==6)|| (point.x==5&&point.y==8)|| (point.x==7&&point.y==10)|| (point.x==7&&point.y==6)|| (point.x==9&&point.y==8) ))returnFALSE; break; caseRED_B: //兵不能在兵位后 if(point.y>7) returnFALSE; //兵过河前不能左右移动 if(point.y>5&&point.x%2==0) returnFALSE; break; caseBLACK_K: //帅不能在红方宫外 if(point.x>6||point.x<4||point.y>3) returnFALSE; break; caseBLACK_S: //士只能在宫内特定点 if(! ( (point.x==4&&point.y==1)|| (point.x==4&&point.y==3)|| (point.x==5&&point.y==2)|| (point.x==6&&point.y==1)|| (point.x==6&&point.y==3) )) returnFALSE; break; caseBLACK_X: //七个相位 if(! ( (point.x==1&&point.y==3)|| (point.x==3&&point.y==1)|| (point.x==3&&point.y==5)|| (point.x==5&&point.y==3)|| (point.x==7&&point.y==1)|| (point.x==7&&point.y==5)|| (point.x==9&&point.y==3) ))returnFALSE; break; caseBLACK_B: //兵不能在兵位后 if(point.y<4) returnFALSE; //兵过河前不能左右移动 if(point.y<6&&point.x%2==0) returnFALSE; break; default: break; } returnTRUE; } Ø保存棋盘状态。 其具体实现如下: voidFixManMap(intmap[11][12],POINTmanpoint[32],intside) { memcpy(map,_defaultmap,132*sizeof(int)); staticPOINT*pman; staticinti; for(i=0;i<32;i++) { pman=&manpoint[i]; if(pman->x) map[pman->x][pman->y]=i; } } Ø规定各个位置不同的价值值: //兵卒在不同位置的价值,数字越大价值越高 constintManBPlus[2][12][11]= { { {0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0}, {0,1,2,3,4,4,4,3,2,1,0}, {0,1,2,3,4,4,4,3,2,1,0}, {0,1,2,3,3,3,3,3,2,1,0}, {0,1,1,1,1,1,1,1,1,1,0}, {0,0,0,1,0,0,0,1,0,0,0}, {0,0,0,0,0,2,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0} }, { {0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 中国象棋 实验 报告