五子棋的简单AI
2017-03-04 23:18
369 查看
遍历求最优解
using UnityEngine; using System.Collections; public class AIController : MonoBehaviour { #region 设置事件对应等级 //预计白子 int whiteTwoAndNoObstacle = 101; int whiteTwoAndOneObstacle = 111; int whiteThreeAndNoObstacle = 41; int whiteThreeAndOneObstacle = 51; int whiteTwoOrMoreThreeAndNoObstacle = 71; int whiteTwoOrMoreThreeAndOneObstacle = 81; //预计黑子 int blackThreeAndNoObstacle = 61; int blackThreeAndOneObstacle = 91; int blackFourAndOneObstacle = 11; int blackTwoOrMoreThreeAndNoObstacle=21; int blackTwoOrMoreThreeAndOneObstacle=31; int blackTwo = 121; int whiteWin = 1; #endregion public static AIController Static; int x; int y; //下子的等级设置 由1 , 11 , 21 ,31 ,41 ,51 ,61.....组成(方便修改 int dangerousLevel; int maxNumber; int chessNum; void Awake() { dangerousLevel = 1000; chessNum = 13; maxNumber = 4; x = 0; y = 0; Static = this; } //随机下 public void downWhiteChess(int k) { int i = k / 13; int j = k % 13; rangeAround(i, j); } //穷举法 public void downWhiteChessForNum(int k) { int blackX = k / 13; int blackY = k % 13; dangerousLevel = 1000; for (int i = 0; i < 13; i++) { for(int j = 0; j < 13; j++) { if (!RectManage.Static.isDown(i, j)) { checkWhiteWinState(i, j, 1, 1, 0); checkWhiteWinState(i, j, 1, 1, 1); checkWhiteWinState(i, j, 1, 1, 2); checkWhiteWinState(i, j, 0, 1, 0); checkWhiteWinState(i, j, 1, 0, 0); checkWhiteWinState(i, j, -1, 1, 0); checkWhiteWinState(i, j, -1, 1, 1); checkBlackWinState(i, j, 1, 1, 0); checkBlackWinState(i, j, 1, 1, 1); checkBlackWinState(i, j, 1, 1, 2); checkBlackWinState(i, j, -1, 1, 0); checkBlackWinState(i, j, -1, 1, 1); checkBlackWinState(i, j, 0, 1, 0); checkBlackWinState(i, j, 1, 0, 0); checkBlackCrisscross(i, j); checkWhiteCrisscross(i, j); if (dangerousLevel == whiteWin) { CommandModel.Static.downWhiteChess(i, j); UiController.Static.onButtonClick("loseImmediate"); return; } } } } if (dangerousLevel != whiteWin) { if (dangerousLevel < 1000) { CommandModel.Static.downWhiteChess(x, y); } else { rangeAround(blackX, blackY); } } } //在棋子周围下棋 void rangeAround(int i, int j) { bool key = false; while (!key) { switch (Random.Range(0, 9)) { case 0: key = initRandomWhiteChess(i - 1, j - 1); break; case 1: key = initRandomWhiteChess(i + 1, j); break; case 2: key = initRandomWhiteChess(i + 1, j + 1); break; case 3: key = initRandomWhiteChess(i - 1, j); break; case 4: key = initRandomWhiteChess(i - 1, j + 1); break; case 5: key = initRandomWhiteChess(i, j + 1); break; case 6: key = initRandomWhiteChess(i - 1, j); break; case 7: key = initRandomWhiteChess(i + 1, j - 1); break; case 8: key = initRandomWhiteChess(i, j - 1); break; default: Debug.Log("ERROR"); key = true; break; } } } //随机查找 bool initRandomWhiteChess(int i, int j) { if (i > chessNum - 1 || i < 0 || j > chessNum - 1 || j < 0) { return false; } if (!RectManage.Static.isDown(i, j)) { CommandModel.Static.downWhiteChess(i,j); return true; } return false; } #region 寻找最适合的下棋位置 //turnDirection=0 为检测/ turnDirection=1 为检测< turnDirection=2 为检测V void checkWhiteWinState(int i, int j, int iDirection, int jDirection, int turnDirection) { int record = 0; bool leftIsBlack = false; bool rightIsBlack = false; int FindX = i + iDirection; int FindY = j + jDirection; int recordLeft = 0; bool isTurn = false; bool isTurnAndEqual = false; if (turnDirection > 0) { isTurn = true; } //找右边 while (FindX >= 0 && FindY < chessNum && FindX < chessNum && FindY >= 0) { if (RectManage.Static.isWhiteDown(FindX, FindY)) { record++; } else { rightIsBlack = RectManage.Static.isBlackDown(FindX, FindY); break; } if (record >= maxNumber) { setIJAccordingLevel(i, j, whiteWin); return; } FindX += iDirection; FindY += jDirection; } if(!(FindX >= 0 && FindY < chessNum && FindX < chessNum && FindY >= 0)) { rightIsBlack = true; } switch (turnDirection) { case 1: iDirection = -iDirection;recordLeft = record;record = 0; break; case 2: jDirection = -jDirection;recordLeft = record;record = 0; break; default: break; } FindX =i- iDirection; FindY =j- jDirection; while (FindX >= 0 && FindY < chessNum && FindX < chessNum && FindY >= 0) { if (RectManage.Static.isWhiteDown(FindX, FindY)) { record++; } else { leftIsBlack = RectManage.Static.isBlackDown(FindX, FindY); break; } if (record >= maxNumber) { setIJAccordingLevel(i, j, whiteWin); return; } FindX -= iDirection; FindY -= jDirection; } if (!(FindX >= 0 && FindY < chessNum && FindX < chessNum && FindY >= 0)) { leftIsBlack = true; } if (recordLeft == record) { isTurnAndEqual = true; } record += recordLeft; checkWhiteState(i, j, leftIsBlack, rightIsBlack, record,isTurn,isTurnAndEqual); } //turnDirection=0 为检测/ turnDirection=1 为检测< turnDirection=2 为检测V void checkBlackWinState(int i,int j,int iDirection,int jDirection,int turnDirection) { int record = 0; bool leftIsWhite = false; bool rightIsWhite = false; int FindX = i + iDirection; int FindY = j + jDirection; int recordLeft = 0; bool isTurn = false; bool isTurnAndEqual = false; if (turnDirection > 0) { isTurn = true; } //找右边 while (FindX >= 0 && FindY < chessNum&&FindX<chessNum&&FindY>=0) { if (RectManage.Static.isBlackDown(FindX, FindY)) { record++; } else { rightIsWhite = RectManage.Static.isWhiteDown(FindX, FindY); break; } FindX+=iDirection; FindY+=jDirection; } if (!(FindX >= 0 && FindY < chessNum && FindX < chessNum && FindY >= 0)) { rightIsWhite = true; } switch (turnDirection) { case 1: iDirection = -iDirection;recordLeft = record;record = 0; break; case 2: jDirection = -jDirection;recordLeft = record;record = 0; break; default: break; } FindX = i - iDirection; FindY = j - jDirection; while (FindX >= 0 && FindY < chessNum && FindX < chessNum && FindY >= 0) { if (RectManage.Static.isBlackDown(FindX, FindY)) { record++; } else { leftIsWhite = RectManage.Static.isWhiteDown(FindX, FindY); break; } FindX-=iDirection; FindY-=jDirection; } if (!(FindX >= 0 && FindY < chessNum && FindX < chessNum && FindY >= 0)) { leftIsWhite = true; } if (record == recordLeft) { isTurnAndEqual = true; } record += recordLeft; checkBlackState(i, j, leftIsWhite, rightIsWhite, record,isTurn,isTurnAndEqual); } public void checkBlackCrisscross(int i, int j) { int findX = i; int findY = j; if (RectManage.Static.checkBorder(findX + 1, findY) && RectManage.Static.checkBorder(findX, findY + 1) && RectManage.Static.checkBorder(findX - 1, findY) && RectManage.Static.checkBorder(findX, findY - 1)) { if (RectManage.Static.isBlackDown(findX + 1, findY) && RectManage.Static.isBlackDown(findX, findY + 1) && RectManage.Static.isBlackDown(findX - 1, findY) && RectManage.Static.isBlackDown(findX, findY - 1)) { if (RectManage.Static.checkBorder(findX + 2, findY) && RectManage.Static.checkBorder(findX, findY + 2) && RectManage.Static.checkBorder(findX - 2, findY) && RectManage.Static.checkBorder(findX, findY - 2)) { if (!RectManage.Static.isWhiteDown(findX + 2, findY) && !RectManage.Static.isWhiteDown(findX, findY + 2) && !RectManage.Static.isWhiteDown(findX - 2, findY) && !RectManage.Static.isWhiteDown(findX, findY - 2)) { setIJAccordingLevel(i, j, blackTwoOrMoreThreeAndNoObstacle); } else { setIJAccordingLevel(i, j, blackTwoOrMoreThreeAndOneObstacle); } } } } } public void checkWhiteCrisscross(int i, int j) { int findX = i; int findY = j; if(RectManage.Static.checkBorder(findX + 1, findY) && RectManage.Static.checkBorder(findX, findY + 1) && RectManage.Static.checkBorder(findX - 1, findY) && RectManage.Static.checkBorder(findX, findY - 1)){ if (RectManage.Static.isWhiteDown(findX + 1, findY) && RectManage.Static.isWhiteDown(findX, findY + 1) && RectManage.Static.isWhiteDown(findX - 1, findY) && RectManage.Static.isWhiteDown(findX, findY - 1)) { if(RectManage.Static.checkBorder(findX + 2, findY) && RectManage.Static.checkBorder(findX, findY + 2) && RectManage.Static.checkBorder(findX - 2, findY) && RectManage.Static.checkBorder(findX, findY - 2)) { if (!RectManage.Static.isBlackDown(findX + 2, findY) && !RectManage.Static.isBlackDown(findX, findY + 2) && !RectManage.Static.isBlackDown(findX - 2, findY) && !RectManage.Static.isBlackDown(findX, findY - 2)) { setIJAccordingLevel(i, j, whiteTwoOrMoreThreeAndNoObstacle); } else { setIJAccordingLevel(i, j, whiteTwoOrMoreThreeAndOneObstacle); } } } } } #endregion #region 查找落点状态 public void checkWhiteState(int i,int j,bool isLeftDown,bool isRightDown,int record,bool isTurn, bool isTurnAndEqual) { switch (record) { case 4: if (isTurn && isTurnAndEqual && !isLeftDown && !isRightDown) { setIJAccordingLevel(i, j, whiteTwoOrMoreThreeAndNoObstacle); break; } else { if (isTurn && isTurnAndEqual && (!isLeftDown && !isRightDown)) { setIJAccordingLevel(i, j, whiteTwoOrMoreThreeAndOneObstacle); break; } } if (!isTurn) { setIJAccordingLevel(i, j, whiteWin); } break; case 3: if (!isTurn) { if (!isLeftDown && !isRightDown) { if (setIJAccordingLevel(i, j, whiteThreeAndNoObstacle)) { } break; } if (!isLeftDown || !isRightDown) { setIJAccordingLevel(i, j, whiteThreeAndOneObstacle); } } break; case 2: if (!isLeftDown && !isRightDown) { if (setIJAccordingLevel(i, j, whiteTwoAndNoObstacle)) break; } if (!isLeftDown || !isRightDown) { setIJAccordingLevel(i, j, whiteTwoAndOneObstacle); } break; default: break; } } public void checkBlackState(int i, int j, bool isLeftDown, bool isRightDown, int record,bool isTurn, bool isTurnAndEqual) { switch (record) { case 4: if (isTurn && isTurnAndEqual&&!isLeftDown&&!isRightDown) { setIJAccordingLevel(i, j, blackTwoOrMoreThreeAndNoObstacle); break; } else { if (isTurn && isTurnAndEqual && (!isLeftDown || !isRightDown)) { setIJAccordingLevel(i, j, blackTwoOrMoreThreeAndOneObstacle); break; } } if (!isTurn) { setIJAccordingLevel(i, j, blackFourAndOneObstacle); } break; case 3: if (!isTurn) { if (!isLeftDown && !isRightDown) { if (setIJAccordingLevel(i, j, blackThreeAndNoObstacle)) break; } if ((!isLeftDown || !isRightDown)) { setIJAccordingLevel(i, j, blackThreeAndOneObstacle); } } break; case 2: if (!isLeftDown && !isRightDown) { if (setIJAccordingLevel(i, j, blackTwo)) break; } if (!isLeftDown || !isRightDown) { setIJAccordingLevel(i, j, blackTwo); } break; default: break; } } bool setIJAccordingLevel(int i,int j,int num) { if (dangerousLevel > num) { x = i; y = j; dangerousLevel = num; return true; } return false; } #endregion }
相关文章推荐
- qt实现简单的五子棋(无AI)
- 简单AI的五子棋程序
- NPC简单AI处理
- 使用vb.net实现五子棋的人工智能五子棋的AI构想
- 简单Ai贪食蛇
- 五子棋AI设计——从门外到门内不得不说的事儿1
- 五子棋AI循序渐进——连载说明
- 五子棋AI设计——从门外到门内不得不说的事儿2
- (转载)十四步实现拥有强大AI的五子棋游戏
- 游戏AI简单实现
- js 五子棋(无ai,仅判断胜负)
- 五子棋AI
- 简单的五子棋系统
- 五子棋算法 + 五子棋AI 估价算法
- 记在北大五子棋AI比赛后
- NPC简单AI处理
- 本人用 C 和 WinAPI 写的一个 带AI的五子棋
- ai引擎中最简单的状态机
- 基于脚本的简单AI和摄像机系统
- 五子棋AI设计——从门外到门内不得不说的事儿3