中关村在线官方网站,广州低成本网络营销,学校校园网站使用,editplus网站开发前些天闲时写的,在学数据结构的时拿来练手的.没技术含量,最有技术含量的AI部分,我是看别人(园子里叫二十四生的)的算法改的.刚弄了一下午小程序弄不过去,头疼,现无聊的紧,闲着发着玩.当消遣主要发下AI核心算法.有兴趣的同学用VB,VC.VC#都可以一起做着玩.保持对编程的兴趣.其它没…前些天闲时写的,在学数据结构的时拿来练手的.没技术含量,最有技术含量的AI部分,我是看别人(园子里叫二十四生的)的算法改的.刚弄了一下午小程序弄不过去,头疼,现无聊的紧,闲着发着玩.当消遣主要发下AI核心算法.有兴趣的同学用VB,VC.VC#都可以一起做着玩.保持对编程的兴趣.其它没了. 一,说下五子棋的原理:5子成一线即赢.所以可以这样做,当一子落下时,判断该子是否成5子,下面的代码说的很清楚了 /**//// summary当一棋子落子时检查该色子是否胜利 /// 当一棋子落子时检查该色子是否胜利 /// /summary /// param namechessPoint落子位置/param /// param namecolor棋子色/param /// returnsbool/returns /// 把棋子分8个方向计算 /// 2 3 4 /// 1 x,y 5 /// 8 7 6 public bool CheckeWin(ChessPoint chessPoint, CheckerColor color) //检查是否胜利 { int X chessPoint.X; int Y chessPoint.Y; int times 1; int tempX X - 1; int tempY Y; /**///检查 1 方向// while (true) { if (NextHasChecker(tempX, tempY, 1, color)) { times; tempX--; continue; } else break; } /**/////检查 5 方向//// tempX X 1; while (true) { if (NextHasChecker(tempX, tempY, 5, color)) { times; tempX; continue; } else break; } if (times 5) return true; /**/////1-5 方向检查完毕 times 1; tempX X; tempY Y - 1; /**///检查 3 方向//// while (true) { if (NextHasChecker(tempX, tempY, 3, color)) { times; tempY--; continue; } else break; } /**///检查 7 方向 tempY Y 1; while (true) { if (NextHasChecker(tempX, tempY, 7, color)) { times; tempY; continue; } else break; } if (times 5) return true; /**//3-7 方向检查完毕//// times 1; tempX X - 1; tempY Y - 1; /**////检查 2 方向 while (true) { if (NextHasChecker(tempX, tempY, 2, color)) { times; tempX--; tempY--; continue; } else break; } tempX X 1; tempY Y 1; /**//检查 6 方向/ while (true) { if (NextHasChecker(tempX, tempY, 6, color)) { times; tempX; tempY; continue; } else break; } if (times 5) return true; /**/2-6方向检查完毕//// times 1; tempX X 1; tempY Y - 1; /**////检查 4 方向 while (true) { if (NextHasChecker(tempX, tempY, 4, color)) { times; tempX; tempY--; continue; } else break; } tempX X - 1; tempY Y 1; /**////检查 8 方向/ while (true) { if (NextHasChecker(tempX, tempY, 8, color)) { times; tempX--; tempY; continue; } else break; } if (times 5) return true; return false; //默认返回False } 检查1.2.3.4.5.6.7.8 方向是否有该色的子#region 检查1.2.3.4.5.6.7.8 方向是否有该色的子 public bool NextHasChecker(int x, int y, int direction, CheckerColor color) { switch (direction) { case 1: if (x 0) return false; if (GoBang[x, y] ! null GoBang[x, y].CheckColor color) return true; else return false; case 5: if (x 14) return false; if (GoBang[x, y] ! null GoBang[x, y].CheckColor color) return true; else return false; case 3: if (y 0) return false; if (GoBang[x, y] ! null GoBang[x, y].CheckColor color) return true; else return false; case 7: if (y 14) return false; if (GoBang[x, y] ! null GoBang[x, y].CheckColor color) return true; else return false; case 2: if (x 0 || y 0) return false; if (GoBang[x, y] ! null GoBang[x, y].CheckColor color) return true; else return false; case 6: if (x 14 || y 14) return false; if (GoBang[x, y] ! null GoBang[x, y].CheckColor color) return true; else return false; case 4: if (x 14 || y 0) return false; if (GoBang[x, y] ! null GoBang[x, y].CheckColor color) return true; else return false; case 8: if (x 0 || y 14) return false; if (GoBang[x, y] ! null GoBang[x, y].CheckColor color) return true; else return false; default: return false; } } #endregion //检查1.2.3.4.5.6.7.8 方向是否有该色的子 (二),这样只是达到判断胜否的目的.做一个单机版的五子棋.要求有个电脑和你玩.那么就是个AI的问题,COMPUTER,根椐盘上的棋子作出相应的攻守.一个稍微简单点的AI,也是我能理解的AI思路.当电脑下子时,递归或循环棋盘上每一个未下子的位置,对每个位置下子进行打分,比如当电脑色棋面上有三子已成一线,且成活三必胜局面,那么在此位置下子应当是得分比较高的点,或者当对手的成活三,双三,禁手的点,在那点电脑下子也应当是得分比较高的,其次是成二子,成一子..依次分配合理的权值.最后把权值相加,取得分最高点着子.所以不同情况的权值的取大小直接影响到电脑对该位置落子认可度.当然我没有,要很多的测试才能得出,下面给一个别人的权值计算公式,相对合理. //找自己的取胜点10000 int w1 100000; //找对手的取胜点50000 int w2 50000; //找自己的三个相连的点10000 int w3 10000; //找对手的三个相连的点5000 int w4 5000; //找自己的两个相连的点1000 int w5 1000; //找对手的两个相连的点500 int w6 500; //找自己的相连的点100 int w7 100; //找对方的相连的点50 int w8 50; //找自己的失败点 int w9 -1000000;(三),明白了COMPUTER找最佳落子位置原理后就是计算棋盘上落子的分值的时候了.前面已说过.一个棋子在盘中有四个方向,水平,竖值,两个方向斜,前面说是1.2.3.4.5.6.7.8那么也就是计算这4个方向的棋子的连子数,我给出参考算法:从四个方向检测连子个数#region 从四个方向检测连子个数 /**//// summary /// 正东正西检测与mn点棋子相同的棋子个数 /// /summary /// param namem/param /// param namen/param /// param namearrchessboard/param /// returns如果返回负值则表示改方向在无子可下/returns public static int Xnum(int m, int n, Checker[,] arrchessboard,CheckerColor color) { //检查是否无子可下当flag2时表示无子可下 int flag 0; //连子个数 int num 1; //正东方向检查(x) int i m 1; //不超出棋格 while (i 15) { //前方的棋子与m,n点不同时跳出循环 if (arrchessboard[i, n] ! null arrchessboard[i, n].CheckColor color) { num; i; } else { break; } } //正东方向超出棋格 if (i 15) { flag; } else { //正东方向有别的子不可在下 if (arrchessboard[i, n] ! null) { flag; } } //正西方向检查(x-) i m - 1; while (i 0) { //前方的棋子与m,n点不同时跳出循环 if (arrchessboard[i, n] ! null arrchessboard[i, n].CheckColor color) { num; i--; } else { break; } } //正西方向超出棋格 if (i -1) { flag; } else { //正西方向有别的子不可在下 if (arrchessboard[i, n] ! null) { flag; } } if (flag 2) { return -num; } else { if (flag 1 num 3) { //连子数为3时有一边不能下就不是活三 return -num; } else { return num; } } } /**//// summary /// 正南正北方向检测 /// /summary /// param namem/param /// param namen/param /// param namearrchessboard/param /// returns如果返回负值则表示改方向在无子可下/returns public static int Ynum(int m, int n, Checker[,] arrchessboard, CheckerColor color) { //检查是否无子可下当flag2时表示无子可下 int flag 0; //连子个数 int num 1; //正南方向检查(y) int i n 1; while (i 15) { //前方的棋子与m,n点不同时跳出循环 if (arrchessboard[m,i] ! null arrchessboard[m, i].CheckColor color) { num; i; } else { break; } } //正南方向超出棋格 if (i 15) { flag; } else { //正南方向有别的子不可在下 if (arrchessboard[m, i] ! null) { flag; } } //正北方向检查(y-) i n - 1; while (i 0) { //前方的棋子与m,n点不同时跳出循环 if (arrchessboard[m,i] ! null arrchessboard[m, i].CheckColor color) { num; i--; } else { break; } } //正北方向超出棋格 if (i -1) { flag; } else { //正北方向有别的子不可在下 if (arrchessboard[m, i] ! null) { flag; } } if (flag 2) { return -num; } else { if (flag 1 num 3) { //连子数为3时有一边不能下就不是活三 return -num; } else { return num; } } } /**//// summary /// 西北东南方向检查 /// /summary /// param namem/param /// param namen/param /// param namearrchessboard/param /// returns如果返回负值则表示改方向在无子可下/returns public static int YXnum(int m, int n, Checker[,] arrchessboard, CheckerColor color) { //检查是否无子可下当flag2时表示无子可下 int flag 0; //连子个数 int num 1; //东南方向(x,y) int i m 1; int j n 1; //不超出棋格 while (i 15 j 15) { //前方的棋子与m,n点不同时跳出循环 if (arrchessboard[i,j] ! null arrchessboard[i, j].CheckColor color) { num; i; j; } else { break; } } //东南方向超出棋格 if (i 15 || j 15) { flag; } else { //东南方向有别的子不可在下 if (arrchessboard[i, j] ! null) { flag; } } //西北方向(x-,y-) i m - 1; j n - 1; //不超出棋格 while (i 0 j 0) { //前方的棋子与m,n点不同时跳出循环 if (arrchessboard[i, j] ! null arrchessboard[i, j].CheckColor color) { num; i--; j--; } else { break; } } //西北方向超出棋格 if (i -1 || j -1) { flag; } else { //西北方向有别的子不可在下 if (arrchessboard[i, j] ! null) { flag; } } if (flag 2) { return -num; } else { if (flag 1 num 3) { //连子数为3时有一边不能下就不是活三 return -num; } else { return num; } } } /**//// summary /// 西南东北方向检查 /// /summary /// param namem/param /// param namen/param /// param namearrchessboard/param /// returns如果返回负值则表示改方向在无子可下/returns public static int XYnum(int m, int n, Checker[,] arrchessboard, CheckerColor color) { //检查是否无子可下当flag2时表示无子可下 int flag 0; //连子个数 int num 1; //西南方向(x-,y) int i m - 1; int j n 1; //不超出棋格 while (i 0 j 15) { //前方的棋子与m,n点不同时跳出循环 if (arrchessboard[i, j] ! null arrchessboard[i, j].CheckColor color) { num; i--; j; } else { break; } } //西南方向超出棋格 if (i -1 || j 15) { flag; } else { //西南方向有别的子不可在下 if (arrchessboard[i, j] ! null) { flag; } } //东北方向(x,y-) i m 1; j n - 1; //不超出棋格 while (i 15 j 0) { //前方的棋子与m,n点不同时跳出循环 if (arrchessboard[i, j] ! null arrchessboard[i, j].CheckColor color) { num; i; j--; } else { break; } } //东北方向超出棋格 if (i 15 || j -1) { flag; } else { //东北方向有别的子不可在下 if (arrchessboard[i, j] ! null) { flag; } } if (flag 2) { return -num; } else { if (flag 1 num 3) { //连子数为3时有一边不能下就不是活三 return -num; } else { return num; } } } #endregion (四),上面是对一点计算如果在该处落子时得分,设四个数组,就是那四个方向的连子数*相应权值 arrf[0] arrf[1] arrf[2] arrf[3] 那么找最高分就是一个循环或递归的过程,不多说.找到该点坐标,落子.交换棋子色,人下子,COMPUTER下子,...只到有5子有人成功. 我用C#,VS2005完整解决方案放下,关于人工智能,何其深奥,已此简单的算法基础我对AI有一点初步认识. 转载于:https://www.cnblogs.com/solo/archive/2007/01/09/616068.html