1、实验报告实验一 五子棋游戏北方工业大学 2013级 计算机技术 米鹏一、实验原理及方法五子棋游戏开发借用Visual Studio 2012软件开发平台,选用C#语言进行编写。整体程序主要分为三部分:界面操作部分、AI逻辑部分和棋子定点分析部分。1、界面操作部分界面操作部分代码主要针对图像呈现、对应矩阵存储、下棋过程控制等可见的操作环节进编写。同时负责整个程序的初始化工作。图像呈现采用C#中Graphics进行绘制。棋盘被划分为15行15列,每个划分出的小方格均为30*30的正方形,棋盘可操作的范围规定在(20,20)、(460,460)两点的确定的正方形区域内。通过鼠标左击来确定下子地点。程
2、序会根据鼠标鼠标点击的位置进行计算,计算得到时对应矩阵的行列,之后再改变对应矩阵的内容后,在通过行列值乘以小方格边长计算得到在显示区域中的具体位置,再稍加变动后画到显示区域中。以X点坐标为例,下面是计算X(Column)的流程图:在对应矩阵存储方面,后面AI逻辑和棋子分析所用到的矩阵都是来源这里。同时AI逻辑和棋子分析不能去修改对应矩阵内容。图像呈现点的位置、重绘的根据都是来源这里。在下棋过程控制方面采用信号亮的机制,当操作者下过后,根据信号AI会立即计算将要下点的位置同时改变信号亮变量。当AI下过棋子后,由于信号亮的的限制就等待操作者去下棋,同时改变信号亮变量内容。AI和操作者的所有下子、修
3、改矩阵、显示棋子的过程都是统一的。在每一盘游戏开始时程序会对一些重要的变量进行初始化这里包括矩阵、信号亮、第一步棋子颜色、呈现图像等内容进行初始化。同时AI会在棋盘中央下第一子。2、AI逻辑部分AI逻辑部分算是整个程序策略的灵魂。其中的一些关键性判别的前后关系将影响AI的下棋的结果。同时加大和降低AI的难度也是这里。下面是我设计的策略过程:从下棋者的考虑角度进行考虑,尽可能保证每一次下子都是有必要的、都是在情理当中的。我所设计的策略并不是完整,漏洞在与没有考虑三棋子连续的情况。3、棋子定点分析部分棋子定点分析部分是这个程序策略的支撑。分析的正确与否直接影响AI下子是否真的有意义、是否真的可以达
4、到所需目的。这里的代码也是最复杂。这里包括了检测是否输赢的五棋子连续的状态、四子状态(再补一子,五子连续)存在与否、每个棋子的上到下、左到右、左上到右下、右上到左下,四个方向上棋子排列情况和可落子情况,同时分析出落子情况的优先级。对于优先级较高额在AI逻辑部分会优先选择下子。下面列举在从左到右这个方向上可下子的区域情况流程图:二、源程序清单:1、界面操作部分代码:word文档 可自由复制编辑public partial class Form1 : Formbool isBlack = true;bool IsAI = true;int, bg = 0, 0, 0, 0, 0, 0, 0, 0,
5、 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, 0, 0, 0, 0, 0, 0 , 0
6、, 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, 0, 0, 0, 0, 0, 0, 0
7、, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;int change = 0;public Form1()InitializeComponent();this.Width = 497;private void InitPanel()int index = 60;Graphics gs = panel1.CreateGraphics();Pen myPen = new Pen(Color.Black, 2);gs.DrawLine(myPen, new Point(30, 30), new Point(30, 4
8、50);gs.DrawLine(myPen, new Point(30, 30), new Point(450, 30);gs.DrawLine(myPen, new Point(450, 30), new Point(450, 450);gs.DrawLine(myPen, new Point(30, 450), new Point(450, 450);myPen.Width = 1;while (index = 420) gs.DrawLine(myPen, new Point(30, index), new Point(450, index); gs.DrawLine(myPen, ne
9、w Point(index, 30), new Point(index, 450); index += 30;SolidBrush bursh = new SolidBrush(Color.Black);gs.FillEllipse(bursh, 240 - 4, 240 - 4, 8, 8);for (int i = 0; i 15; i+) for (int j = 0; j 20 & e.X 20 & e.Y 460 & e.Button = MouseButtons.Left)p = e.X % 30;q = e.X / 30;if (q 14) if (q = 15)q = q +
10、1;colume = q;q = e.Y / 30;p = e.Y % 30;if (q 14) if (q 15)q = q + 1;row = q;IsAI = false;this.PutOn(row, colume);2、AI逻辑部分class AI : IsFiveChessmanprotected int AIValue = 0;protected int firstX = -1;protected int firstY = -1;ArrayList listAI = new ArrayList();ArrayList listP = new ArrayList();public
11、AI(int, bg, int value)base.BG = bg;AIValue = value;private void SetFirst(int x, int y, int current)firstX = x;firstY = y;BGx, y = current;private void BackFirst()BGfirstX, firstY = 0;firstX = -1;firstY = -1;private ArrayList SelectCountOfSame(ArrayList list)int i = 0;string tempStr = ;int tempCount
12、= 0;for (i = 0; i list.Count; i+) tempStr = listi.ToString(); for (int j = 0; j list.Count; j+) if (tempStr = listj.ToString() tempCount+; tempStr += # + tempCount.ToString(); listi = tempStr; tempCount = 0; tempStr = ; return list;private ArrayList BetweenSame(ArrayList listA, ArrayList listB)Array
13、List arry = new ArrayList();for (int i = 0; i listA.Count; i+) for (int j = 0; j 0)tempStr = ;tempCount = 0;for (i = 0; i arry.Count; i+) k = 0;SetFirst(Convert.ToInt32(arryi.ToString().Split(#)1), Convert.ToInt32(arryi.ToString().Split(#)2), flag*AIValue); tempStr += this.DirectionA(firstX, firstY,
14、 flag*AIValue); tempStr += this.DirectionB(firstX, firstY, flag*AIValue); tempStr += this.DirectionC(firstX, firstY, flag*AIValue); tempStr += this.DirectionD(firstX, firstY, flag*AIValue);for (j = 0; j tempCount) x = firstX; y = firstY; tempCount = k; BackFirst();if (tempCount counts) return x.ToSt
15、ring() + # + y.ToString();else Random rg = new Random(); i = rg.Next(0, arry.Count - 1); return arryi.ToString().Split(#)1 + # + arryi.ToString().Split(#)2;return ;public string AIMain()int i = 0;int j = 0;int k = 0;string allP = ;string allAI = ;string tempStr = ;ArrayList arry = new ArrayList();#r
16、egion AI可放棋子位置 allAIfor (i = 0; i 15; i+) for (j = 0; j 15; j+) if (BGi, j = AIValue) allAI += this.DirectionA(i, j, AIValue); allAI += this.DirectionB(i, j, AIValue); allAI += this.DirectionC(i, j, AIValue); allAI += this.DirectionD(i, j, AIValue); #endregion#region 人可放棋子位置 allPfor (i = 0; i 15; i+
17、)for (j = 0; j = 0)int TstartIndexOfAI = allAI.IndexOf(T);int TendIndexOfAI = allAI.IndexOf($, TstartIndexOfAI);tempStr = allAI.Substring(TstartIndexOfAI + 2, TendIndexOfAI - TstartIndexOfAI - 2);return tempStr.Split(#)0 + # + tempStr.Split(#)1;#endregion#region 人放子后必赢(五连)if (allP.IndexOf(T) = 0) in
18、t TstartIndexOfP = allP.IndexOf(T); int TendIndexOfP = allP.IndexOf($, TstartIndexOfP); tempStr = allP.Substring(TstartIndexOfP+2, TendIndexOfP - TstartIndexOfP-2); return tempStr.Split(#)0 + # + tempStr.Split(#)1;#endregion#region 可放棋子结果统计string temp = allAI.Split($);for (k = 0; k temp.Length; k+)
19、listAI.Add(tempk);temp = allP.Split($);for (k = 0; k temp.Length; k+) listP.Add(tempk);listAI.RemoveAt(listAI.Count - 1);listP.RemoveAt(listP.Count - 1);listAI = this.SelectCountOfSame(listAI);listP = this.SelectCountOfSame(listP);#endregion#region AI放子后四连arry.Clear();for (i = 0; i listAI.Count; i+)
20、 if (listAIi.ToString()0.ToString() = F) if (arry.Contains(listAIi) = false) arry.Add(listAIi); tempStr = this.Selects(arry, 1,1); if (tempStr != ) arry = null; return tempStr; #endregion#region 人放子后四连 arry.Clear();for (i = 0; i listP.Count; i+) if (listPi.ToString()0.ToString() = F) if (arry.Contai
21、ns(listPi) = false) arry.Add(listPi); tempStr = this.Selects(arry, -1,1); if (tempStr != ) arry = null; return tempStr; #endregion #region 两子内可以四连,同时影响对手落子 arry.Clear(); arry = this.BetweenSame(listAI, listP); tempStr = this.Selects(arry, -1,0); if (tempStr != ) arry = null; return tempStr; #endregion #region 在AI区域内随意落子 Random rg3 = new Random(); i = rg3.Next(0, listAI.Count - 1); return listAIi.ToString().Split(#)1 + # + listAIi.ToString().Split(#)2; #endre