数据结构中国象棋实验报告文档格式.docx
- 文档编号:5121322
- 上传时间:2023-05-04
- 格式:DOCX
- 页数:72
- 大小:396.53KB
数据结构中国象棋实验报告文档格式.docx
《数据结构中国象棋实验报告文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构中国象棋实验报告文档格式.docx(72页珍藏版)》请在冰点文库上搜索。
马
相
象
己方区域内(实际上是7个特殊棋位)
仕
士
己方九宫内(实际上是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]!
if(ManToType[manmap[from.x][j]]==RED_K)//照相
flag=TRUE;
break;
}
if(flag)
returnTRUE;
else
}
else
returnFALSE;
}
//下面几行判断目标点是否己方的棋子
if(SideOfMan[man]==0)
{
if(manmap[to.x][to.y]!
=32&
SideOfMan[manmap[to.x][to.y]]==0)
elseif(SideOfMan[man]==1)
SideOfMan[manmap[to.x][to.y]]==1)
//以下是各棋子的规则
switch(ManToType[man])
caseRED_B:
//兵不回头
if(to.y>
from.y)
//兵只走一步直线
if(from.y-to.y+abs(to.x-from.x)>
1)
break;
caseBLACK_B:
//卒不回头
if(to.y<
//卒只走一步直线
if(to.y-from.y+abs(to.x-from.x)>
caseRED_S:
caseBLACK_S:
//士走斜线一步
if(abs(from.y-to.y)>
1||abs(to.x-from.x)>
caseRED_X:
caseBLACK_X:
//象走田
if(abs(from.x-to.x)!
=2||abs(from.y-to.y)!
=2)
//象心
if(manmap[(from.x+to.x)/2][(from.y+to.y)/2]!
caseRED_K:
caseBLACK_K:
//将帅只走一步直线
if(abs(from.y-to.y)+abs(to.x-from.x)>
caseRED_J:
caseBLACK_J:
//车只能走直线
if(from.y!
=to.y&
from.x!
=to.x)
//车经过的路线不能有棋子
if(from.y==to.y)
if(from.x<
to.x)
for(i=from.x+1;
i<
to.x;
i++)
if(manmap[i][from.y]!
returnFALSE;
else
for(i=to.x+1;
from.x;
if(from.y<
to.y)
for(j=from.y+1;
to.y;
for(j=to.y+1;
from.y;
caseRED_P:
caseBLACK_P:
//炮只能走直线
//炮不吃子时经过的路线不能有棋子
if(manmap[to.x][to.y]==32)
if(from.y==to.y)
if(from.x<
for(i=from.x+1;
if(manmap[i][from.y]!
returnFALSE;
for(i=to.x+1;
if(from.y<
for(j=from.y+1;
if(manmap[from.x][j]!
for(j=to.y+1;
else//吃子时
intcount=0;
count++;
if(count!
=1)
caseRED_M:
caseBLACK_M:
//马走日
((abs(to.x-from.x)==1&
abs(to.y-from.y)==2)
||(abs(to.x-from.x)==2&
abs(to.y-from.y)==1)))
//找马脚
if(to.x-from.x==2){i=from.x+1;
j=from.y;
}
elseif(from.x-to.x==2){i=from.x-1;
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]!
default:
returnTRUE;
判断棋子的位置是不是合法,用函数IsNormal实现。
具体是实现如下:
BOOLIsNormal(constint&
mantype,constPOINT&
point)
if(point.x<
1||point.x>
9||point.y<
1||point.y>
10)
returnFALSE;
switch(mantype)
//帅不能在红方宫外
if(point.x>
6||point.x<
4||point.y<
8)
//士只能在宫内特定点
(
(point.x==4&
point.y==10)||
point.y==8)||
(point.x==5&
point.y==9)||
(point.x==6&
point.y==8)
))
//七个相位
if(!
(point.x==1&
point.y==8)||
(point.x==3&
point.y==10)||
point.y==6)||
(point.x==5&
(point.x==7&
(point.x==9&
))returnFALSE;
//兵不能在兵位后
if(point.y>
7)
//兵过河前不能左右移动
5&
point.x%2==0)
4||point.y>
3)
point.y==1)||
point.y==3)||
point.y==2)||
point.y==3)
point.y==3)||
point.y==1)||
point.y==5)||
if(point.y<
4)
6&
保存棋盘状态。
其具体实现如下:
voidFixManMap(intmap[11][12],POINTmanpoint[32],intside)
memcpy(map,_defaultmap,132*sizeof(int));
staticPOINT*pman;
staticinti;
for(i=0;
32;
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,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
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 中国象棋 实验 报告