中国智能象棋实验报告C#程序.docx

上传人:b****7 文档编号:9976916 上传时间:2023-02-07 格式:DOCX 页数:8 大小:19.46KB
下载 相关 举报
中国智能象棋实验报告C#程序.docx_第1页
第1页 / 共8页
中国智能象棋实验报告C#程序.docx_第2页
第2页 / 共8页
中国智能象棋实验报告C#程序.docx_第3页
第3页 / 共8页
中国智能象棋实验报告C#程序.docx_第4页
第4页 / 共8页
中国智能象棋实验报告C#程序.docx_第5页
第5页 / 共8页
点击查看更多>>
下载资源
资源描述

中国智能象棋实验报告C#程序.docx

《中国智能象棋实验报告C#程序.docx》由会员分享,可在线阅读,更多相关《中国智能象棋实验报告C#程序.docx(8页珍藏版)》请在冰豆网上搜索。

中国智能象棋实验报告C#程序.docx

中国智能象棋实验报告C#程序

象棋游戏C#程序设计报告

这个程序中主要训练了象棋的一些算法,以及关于多态和继承的思想。

程序没有花俏的界面,就是一个程序主窗体,也为棋盘部分。

用一个函数来记录棋盘上所有点的坐标,再把所有坐标点均采用一个数学公式求出此点映射到一维数组对应的索引,由索引来确定棋子的走动。

其中程序中的各种判断机制,特别是各种情况效验,主要为if的使用,包括类型比对,空值判断等等。

首先确定用户操作,在编写程序前,我们应该先确定我们的用户共有哪些行为和操作,在确定这些行为和操作以后,我们再对它进行模块划分。

我们的用户所做的所有操作仅两个,一是点击棋子,二是点击棋盘。

而点击棋子可能带来的操作为选中棋子和吃掉棋子,而我们点击棋盘则会带来移动棋子的过程。

分割程序模块,所有的操作和行为已经确定,接下来应该划分具体的模块,大体上,我们可以划分出棋盘和棋子两个大模块,但是在我们象棋中,棋子一共有7种,各有个性,单也有共性。

比如,所有棋子移动均不能超越棋盘边界,均不能阁棋子移动,这些都是象棋棋子的共性。

角色的事件激发过程,接下来分析一下每个参与的角色的事件激发过程。

用户点中棋子包含两个操作,选中棋子和吃棋子。

所有的操作均来自棋子被选中以后,只有当有了目标棋子以后,所有的包括移动,吃棋子才产生意义。

在象棋中有伦次概念,即蓝方移动以后,伦次应转换为红方移动。

那么当第二次操作,即移动或者吃棋子以后应该转换伦次。

棋盘为9X10格,那么此时不可能使用象素点来做为定位网格。

但是可以假定一个虚拟的网格模型,必须确定整个棋盘的边界。

编码实现

一、Class1是一个自定义类,记录了旗盘位置特点类,以非常技巧的数据结构,记录了每一时刻旗盘上的旗子情况。

GetNearPoint求两点间的距离公式N(x2-x1)2-(y2-y2)2

CountIndex已知一个点,求出此点映射到一维数组对应的索引,既是代表在棋盘上的位置。

公式为:

(y2-y1)/this.height*9+(x2-x1)/this.width

由index决定是前进还是往后退:

intindex=this.CountIndex(point);

if(index>=0&&index<45)

return"up";

else

{if(index>=45&&index<90)

return"down";

二、class2继承于class1,也是一个自定义类,记录了旗盘位置特点类,规定了各个旗子的走法。

没有考虑所有情况,而只考虑了真的情况;能够避免作蔽,程序规定必须按每个旗子的走法走旗。

旗子判断步伐时,为了提高执行效率,只判断旗子可以走的情况。

自己周围的规则点是不是在旗盘上;如果周围的规则点在旗盘上,则该点是否是自己的旗子,如果是,则不允许走。

首先判断各个棋的走法是否合理之前,都要先判断这个棋子能不能走。

既先求标志起点信息的一维数组的索引,再求标志终点信息的一维数组的索引,如果起点和终点是同一个点,则允许放回旗子,重新选其它路,如果起点和终点是同一边的旗子,则不能走

(一)、判断马的走法是否合理,

除去以上几种情况,其余终点都不能落旗

1、当马向上跳时有两种跳法(左上日和右上日),起点上面没有旗子,也就是不"挡马腿"时可以往上走旗:

if(this.GetNextPoint(fromPoint,-2,1)==toPoint||this.GetNextPoint(fromPoint,-2,-1)==toPoint)

if(this.have[this.CountIndex(this.GetNextPoint(fromPoint,-1,0))]==false)

2、同上,只是变为向下跳马,不"挡马腿"时可以往下走:

this.GetNextPoint(fromPoint,2,1)

this.GetNextPoint(fromPoint,2,-1)

this.CountIndex(this.GetNextPoint(fromPoint,1,0))]==false)

3、同上,只是变为向右跳马,不"挡马腿"时可以往右走:

this.GetNextPoint(fromPoint,1,2)

this.GetNextPoint(fromPoint,-1,2)

this.CountIndex(this.GetNextPoint(fromPoint,0,1))]==false)

4、同上,只是变为向左跳马

this.GetNextPoint(fromPoint,-1,-2)

this.GetNextPoint(fromPoint,1,-2)==toPoint)

(二)、断兵/卒的走法是否合理

要先判断起点是在旗盘上方,还是下方,终点是在旗盘上方,还是下方。

假如起始点是蓝兵,起点和终点都在下面或起点在下面终点在上面时this.GetNextPoint(fromPoint,-1,0),如果终点是起点的上面一个点,则返回真

如果起点和终点都在上面时有以下几种情况:

过河后可以往上走:

this.GetNextPoint(fromPoint,-1,0)

过河后可以往右走:

(this.GetNextPoint(fromPoint,0,1)

过河后可以往左走:

this.GetNextPoint(fromPoint,0,-1)

假如起始点是红兵,规则同上蓝兵,不过是过河后往下走时是this.GetNextPoint(fromPoint,1,0)

(三)、判断車的走法是否合理

1、起点和终点在同一条垂直直线上,

起点在终点下面,判断起点终点之间有无旗子:

for(inti=-1;this.GetNextPoint(fromPoint,i,0)!

=toPoint;i--)

起点在终点上面,判断起点终点之间有无旗子:

for(inti=1;this.GetNextPoint(fromPoint,i,0)!

=toPoint;i++)

2、起点和终点在同一条水平直线上

起点在终点左边判断起点终点之间有无旗子:

for(intj=1;this.GetNextPoint(fromPoint,0,j)!

=toPoint;j++)

起点在终点右边

(四)、判断炮的走法是否合理

1、起点和终点在同一垂直线上

起点在终点下面,先判断起点终点之间旗子数量,如果起点和终点之间的旗子数大于1,则不能落旗;起点和终点之间无旗子,且终点也无旗子,则可以在终点落旗;起点和终点之间仅有一个旗而且终点有旗子且是对方的旗子,炮就可以吃掉对方的棋子。

for(inti=-1;this.GetNextPoint(fromPoint,i,0)!

=toPoint;i--)

if(number_QiZi>1)

还有起点在终点下面、起点在终点右边、起点在终点左边这三种情况,编程方法同上。

(五)、判断象的走法是否合理

如果起点和终点所在边不相同,如一个在河上,一个在河下,则不能落旗,即各边的象不能过河.象的四种走法:

当象向右下方跳时右下田,起点右下一个点上没有旗子,也就是不挡象腿时可以往上走旗:

if(this.GetNextPoint(fromPoint,2,2)==toPoint)

this.GetNextPoint(fromPoint,1,1))]==false

左下田:

(fromPoint,2,-2)fromPoint,1,-1))]==false

右上田:

(fromPoint,-2,2)(fromPoint,-1,1))]==false)

左上田:

(fromPoint,-2,-2)(fromPoint,-1,-1))]==false)

(六)、判断士的走法是否合理

如果起点和终点所在边不相同,如一个在河上,一个在河下,则不能落旗,即各边的士不能过河.控制士的活动范围:

if(index!

=3&&index!

=5&&index!

=13&&index!

=21&&index!

=23&&index!

=66)

if(index!

=68&&index!

=76&&index!

=84&&index!

=86)

returnfalse;

左上方一点跳:

(fromPoint,-1,-1)

左下方一点跳:

fromPoint,1,-1)

(七)判断将/帅的走法是否合理

if(GenEatGen)将与帅相望则可以直接吃掉对方,需要移动棋子来解除将对帅,控制将帅的活动范围:

if(index!

=3&&index!

=4&&index!

=5&&index!

=12&&index!

=13&&index!

=14&&index!

=21&&index!

=22&&index!

=23)if(index!

=66&&index!

=67&&index!

=68&&index!

=75&&index!

=76

&&index!

=77&&index!

=84&&index!

=85&&index!

=86)

returnfalse;

往左方一点走:

this.GetNextPoint(fromPoint,0,-1)==toPoint

往右方一点走:

this.GetNextPoint(fromPoint,0,1)==toPoint

往上方一点走:

this.GetNextPoint(fromPoint,-1,0)==toPoint

往下方一点走:

this.GetNextPoint(fromPoint,1,0)==toPoint

三、Class3类主要是对悔旗操作,较困难的一个类,极具有技巧性;先用activeIndex起流动指针作用,tailIndex始终指向尾部既是刚走完的最后一步旗的索引。

先初始化各数组和索引,再判断activeIndex和tailIndex的值,根据它们值的大小来将tailIndex变为activeIndex。

(this.activeIndex>this.tailIndex-1)

this.tailIndex--;

this.activeIndex=this.tailIndex;

(this.activeIndex

this.activeIndex++

if(this.activeIndex>this.tailIndex)

this.activeIndex=this.tailIndex;

还要防止一开始就点后退:

if(this.activeIndex<0)

return0;

if(this.activeIndex>=this.tailIndex)

this.activeIndex=this.tailIndex-1;

if(this.activeIndex<=-1)

return0;

四、Class4走完一步旗后,判断是否将军;走完一步判断是否一方胜利。

功能比较完整。

一方被将军后如能找到自己的棋子来解除将军,则继续下棋;如果一方不能找到棋子来解除将军,则这方就输棋了。

如果帅将隔河相望,则也算是将军:

if(ShuaiSymmetryJiang())

{shanShuo=true;

GenEatGen=true;}

红帅被将军:

index=a.GetIndexByPictureIndex(4);

if(index==-1)return;

if(b.have[i]&&b.who[i]=="blue"&&b.AcceptJudge(b.allPoint[i],p,false))

{blueToRed=true;}

表示蓝方胜:

index=a.GetIndexByPictureIndex(4);

if(index==-1)

表示红方胜:

index=a.GetIndexByPictureIndex(27);

if(index==-1)

五、Class5增加键盘支持功能,使鼠标和键盘操作互斥。

键盘能够独立完成鼠标独立的功能;而且对鼠标左右键的互斥性和键盘与鼠标的互斥性支持较好。

定义键盘的上键、下键、左键、右键来控制棋子的上下左右走动。

p1=a.GetNearPoint(currentPoint.X,currentPoint.Y);

p2=a.GetNextPoint(p1,-1,0)

if(p2.X!

=-1)

returnp2;

returna.GetNextPoint(p1,9,0);

六、Class6实现游戏中随时能够设置断点,随时能够读取断点功能。

不但能够恢复断点,而且还能在相应的断点执行退旗等操作,即能回到断点处重新开始游戏。

在本自定义类中序列化Form2中的数组和变量和类;序列化Form2中pictureBoxStatus数组;序列化Form2中类Class2a中的变量和数组;序列化Form2中Class3huiQi中的变量/数组和类实例数组;序列化Form2中类Class4jiangJun中的变量/数组/类实例还有Class2b的变量/数组;序列化Form2中类Class5keyBoard中的变量。

反序列化Form2中pictureBoxStatus数组;反序列化Form2中Class2a中的变量和数组;反序列化Form2中Class3huiQi中的变量/数组和类实例数组;反序列化Form2中类Class4jiangJun中的变量/数组/类实例还有Class2b的变量/数组;反序列化Form2中类Class5keyBoard中的变量。

七、Class8实现电脑自动分析走旗。

可以实现双人模式与单人模式切换,红方可以在任意时刻由电脑下或由人下。

不过就是有点不是很有技巧性。

电脑下棋程序分为防守和进攻。

寻找有没有直接吃掉对方将帅的旗子的旗子,帅被将军,移动自己非帅旗子解除将军或者帅自己走动来解除将军;要随时看有没有可吃的旗子或者是能够将对方军的棋子:

if(b.who[i]=="red"&&b.who[j]=="blue"&&

b.AcceptJudge(b.allPoint[i],b.allPoint[j],false))。

防守时避开一方旗子:

if(b.who[i]=="blue"&&b.who[j]=="red"&&

b.AcceptJudge(b.allPoint[i],b.allPoint[j],false)&&run);

杀死正踩旗头的旗子:

if(b.who[i]=="red"&&b.AcceptJudge(b.allPoint[i],

b.allPoint[index],false));保护被对方旗子踩头的旗子。

八、Class9用于同步或者异步地播放音乐。

用一个swith,case语句来播放各种音效,像开始、后退、下棋、悔棋、将军、吃棋、胜利、移棋等等。

九、Windows应用程序使用图形界面,一般有一个窗口(Form),采用事件驱动方式工作。

自定义类Form1以Form类为基类。

Form类是.Net系统中定义的窗体类,Form类对象具有Windows应用程序窗口的最基本功能,有标题栏、系统菜单、最大化按钮、最小化按钮和关闭按钮、用户区。

Form类对象还是一个容器,在Form窗体中可以放置其它控件,例如菜单控件,工具条控件等等;System.Application类中的静态方法Run负责完成一个应用程序的初始化,运行,终止等功能,其参数是本程序使用的窗体Form1类对象,Run方法还负责从操作系统接受事件,并把事件送到窗体中响应。

窗体关闭,方法Run退出,Windows应用程序结束。

可以为Form1类定义构造函数,在构造函数中做一些初始化的工作,例如修改Form1标题栏中的标题。

还可以在Form1中定义控件类的对象,这些控件将在Form1的用户区显示出来,换句话讲,在Form1中生成控件对象,也就是把控件放到窗体中。

Form类主要是绘出界面,进行一些简单的初始化操作,panel1_Paint画旗盘,先确定每个方格的宽和高,画一行方格再往下移动动坐标,画下一行方格;最后移动坐标,画下方旗盘g.DrawRectangle(pen1,startX,startY,width,height);

point[Index]=newPoint(startX,startY);

Index++;

startX+=width;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 判决书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1