郑州科技学院课程设计论文基于C#的五子棋游戏的设计与实现学生姓名:王新年学号:201015066年级专业:10级计科二班指导老师:王玉萍学院:信息工程学院1 引言 (1)1.1 五子棋介绍 (1)2 软件架构 (1)3 五子棋设计说明 (2)3.1 主要成员变量说明 (2)3.2 回溯栈元素类——StackElement (3)3.3 棋子点属性类——qzdianshuxing (3)3.4 主要成员函数说明 (3)3.5 实现人机对弈的主要函数 (7)3.6 实现菜单功能的函数 (26)3.6 程序运行界面 (30)4 心得体会 (311)1 引言1.1 五子棋介绍五子棋是起源于中国古代的传统黑白棋种之一。
现代五子棋日文称之为“連珠”,英译为“Renju ”,英文称之为“Gobang ”或“FIR ”(Five in a Row 的缩写),亦有“连五子”、“五子连”、“串珠”、“五目”、“五目碰”、“五格”等多种称谓。
五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。
五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴阳易理”;它既有简单易学的特性,为人民群众所喜闻乐见,又有深奥的技巧和高水平的国际性比赛;它的棋文化源渊流长,具有东方的神秘和西方的直观;既有“场”的概念,亦有“点”的连接。
它是中西文化的交流点,是古今哲理的结晶。
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)棋盘数据——pointspoints为棋盘情况数组,是用一个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用枚举类型来表示结局。
如:public enum result : 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 < e.X && 10< e.Y &&e.X <ClientRectangle.Width && e.Y <ClientRectangle.Height){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::五子棋stblackstone;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::五子棋stwhitestone;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色棋的连子数(包括活期)。