基于c#的五子棋游戏的设计与实现.docx
《基于c#的五子棋游戏的设计与实现.docx》由会员分享,可在线阅读,更多相关《基于c#的五子棋游戏的设计与实现.docx(34页珍藏版)》请在冰豆网上搜索。
基于c#的五子棋游戏的设计与实现
郑州科技学院
课程设计论文
基于C#的五子棋游戏的设计与实现
1 引言
1.1 五子棋介绍
五子棋是起源于中国古代的传统黑白棋种之一。
现代五子棋日文称之为“連珠”,英译为“Renju”,英文称之为“Gobang”或“FIR”(FiveinaRow的缩写),亦有“连五子”、“五子连”、“串珠”、“五目”、“五目碰”、“五格”等多种称谓。
五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。
五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴阳易理”;它既有简单易学的特性,为人民群众所喜闻乐见,又有深奥的技巧和高水平的国际性比赛;它的棋文化源渊流长,具有东方的神秘和西方的直观;既有“场”的概念,亦有“点”的连接。
它是中西文化的交流点,是古今哲理的结晶。
2 软件架构
软件的总体架构如图2.1:
图2.1软件架构
3 五子棋设计说明
3.1 主要成员变量说明
1)选择游戏模式标志——m_renren
用来表示当前玩家选择游戏的情况,当m_renren为false时,表示人机对战;为true时,表示人人对弈。
2)游戏开始标志——begin
用来判断当前游戏是否开始
3)音效标志——sound
在下棋过程中,判断是否需要声音,当sound为true时,表示玩家需要声音,否则的话,玩家不需要声音。
4)谁先下的标志——first
这个标志只对人机对弈时有效。
当first为true时,表示人先下,否则,电脑先下。
5)棋盘数据——points
points为棋盘情况数组,是用一个15*15的二维数组来表示的。
points[i,j]=2表示此处无子,points[i,j]=1表示此处为黑子points[i,j]=0表示此处为白子。
6)棋子颜色标志——qzcolor
用来表示当前棋子的颜色,qzcolor=1时表示黑棋,qzcolor=0时表示百棋。
7)棋子数据——qz
表示棋子所放的位子,是用一个15*15的PictureBox类型的二维数组来表示。
它还可以用来显示当前棋子的图片。
8)oldMovePoint
用来记录鼠标经过后点的位置。
9)backStack
用于悔棋的栈。
10)backTrackStack
用于回溯的栈
11)结局——result
用枚举类型来表示结局。
如:
publicenumresult:
int//结局
{
lose=-1,
equal,
win
}
3.2 回溯栈元素类——StackElement
成员变量:
1)qzColor棋子的颜色
2)bestFivePoints最好点的位置
3)pointsCount计算最好点的数目
4)pointNumber点的数目
5)Theresult结局
6)stepNumber预测的步数
3.3 棋子点属性类——qzdianshuxing
1)blackConnect黑棋子i个(包括活棋)的连接条数
2)blackActive黑活棋i个的连接条数
3)whiteConnect白棋子i个(包括活棋)的连接条数
4)whiteActive白活棋i个的连接条数
5)tempActive3活棋数为3的连接条数
3.4 主要成员函数说明
1)初始化棋盘——Initializeqp
初始化操作包括以下几个步骤:
●设置棋子所在的位置
●设置棋子的大小
●初始化棋子的背景颜色
●将棋子的sizemode设置为CenterImage
●将棋子的可见性设置为false
●将棋子添加到form上。
2)绘制棋盘——Form1_Paint
其主要是画出以40*40的大小为每一小格,代码如下:
for(i=0;i<15;i++)
g.DrawLine(myPen,30+i*40,50,30+i*40,610);
g.DrawLine(myPen,30,50+i*40,590,50+i*40);
3)绘制光标——Form1_MouseMove
当鼠标在棋盘上移动时,当前的显示画红方框,过去的显示和背景一样颜色的方框。
当前的红方框代码如下:
if(10{x=((e.X-10)/40)*40+30;y=((e.Y-10)/40)*40+50;g.DrawLine(newpen,x-15,y-15,x-15,y-5);g.DrawLine(newpen,x-15,y-15,x-5,y-15);g.DrawLine(newpen,x+15,y-15,x+5,y-15);g.DrawLine(newpen,x+15,y-15,x+15,y-5);g.DrawLine(newpen,x-15,y+15,x-15,y+5);g.DrawLine(newpen,x-15,y+15,x-5,y+15);g.DrawLine(newpen,x+15,y+15,x+15,y+5);g.DrawLine(newpen,x+15,y+15,x+5,y+15);oldMovePoint.X=x;oldMovePoint.Y=y;}过去的方框代码如下:if(oldMovePoint.X!=-1){g.DrawLine(oldpen,oldMovePoint.X-15,oldMovePoint.Y-15,oldMovePoint.X-15,oldMovePoint.Y-5);g.DrawLine(oldpen,oldMovePoint.X-15,oldMovePoint.Y-15,oldMovePoint.X-5,oldMovePoint.Y-15);g.DrawLine(oldpen,oldMovePoint.X+15,oldMovePoint.Y-15,oldMovePoint.X+5,oldMovePoint.Y-15);g.DrawLine(oldpen,oldMovePoint.X+15,oldMovePoint.Y-15,oldMovePoint.X+15,oldMovePoint.Y-5);g.DrawLine(oldpen,oldMovePoint.X-15,oldMovePoint.Y+15,oldMovePoint.X-15,oldMovePoint.Y+5);g.DrawLine(oldpen,oldMovePoint.X-15,oldMovePoint.Y+15,oldMovePoint.X-5,oldMovePoint.Y+15);g.DrawLine(oldpen,oldMovePoint.X+15,oldMovePoint.Y+15,oldMovePoint.X+15,oldMovePoint.Y+5);g.DrawLine(oldpen,oldMovePoint.X+15,oldMovePoint.Y+15,oldMovePoint.X+5,oldMovePoint.Y+15);}4)下棋子——putqz下棋子有两种可能性,一是知道一个点的横纵坐标;二是知道一个点。下面我就说一说知道x,y坐标的情况,第二种情况只要调用第一种情况就行了。假如下的是一个黑棋子,将qz的背景图设置为blackstone,并将此处标记为已下黑棋,并将此棋子标记为最后落子指示。如果悔棋的栈不为空,将其弹出栈,并将qz的图像设置为什么都没有,再将其压入栈。同理,白旗也跟这一样做。代码如下:if(qzcolor==1){qz[x,y].BackgroundImage=global::五子棋.Properties.Resources.blackstone;points[x,y]=1;qz[x,y].Image=global::五子棋.Properties.Resources.lastblackstone;if(backStack.Count>0){temp=(Point)backStack.Pop();qz[temp.X,temp.Y].Image=global::五子棋.Properties.Resources.nullll;backStack.Push(temp);}}else{qz[x,y].BackgroundImage=global::五子棋.Properties.Resources.whitestone;points[x,y]=0;qz[x,y].Image=global::五子棋.Properties.Resources.lastwhitestone;if(backStack.Count>0){temp=(Point)backStack.Pop();qz[temp.X,temp.Y].Image=global::五子棋.Properties.Resources.nullll;backStack.Push(temp);}}最后将其可见性设置为true。5)开始函数——start当棋局开始时,就应将棋盘初始化,使棋盘上没有棋子。如果有悔棋,就要将悔棋栈清空。代码如下:if(!begin){begin=true;for(x=0;x<15;x++)for(y=0;y<15;y++){qz[x,y].Visible=false;points[x,y]=2;}while(backStack.Count>0)backStack.Pop();}3.5 实现人机对弈的主要函数6)察看两点之间的棋子数函数——ConnectqpCount这个函数主要求两点之间可能形成五连子的qzcolor色棋的连子数(包括活期)。首先,求出两点之间总共的棋子数,并判断棋子所在哪个方向。沿着这个方向每个点的坐标,并察看这几个点中有没有反色的棋子。如果有,棋子数设为0,否则的话,棋子数自加1。代码如下:intx,y,i,j,length,xPlus=0,yPlus=0,sum,maxSum=0;length=Math.Max(Math.Abs(point1.X-point2.X),Math.Abs(point1.Y-point2.Y))+1;if(point1.X!=point2.X)xPlus=1;if(point1.Y!=point2.Y)yPlus=(point2.Y-point1.Y)/Math.Abs(point2.Y-point1.Y);for(i=0;i{x=point1.X+i*xPlus;y=point1.Y+i*yPlus;sum=0;for(j=0;j<5;j++){//察看两点之间当中有没有反色if(points[x+j*xPlus,y+j*yPlus]==qzcolor)sum++;elseif(points[x+j*xPlus,y+j*yPlus]==-qzcolor+1){sum=0;break;}}if(maxSummaxSum=sum;}returnmaxSum;7)察看两点之间是否存在活棋的函数——ActiveConnectqp这个函数主要求两点之间qzcolor色棋是否存在活棋。temp1变量表示在一直线上,比如,一条向下的直线,则表示点point1上方可下的个数;而temp2表示点point2下方可下的个数。代码表示为:temp1=Math.Min(Math.Min(Math.Min(5-count,point1.X),point1.Y),14-point1.Y);temp2=Math.Min(Math.Min(Math.Min(5-count,14-point2.X),14-point2.Y),point2.Y);则长度表示为:length=Math.Max(Math.Abs(point1.X-point2.X),Math.Abs(point1.Y-point2.Y))+1+temp1+temp2;先求两点之间qzcolor色棋的棋子个数,做法和函数ConnectqpCount一样。再判断它是否是活棋。当参数count和所得两点之间qzcolor色棋的棋子个数相等,并且两头都没下棋子时,它为活棋。否则,反之。代码如下:if(point1.X!=point2.X)xPlus=1;if(point1.Y!=point2.Y)yPlus=(point2.Y-point1.Y)/Math.Abs(point2.Y-point1.Y);for(i=0;i{x=point1.X-temp1*xPlus+i*xPlus;y=point1.Y-temp1*yPlus+i*yPlus;if(x+4*xPlus>14||y+4*yPlus>14)break;sum=0;for(j=0;j<4;j++){if(points[x+j*xPlus,y+j*yPlus]==qzcolor)sum++;elseif(points[x+j*xPlus,y+j*yPlus]==-qzcolor+1){sum=0;break;}}if(0{if(sum==count&&points[x-xPlus,y-yPlus]==2&&points[x+4*xPlus,y+4*yPlus]==2)returntrue;}}8)查看是否被破坏活期——BreakActiveConnectqp在(x,y)处放qzcolor色棋后形成活count,且放一反色棋后破坏棋形成活count。代码如下:if(!ActiveConnectqp(qzcolor,count,point1,point2))returnfalse;if(count==5)returnfalse;elseif(count==4)returntrue;else{boolblnFlag;points[x,y]=-qzcolor+1;blnFlag=!ActiveConnectqp(qzcolor,count-1,point1,point2);points[x,y]=qzcolor;returnblnFlag;}9)查看是否是最好的点——FindBestPoint首先,查看有没有最佳点,并形成栈元素。如果没有,返回false;否则,将这栈元素压入回溯栈中。当栈非空时,将栈元素弹出,如果栈中的pointNumber小于pointCount时,在棋盘上下一棋。如果赢棋,不再继续探测,并在棋盘上退一棋。如果和棋的话,也不再继续探测,并在棋盘上退一棋。否则,继续下棋并探测。如果栈顶元素无点,弹出后栈必非空,并在棋盘上退一棋。如果栈顶元素中点均已试过,则寻找栈顶元素中点的最好结局,并寻找最佳步数。实现的代码如下:resulttotalresult=result.lose;inti,bestStepNumber=0;StackElementtempStackElement=newStackElement();if(first){qzcolor=0;if(!FindBestFivePointsAndFormAStackElement(qzcolor,reftempStackElement))returnfalse;}else{qzcolor=1;if(!FindBestFivePointsAndFormAStackElement(qzcolor,reftempStackElement))returnfalse;}backTrackStack.Push(tempStackElement);while(backTrackStack.Count>0)//栈非空{tempStackElement=(StackElement)backTrackStack.Pop();if(tempStackElement.pointNumber{//在棋盘上下一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=tempStackElement.qzColor;if(Win(tempStackElement.qzColor,tempStackElement.bestFivePoints[tempStackElement.pointNumber])){//赢棋,不在继续探测tempStackElement.theresult[tempStackElement.pointNumber]=result.win;tempStackElement.stepNumber[tempStackElement.pointNumber]=backTrackStack.Count+1;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=2;tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);}elseif(backTrackStack.Count==M-1){//将此元素压入栈后栈满,不在继续探测tempStackElement.theresult[tempStackElement.pointNumber]=result.equal;tempStackElement.stepNumber[tempStackElement.pointNumber]=M;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=2;tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);}else{//另一方继续下棋向下探测tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);FindBestFivePointsAndFormAStackElement(-tempStackElement.qzColor+1,reftempStackElement);backTrackStack.Push(tempStackElement);}}//endifelse//栈顶元素无点或点均已试过{if(tempStackElement.pointsCount==0)//栈顶元素无点,且弹出后栈必非空{tempStackElement=(StackElement)backTrackStack.Pop();tempStackElement.theresult[tempStackElement.pointNumber-1]=result.win;tempStackElement.stepNumber[tempStackElement.pointNumber-1]=backTrackStack.Count+1;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber-1].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber-1].Y]=2;backTrackStack.Push(tempStackElement);}else//栈顶元素中点均已试过{//寻找栈顶元素中点的最好结局totalresult=tempStackElement.theresult[0];for(i=0;iif(totalresulttotalresult=tem
x=((e.X-10)/40)*40+30;
y=((e.Y-10)/40)*40+50;
g.DrawLine(newpen,x-15,y-15,x-15,y-5);
g.DrawLine(newpen,x-15,y-15,x-5,y-15);
g.DrawLine(newpen,x+15,y-15,x+5,y-15);
g.DrawLine(newpen,x+15,y-15,x+15,y-5);
g.DrawLine(newpen,x-15,y+15,x-15,y+5);
g.DrawLine(newpen,x-15,y+15,x-5,y+15);
g.DrawLine(newpen,x+15,y+15,x+15,y+5);
g.DrawLine(newpen,x+15,y+15,x+5,y+15);
oldMovePoint.X=x;
oldMovePoint.Y=y;
过去的方框代码如下:
if(oldMovePoint.X!
=-1)
g.DrawLine(oldpen,oldMovePoint.X-15,oldMovePoint.Y-15,oldMovePoint.X-15,oldMovePoint.Y-5);
g.DrawLine(oldpen,oldMovePoint.X-15,oldMovePoint.Y-15,oldMovePoint.X-5,oldMovePoint.Y-15);
g.DrawLine(oldpen,oldMovePoint.X+15,oldMovePoint.Y-15,oldMovePoint.X+5,oldMovePoint.Y-15);
g.DrawLine(oldpen,oldMovePoint.X+15,oldMovePoint.Y-15,oldMovePoint.X+15,oldMovePoint.Y-5);
g.DrawLine(oldpen,oldMovePoint.X-15,oldMovePoint.Y+15,oldMovePoint.X-15,oldMovePoint.Y+5);
g.DrawLine(oldpen,oldMovePoint.X-15,oldMovePoint.Y+15,oldMovePoint.X-5,oldMovePoint.Y+15);
g.DrawLine(oldpen,oldMovePoint.X+15,oldMovePoint.Y+15,oldMovePoint.X+15,oldMovePoint.Y+5);
g.DrawLine(oldpen,oldMovePoint.X+15,oldMovePoint.Y+15,oldMovePoint.X+5,oldMovePoint.Y+15);
4)下棋子——putqz
下棋子有两种可能性,一是知道一个点的横纵坐标;二是知道一个点。
下面我就说一说知道x,y坐标的情况,第二种情况只要调用第一种情况就行了。
假如下的是一个黑棋子,将qz的背景图设置为blackstone,并将此处标记为已下黑棋,并将此棋子标记为最后落子指示。
如果悔棋的栈不为空,将其弹出栈,并将qz的图像设置为什么都没有,再将其压入栈。
同理,白旗也跟这一样做。
代码如下:
if(qzcolor==1)
qz[x,y].BackgroundImage=global:
:
五子棋.Properties.Resources.blackstone;
points[x,y]=1;
qz[x,y].Image=global:
五子棋.Properties.Resources.lastblackstone;
if(backStack.Count>0)
temp=(Point)backStack.Pop();
qz[temp.X,temp.Y].Image=global:
五子棋.Properties.Resources.nullll;
backStack.Push(temp);
else
五子棋.Properties.Resources.whitestone;
points[x,y]=0;
五子棋.Properties.Resources.lastwhitestone;
最后将其可见性设置为true。
5)开始函数——start
当棋局开始时,就应将棋盘初始化,使棋盘上没有棋子。
如果有悔棋,就要将悔棋栈清空。
代码如下:
if(!
begin)
begin=true;
for(x=0;x<15;x++)
for(y=0;y<15;y++)
qz[x,y].Visible=false;
points[x,y]=2;
while(backStack.Count>0)
backStack.Pop();
3.5 实现人机对弈的主要函数
6)察看两点之间的棋子数函数——ConnectqpCount
这个函数主要求两点之间可能形成五连子的qzcolor色棋的连子数(包括活期)。
首先,求出两点之间总共的棋子数,并判断棋子所在哪个方向。
沿着这个方向每个点的坐标,并察看这几个点中有没有反色的棋子。
如果有,棋子数设为0,否则的话,棋子数自加1。
intx,y,i,j,length,xPlus=0,yPlus=0,sum,maxSum=0;
length=Math.Max(Math.Abs(point1.X-point2.X),Math.Abs(point1.Y-point2.Y))+1;
if(point1.X!
=point2.X)xPlus=1;
if(point1.Y!
=point2.Y)yPlus=(point2.Y-point1.Y)/Math.Abs(point2.Y-point1.Y);
for(i=0;i{x=point1.X+i*xPlus;y=point1.Y+i*yPlus;sum=0;for(j=0;j<5;j++){//察看两点之间当中有没有反色if(points[x+j*xPlus,y+j*yPlus]==qzcolor)sum++;elseif(points[x+j*xPlus,y+j*yPlus]==-qzcolor+1){sum=0;break;}}if(maxSummaxSum=sum;}returnmaxSum;7)察看两点之间是否存在活棋的函数——ActiveConnectqp这个函数主要求两点之间qzcolor色棋是否存在活棋。temp1变量表示在一直线上,比如,一条向下的直线,则表示点point1上方可下的个数;而temp2表示点point2下方可下的个数。代码表示为:temp1=Math.Min(Math.Min(Math.Min(5-count,point1.X),point1.Y),14-point1.Y);temp2=Math.Min(Math.Min(Math.Min(5-count,14-point2.X),14-point2.Y),point2.Y);则长度表示为:length=Math.Max(Math.Abs(point1.X-point2.X),Math.Abs(point1.Y-point2.Y))+1+temp1+temp2;先求两点之间qzcolor色棋的棋子个数,做法和函数ConnectqpCount一样。再判断它是否是活棋。当参数count和所得两点之间qzcolor色棋的棋子个数相等,并且两头都没下棋子时,它为活棋。否则,反之。代码如下:if(point1.X!=point2.X)xPlus=1;if(point1.Y!=point2.Y)yPlus=(point2.Y-point1.Y)/Math.Abs(point2.Y-point1.Y);for(i=0;i{x=point1.X-temp1*xPlus+i*xPlus;y=point1.Y-temp1*yPlus+i*yPlus;if(x+4*xPlus>14||y+4*yPlus>14)break;sum=0;for(j=0;j<4;j++){if(points[x+j*xPlus,y+j*yPlus]==qzcolor)sum++;elseif(points[x+j*xPlus,y+j*yPlus]==-qzcolor+1){sum=0;break;}}if(0{if(sum==count&&points[x-xPlus,y-yPlus]==2&&points[x+4*xPlus,y+4*yPlus]==2)returntrue;}}8)查看是否被破坏活期——BreakActiveConnectqp在(x,y)处放qzcolor色棋后形成活count,且放一反色棋后破坏棋形成活count。代码如下:if(!ActiveConnectqp(qzcolor,count,point1,point2))returnfalse;if(count==5)returnfalse;elseif(count==4)returntrue;else{boolblnFlag;points[x,y]=-qzcolor+1;blnFlag=!ActiveConnectqp(qzcolor,count-1,point1,point2);points[x,y]=qzcolor;returnblnFlag;}9)查看是否是最好的点——FindBestPoint首先,查看有没有最佳点,并形成栈元素。如果没有,返回false;否则,将这栈元素压入回溯栈中。当栈非空时,将栈元素弹出,如果栈中的pointNumber小于pointCount时,在棋盘上下一棋。如果赢棋,不再继续探测,并在棋盘上退一棋。如果和棋的话,也不再继续探测,并在棋盘上退一棋。否则,继续下棋并探测。如果栈顶元素无点,弹出后栈必非空,并在棋盘上退一棋。如果栈顶元素中点均已试过,则寻找栈顶元素中点的最好结局,并寻找最佳步数。实现的代码如下:resulttotalresult=result.lose;inti,bestStepNumber=0;StackElementtempStackElement=newStackElement();if(first){qzcolor=0;if(!FindBestFivePointsAndFormAStackElement(qzcolor,reftempStackElement))returnfalse;}else{qzcolor=1;if(!FindBestFivePointsAndFormAStackElement(qzcolor,reftempStackElement))returnfalse;}backTrackStack.Push(tempStackElement);while(backTrackStack.Count>0)//栈非空{tempStackElement=(StackElement)backTrackStack.Pop();if(tempStackElement.pointNumber{//在棋盘上下一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=tempStackElement.qzColor;if(Win(tempStackElement.qzColor,tempStackElement.bestFivePoints[tempStackElement.pointNumber])){//赢棋,不在继续探测tempStackElement.theresult[tempStackElement.pointNumber]=result.win;tempStackElement.stepNumber[tempStackElement.pointNumber]=backTrackStack.Count+1;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=2;tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);}elseif(backTrackStack.Count==M-1){//将此元素压入栈后栈满,不在继续探测tempStackElement.theresult[tempStackElement.pointNumber]=result.equal;tempStackElement.stepNumber[tempStackElement.pointNumber]=M;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=2;tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);}else{//另一方继续下棋向下探测tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);FindBestFivePointsAndFormAStackElement(-tempStackElement.qzColor+1,reftempStackElement);backTrackStack.Push(tempStackElement);}}//endifelse//栈顶元素无点或点均已试过{if(tempStackElement.pointsCount==0)//栈顶元素无点,且弹出后栈必非空{tempStackElement=(StackElement)backTrackStack.Pop();tempStackElement.theresult[tempStackElement.pointNumber-1]=result.win;tempStackElement.stepNumber[tempStackElement.pointNumber-1]=backTrackStack.Count+1;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber-1].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber-1].Y]=2;backTrackStack.Push(tempStackElement);}else//栈顶元素中点均已试过{//寻找栈顶元素中点的最好结局totalresult=tempStackElement.theresult[0];for(i=0;iif(totalresulttotalresult=tem
x=point1.X+i*xPlus;
y=point1.Y+i*yPlus;
sum=0;
for(j=0;j<5;j++)
{//察看两点之间当中有没有反色
if(points[x+j*xPlus,y+j*yPlus]==qzcolor)
sum++;
elseif(points[x+j*xPlus,y+j*yPlus]==-qzcolor+1)
break;
if(maxSummaxSum=sum;}returnmaxSum;7)察看两点之间是否存在活棋的函数——ActiveConnectqp这个函数主要求两点之间qzcolor色棋是否存在活棋。temp1变量表示在一直线上,比如,一条向下的直线,则表示点point1上方可下的个数;而temp2表示点point2下方可下的个数。代码表示为:temp1=Math.Min(Math.Min(Math.Min(5-count,point1.X),point1.Y),14-point1.Y);temp2=Math.Min(Math.Min(Math.Min(5-count,14-point2.X),14-point2.Y),point2.Y);则长度表示为:length=Math.Max(Math.Abs(point1.X-point2.X),Math.Abs(point1.Y-point2.Y))+1+temp1+temp2;先求两点之间qzcolor色棋的棋子个数,做法和函数ConnectqpCount一样。再判断它是否是活棋。当参数count和所得两点之间qzcolor色棋的棋子个数相等,并且两头都没下棋子时,它为活棋。否则,反之。代码如下:if(point1.X!=point2.X)xPlus=1;if(point1.Y!=point2.Y)yPlus=(point2.Y-point1.Y)/Math.Abs(point2.Y-point1.Y);for(i=0;i{x=point1.X-temp1*xPlus+i*xPlus;y=point1.Y-temp1*yPlus+i*yPlus;if(x+4*xPlus>14||y+4*yPlus>14)break;sum=0;for(j=0;j<4;j++){if(points[x+j*xPlus,y+j*yPlus]==qzcolor)sum++;elseif(points[x+j*xPlus,y+j*yPlus]==-qzcolor+1){sum=0;break;}}if(0{if(sum==count&&points[x-xPlus,y-yPlus]==2&&points[x+4*xPlus,y+4*yPlus]==2)returntrue;}}8)查看是否被破坏活期——BreakActiveConnectqp在(x,y)处放qzcolor色棋后形成活count,且放一反色棋后破坏棋形成活count。代码如下:if(!ActiveConnectqp(qzcolor,count,point1,point2))returnfalse;if(count==5)returnfalse;elseif(count==4)returntrue;else{boolblnFlag;points[x,y]=-qzcolor+1;blnFlag=!ActiveConnectqp(qzcolor,count-1,point1,point2);points[x,y]=qzcolor;returnblnFlag;}9)查看是否是最好的点——FindBestPoint首先,查看有没有最佳点,并形成栈元素。如果没有,返回false;否则,将这栈元素压入回溯栈中。当栈非空时,将栈元素弹出,如果栈中的pointNumber小于pointCount时,在棋盘上下一棋。如果赢棋,不再继续探测,并在棋盘上退一棋。如果和棋的话,也不再继续探测,并在棋盘上退一棋。否则,继续下棋并探测。如果栈顶元素无点,弹出后栈必非空,并在棋盘上退一棋。如果栈顶元素中点均已试过,则寻找栈顶元素中点的最好结局,并寻找最佳步数。实现的代码如下:resulttotalresult=result.lose;inti,bestStepNumber=0;StackElementtempStackElement=newStackElement();if(first){qzcolor=0;if(!FindBestFivePointsAndFormAStackElement(qzcolor,reftempStackElement))returnfalse;}else{qzcolor=1;if(!FindBestFivePointsAndFormAStackElement(qzcolor,reftempStackElement))returnfalse;}backTrackStack.Push(tempStackElement);while(backTrackStack.Count>0)//栈非空{tempStackElement=(StackElement)backTrackStack.Pop();if(tempStackElement.pointNumber{//在棋盘上下一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=tempStackElement.qzColor;if(Win(tempStackElement.qzColor,tempStackElement.bestFivePoints[tempStackElement.pointNumber])){//赢棋,不在继续探测tempStackElement.theresult[tempStackElement.pointNumber]=result.win;tempStackElement.stepNumber[tempStackElement.pointNumber]=backTrackStack.Count+1;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=2;tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);}elseif(backTrackStack.Count==M-1){//将此元素压入栈后栈满,不在继续探测tempStackElement.theresult[tempStackElement.pointNumber]=result.equal;tempStackElement.stepNumber[tempStackElement.pointNumber]=M;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=2;tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);}else{//另一方继续下棋向下探测tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);FindBestFivePointsAndFormAStackElement(-tempStackElement.qzColor+1,reftempStackElement);backTrackStack.Push(tempStackElement);}}//endifelse//栈顶元素无点或点均已试过{if(tempStackElement.pointsCount==0)//栈顶元素无点,且弹出后栈必非空{tempStackElement=(StackElement)backTrackStack.Pop();tempStackElement.theresult[tempStackElement.pointNumber-1]=result.win;tempStackElement.stepNumber[tempStackElement.pointNumber-1]=backTrackStack.Count+1;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber-1].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber-1].Y]=2;backTrackStack.Push(tempStackElement);}else//栈顶元素中点均已试过{//寻找栈顶元素中点的最好结局totalresult=tempStackElement.theresult[0];for(i=0;iif(totalresulttotalresult=tem
maxSum=sum;
returnmaxSum;
7)察看两点之间是否存在活棋的函数——ActiveConnectqp
这个函数主要求两点之间qzcolor色棋是否存在活棋。
temp1变量表示在一直线上,比如,一条向下的直线,则表示点point1上方可下的个数;而temp2表示点point2下方可下的个数。
代码表示为:
temp1=Math.Min(Math.Min(Math.Min(5-count,point1.X),point1.Y),14-point1.Y);
temp2=Math.Min(Math.Min(Math.Min(5-count,14-point2.X),14-point2.Y),point2.Y);
则长度表示为:
length=Math.Max(Math.Abs(point1.X-point2.X),Math.Abs(point1.Y-point2.Y))+1+temp1+temp2;
先求两点之间qzcolor色棋的棋子个数,做法和函数ConnectqpCount一样。
再判断它是否是活棋。
当参数count和所得两点之间qzcolor色棋的棋子个数相等,并且两头都没下棋子时,它为活棋。
否则,反之。
for(i=0;i{x=point1.X-temp1*xPlus+i*xPlus;y=point1.Y-temp1*yPlus+i*yPlus;if(x+4*xPlus>14||y+4*yPlus>14)break;sum=0;for(j=0;j<4;j++){if(points[x+j*xPlus,y+j*yPlus]==qzcolor)sum++;elseif(points[x+j*xPlus,y+j*yPlus]==-qzcolor+1){sum=0;break;}}if(0{if(sum==count&&points[x-xPlus,y-yPlus]==2&&points[x+4*xPlus,y+4*yPlus]==2)returntrue;}}8)查看是否被破坏活期——BreakActiveConnectqp在(x,y)处放qzcolor色棋后形成活count,且放一反色棋后破坏棋形成活count。代码如下:if(!ActiveConnectqp(qzcolor,count,point1,point2))returnfalse;if(count==5)returnfalse;elseif(count==4)returntrue;else{boolblnFlag;points[x,y]=-qzcolor+1;blnFlag=!ActiveConnectqp(qzcolor,count-1,point1,point2);points[x,y]=qzcolor;returnblnFlag;}9)查看是否是最好的点——FindBestPoint首先,查看有没有最佳点,并形成栈元素。如果没有,返回false;否则,将这栈元素压入回溯栈中。当栈非空时,将栈元素弹出,如果栈中的pointNumber小于pointCount时,在棋盘上下一棋。如果赢棋,不再继续探测,并在棋盘上退一棋。如果和棋的话,也不再继续探测,并在棋盘上退一棋。否则,继续下棋并探测。如果栈顶元素无点,弹出后栈必非空,并在棋盘上退一棋。如果栈顶元素中点均已试过,则寻找栈顶元素中点的最好结局,并寻找最佳步数。实现的代码如下:resulttotalresult=result.lose;inti,bestStepNumber=0;StackElementtempStackElement=newStackElement();if(first){qzcolor=0;if(!FindBestFivePointsAndFormAStackElement(qzcolor,reftempStackElement))returnfalse;}else{qzcolor=1;if(!FindBestFivePointsAndFormAStackElement(qzcolor,reftempStackElement))returnfalse;}backTrackStack.Push(tempStackElement);while(backTrackStack.Count>0)//栈非空{tempStackElement=(StackElement)backTrackStack.Pop();if(tempStackElement.pointNumber{//在棋盘上下一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=tempStackElement.qzColor;if(Win(tempStackElement.qzColor,tempStackElement.bestFivePoints[tempStackElement.pointNumber])){//赢棋,不在继续探测tempStackElement.theresult[tempStackElement.pointNumber]=result.win;tempStackElement.stepNumber[tempStackElement.pointNumber]=backTrackStack.Count+1;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=2;tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);}elseif(backTrackStack.Count==M-1){//将此元素压入栈后栈满,不在继续探测tempStackElement.theresult[tempStackElement.pointNumber]=result.equal;tempStackElement.stepNumber[tempStackElement.pointNumber]=M;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=2;tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);}else{//另一方继续下棋向下探测tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);FindBestFivePointsAndFormAStackElement(-tempStackElement.qzColor+1,reftempStackElement);backTrackStack.Push(tempStackElement);}}//endifelse//栈顶元素无点或点均已试过{if(tempStackElement.pointsCount==0)//栈顶元素无点,且弹出后栈必非空{tempStackElement=(StackElement)backTrackStack.Pop();tempStackElement.theresult[tempStackElement.pointNumber-1]=result.win;tempStackElement.stepNumber[tempStackElement.pointNumber-1]=backTrackStack.Count+1;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber-1].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber-1].Y]=2;backTrackStack.Push(tempStackElement);}else//栈顶元素中点均已试过{//寻找栈顶元素中点的最好结局totalresult=tempStackElement.theresult[0];for(i=0;iif(totalresulttotalresult=tem
x=point1.X-temp1*xPlus+i*xPlus;
y=point1.Y-temp1*yPlus+i*yPlus;
if(x+4*xPlus>14||y+4*yPlus>14)
for(j=0;j<4;j++)
if(0{if(sum==count&&points[x-xPlus,y-yPlus]==2&&points[x+4*xPlus,y+4*yPlus]==2)returntrue;}}8)查看是否被破坏活期——BreakActiveConnectqp在(x,y)处放qzcolor色棋后形成活count,且放一反色棋后破坏棋形成活count。代码如下:if(!ActiveConnectqp(qzcolor,count,point1,point2))returnfalse;if(count==5)returnfalse;elseif(count==4)returntrue;else{boolblnFlag;points[x,y]=-qzcolor+1;blnFlag=!ActiveConnectqp(qzcolor,count-1,point1,point2);points[x,y]=qzcolor;returnblnFlag;}9)查看是否是最好的点——FindBestPoint首先,查看有没有最佳点,并形成栈元素。如果没有,返回false;否则,将这栈元素压入回溯栈中。当栈非空时,将栈元素弹出,如果栈中的pointNumber小于pointCount时,在棋盘上下一棋。如果赢棋,不再继续探测,并在棋盘上退一棋。如果和棋的话,也不再继续探测,并在棋盘上退一棋。否则,继续下棋并探测。如果栈顶元素无点,弹出后栈必非空,并在棋盘上退一棋。如果栈顶元素中点均已试过,则寻找栈顶元素中点的最好结局,并寻找最佳步数。实现的代码如下:resulttotalresult=result.lose;inti,bestStepNumber=0;StackElementtempStackElement=newStackElement();if(first){qzcolor=0;if(!FindBestFivePointsAndFormAStackElement(qzcolor,reftempStackElement))returnfalse;}else{qzcolor=1;if(!FindBestFivePointsAndFormAStackElement(qzcolor,reftempStackElement))returnfalse;}backTrackStack.Push(tempStackElement);while(backTrackStack.Count>0)//栈非空{tempStackElement=(StackElement)backTrackStack.Pop();if(tempStackElement.pointNumber{//在棋盘上下一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=tempStackElement.qzColor;if(Win(tempStackElement.qzColor,tempStackElement.bestFivePoints[tempStackElement.pointNumber])){//赢棋,不在继续探测tempStackElement.theresult[tempStackElement.pointNumber]=result.win;tempStackElement.stepNumber[tempStackElement.pointNumber]=backTrackStack.Count+1;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=2;tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);}elseif(backTrackStack.Count==M-1){//将此元素压入栈后栈满,不在继续探测tempStackElement.theresult[tempStackElement.pointNumber]=result.equal;tempStackElement.stepNumber[tempStackElement.pointNumber]=M;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=2;tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);}else{//另一方继续下棋向下探测tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);FindBestFivePointsAndFormAStackElement(-tempStackElement.qzColor+1,reftempStackElement);backTrackStack.Push(tempStackElement);}}//endifelse//栈顶元素无点或点均已试过{if(tempStackElement.pointsCount==0)//栈顶元素无点,且弹出后栈必非空{tempStackElement=(StackElement)backTrackStack.Pop();tempStackElement.theresult[tempStackElement.pointNumber-1]=result.win;tempStackElement.stepNumber[tempStackElement.pointNumber-1]=backTrackStack.Count+1;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber-1].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber-1].Y]=2;backTrackStack.Push(tempStackElement);}else//栈顶元素中点均已试过{//寻找栈顶元素中点的最好结局totalresult=tempStackElement.theresult[0];for(i=0;iif(totalresulttotalresult=tem
if(sum==count&&points[x-xPlus,y-yPlus]==2&&points[x+4*xPlus,y+4*yPlus]==2)
returntrue;
8)查看是否被破坏活期——BreakActiveConnectqp
在(x,y)处放qzcolor色棋后形成活count,且放一反色棋后破坏棋形成活count。
ActiveConnectqp(qzcolor,count,point1,point2))returnfalse;
if(count==5)returnfalse;
elseif(count==4)returntrue;
boolblnFlag;
points[x,y]=-qzcolor+1;
blnFlag=!
ActiveConnectqp(qzcolor,count-1,point1,point2);
points[x,y]=qzcolor;
returnblnFlag;
9)查看是否是最好的点——FindBestPoint
首先,查看有没有最佳点,并形成栈元素。
如果没有,返回false;否则,将这栈元素压入回溯栈中。
当栈非空时,将栈元素弹出,如果栈中的pointNumber小于pointCount时,在棋盘上下一棋。
如果赢棋,不再继续探测,并在棋盘上退一棋。
如果和棋的话,也不再继续探测,并在棋盘上退一棋。
否则,继续下棋并探测。
如果栈顶元素无点,弹出后栈必非空,并在棋盘上退一棋。
如果栈顶元素中点均已试过,则寻找栈顶元素中点的最好结局,并寻找最佳步数。
实现的代码如下:
resulttotalresult=result.lose;
inti,bestStepNumber=0;
StackElementtempStackElement=newStackElement();
if(first)
qzcolor=0;
FindBestFivePointsAndFormAStackElement(qzcolor,reftempStackElement))
returnfalse;
qzcolor=1;
backTrackStack.Push(tempStackElement);
while(backTrackStack.Count>0)//栈非空
tempStackElement=(StackElement)backTrackStack.Pop();
if(tempStackElement.pointNumber{//在棋盘上下一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=tempStackElement.qzColor;if(Win(tempStackElement.qzColor,tempStackElement.bestFivePoints[tempStackElement.pointNumber])){//赢棋,不在继续探测tempStackElement.theresult[tempStackElement.pointNumber]=result.win;tempStackElement.stepNumber[tempStackElement.pointNumber]=backTrackStack.Count+1;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=2;tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);}elseif(backTrackStack.Count==M-1){//将此元素压入栈后栈满,不在继续探测tempStackElement.theresult[tempStackElement.pointNumber]=result.equal;tempStackElement.stepNumber[tempStackElement.pointNumber]=M;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=2;tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);}else{//另一方继续下棋向下探测tempStackElement.pointNumber++;backTrackStack.Push(tempStackElement);FindBestFivePointsAndFormAStackElement(-tempStackElement.qzColor+1,reftempStackElement);backTrackStack.Push(tempStackElement);}}//endifelse//栈顶元素无点或点均已试过{if(tempStackElement.pointsCount==0)//栈顶元素无点,且弹出后栈必非空{tempStackElement=(StackElement)backTrackStack.Pop();tempStackElement.theresult[tempStackElement.pointNumber-1]=result.win;tempStackElement.stepNumber[tempStackElement.pointNumber-1]=backTrackStack.Count+1;//在棋盘上退一棋points[tempStackElement.bestFivePoints[tempStackElement.pointNumber-1].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber-1].Y]=2;backTrackStack.Push(tempStackElement);}else//栈顶元素中点均已试过{//寻找栈顶元素中点的最好结局totalresult=tempStackElement.theresult[0];for(i=0;iif(totalresulttotalresult=tem
//在棋盘上下一棋
points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=tempStackElement.qzColor;
if(Win(tempStackElement.qzColor,tempStackElement.bestFivePoints[tempStackElement.pointNumber]))
{//赢棋,不在继续探测
tempStackElement.theresult[tempStackElement.pointNumber]=result.win;
tempStackElement.stepNumber[tempStackElement.pointNumber]=backTrackStack.Count+1;
//在棋盘上退一棋
points[tempStackElement.bestFivePoints[tempStackElement.pointNumber].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber].Y]=2;
tempStackElement.pointNumber++;
elseif(backTrackStack.Count==M-1)
{//将此元素压入栈后栈满,不在继续探测
tempStackElement.theresult[tempStackElement.pointNumber]=result.equal;
tempStackElement.stepNumber[tempStackElement.pointNumber]=M;
{//另一方继续下棋向下探测
FindBestFivePointsAndFormAStackElement(-tempStackElement.qzColor+1,reftempStackElement);
}//endif
else//栈顶元素无点或点均已试过
if(tempStackElement.pointsCount==0)//栈顶元素无点,且弹出后栈必非空
tempStackElement.theresult[tempStackElement.pointNumber-1]=result.win;
tempStackElement.stepNumber[tempStackElement.pointNumber-1]=backTrackStack.Count+1;
points[tempStackElement.bestFivePoints[tempStackElement.pointNumber-1].X,tempStackElement.bestFivePoints[tempStackElement.pointNumber-1].Y]=2;
else//栈顶元素中点均已试过
//寻找栈顶元素中点的最好结局
totalresult=tempStackElement.theresult[0];
for(i=0;iif(totalresulttotalresult=tem
if(totalresulttotalresult=tem
totalresult=tem
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1