欢迎使用我的 在线工具

小D

读历史、看小说、写程序都是我所爱。技术不好,头脑不灵光,靠的是兴趣。
随笔 - 35, 文章 - 25, 评论 - 13, 引用 - 0
数据加载中……

Android五子棋算法简单实现

有一天在网上看到一个Android的五子棋,该程序的作者的GoogleTalk: lixinso@gmail.com。遂下载下来看看,可以下棋,但是没有实现电脑下棋算法,所以我一时兴起花了几个小时加了个电脑下棋算法在里面,很简单。原作者的游戏绘制就不多说了,主要讲电脑下棋算法。

1、准备一个数组表示当前棋盘,另外准备两个数组分别保存电脑和玩家每个可下点的坐标及其分数(棋型数组),每个可下点包括4个方向的分数,分别是横、竖、左斜、右斜。

private int[][] mChessTable = new int[CHESS_GRID][CHESS_GRID]; // 网格

    private int[][][] computerTable = new int[CHESS_GRID][CHESS_GRID][CHECK_DIR]; // 电脑棋形表
    private int[][][] playerTable = new int[CHESS_GRID][CHESS_GRID][CHECK_DIR]; // 电脑棋形表

 2、每个可下点的4个方向分数判断,每个方向取当前点左右每边5个棋点的状态,然后分析它们是否构成五连、活四、活三等,每种棋型给予不同的分数。  1 // -------------------------------------------------------------

  2     /**
  3      * 分析存在五连
  4      * 
  5      * @param tmpChess
  6      */
  7     public boolean analyzeWulian(int[] tmpChess, int isWho) {
  8         int count = 0;
  9         for (int i = 0; i < HALF_LEN; i++) {
 10             if (tmpChess[HALF_LEN - (i + 1)] == isWho) {
 11                 count++;
 12             } else {
 13                 break;
 14             }
 15         }
 16         for (int i = 0; i < HALF_LEN; i++) {
 17             if (tmpChess[HALF_LEN + i] == isWho) {
 18                 count++;
 19             } else {
 20                 break;
 21             }
 22         }
 23         if (count == 4) {
 24             return true;
 25         }
 26         return false;
 27     }
 28 
 29     /**
 30      * 
 31      * 分析活四 return 是否存在活四
 32      * 
 33      * @param tmpChess
 34      */
 35     public boolean analyzeHuosi(int[] tmpChess, int isWho) {
 36         int count = 0;
 37         int i = 0;
 38         boolean isSpace = false;
 39         for (i = 0; i < HALF_LEN; i++) {
 40             if (tmpChess[HALF_LEN - (i + 1)] == isWho) {
 41                 count++;
 42             } else {
 43                 break;
 44             }
 45         }
 46         if (tmpChess[HALF_LEN - (i + 1)] == 0) {
 47             isSpace = true;
 48         }
 49         for (i = 0; i < HALF_LEN; i++) {
 50             if (tmpChess[HALF_LEN + i] == isWho) {
 51                 count++;
 52             } else {
 53                 break;
 54             }
 55         }
 56         if (tmpChess[HALF_LEN + i] == 0) {
 57             isSpace = true;
 58         } else {
 59             isSpace = false;
 60         }
 61 
 62         if (count == 3 && isSpace) {
 63             return true;
 64         }
 65         return false;
 66     }
 67 
 68     /**
 69      * 
 70      * 分析活三 return 是否存在活三
 71      * 
 72      * @param tmpChess
 73      */
 74     public boolean analyzeHuosan(int[] tmpChess, int isWho) {
 75         int count = 0;
 76         int i = 0;
 77         boolean isSpace = false;
 78         for (i = 0; i < HALF_LEN; i++) {
 79             if (tmpChess[HALF_LEN - (i + 1)] == isWho) {
 80                 count++;
 81             } else {
 82                 break;
 83             }
 84         }
 85         if (tmpChess[HALF_LEN - (i + 1)] == 0) {
 86             isSpace = true;
 87         }
 88         for (i = 0; i < HALF_LEN; i++) {
 89             if (tmpChess[HALF_LEN + i] == isWho) {
 90                 count++;
 91             } else {
 92                 break;
 93             }
 94         }
 95         if (tmpChess[HALF_LEN + i] == 0) {
 96             isSpace = true;
 97         } else {
 98             isSpace = false;
 99         }
100 
101         if (count == 2 && isSpace) {
102             return true;
103         }
104         return false;
105     }
3、将玩家棋型数组和电脑棋型数组每个元素的分数比较,选出最大的五个放入一个降序排列的数组中。
/**
     * 找到最佳点
     * 
     * 
@return 最佳点
     
*/
    private ChessPoint findBestPoint() {
        int i, j;
        ChessPoint point;
        int maxScore = 0;
        int tmpScore = 0;
        for (i = 0; i < CHESS_GRID; i++) {
            for (j = 0; j < CHESS_GRID; j++) {
                // 电脑比较
                tmpScore = computerTable[i][j][0];
                tmpScore += computerTable[i][j][1];
                tmpScore += computerTable[i][j][2];
                tmpScore += computerTable[i][j][3];
                if (maxScore <= tmpScore) {
                    maxScore = tmpScore;
                    point = new ChessPoint();
                    point.x = j;
                    point.y = i;
                    point.score = maxScore;
                    insertBetterChessPoint(point);
                }
                // 玩家比较
                tmpScore = playerTable[i][j][0];
                tmpScore += playerTable[i][j][1];
                tmpScore += playerTable[i][j][2];
                tmpScore += playerTable[i][j][3];
                if (maxScore <= tmpScore) {
                    maxScore = tmpScore;
                    point = new ChessPoint();
                    point.x = j;
                    point.y = i;
                    point.score = maxScore;
                    insertBetterChessPoint(point);
                }

            }
        }

        // Log.v("cmaxpoint = ", "" + cMaxScore);
        
// Log.v("pmaxpoint = ", "" + pMaxScore);

        
        return analyzeBetterChess();
    }
4、处理降序排列的数组,如果第一个元素的分数>=(必胜的条件的分数),直接返回就可以了,如果小于就继续处理我们降序排列的数组每个元素,假设每个元素已下,然后判断其产生的后果,取出具有最佳后果的元素,并返回其值,作为电脑下棋点。判断每个元素的产生后果时,其实只需要处理其产生作用的棋盘范围就行了(以该元素位置为中心的正方形的棋盘范围,正方形边长为4 + 1 + 4,我用的10),不必要处理搜索处理整个棋盘的棋子。private ChessPoint analyzeBetterChess() {
        if(fiveBetterPoints[0].score > 30){
            return fiveBetterPoints[0];
        }
        else
        {
            ChessPoint betterPoint = null;
            ChessPoint tmpPoint = null;        
            
            int goodIdx = 0;
            int i = 0;
            int startx, starty, endx, endy;
            ChessPoint[] fbpTmp  = new ChessPoint[5];
            for(i = 0; i < 5;i++){
                fbpTmp[i] = fiveBetterPoints[i];
            }
            
            for(i = 0; i < 5;i++){
                if(fbpTmp[i] == nullbreak;
                mChessTable[fbpTmp[i].y][fbpTmp[i].x] = BLACK;
                clearChessArray();
                
                startx = fbpTmp[i].x - 5;
                starty = fbpTmp[i].y - 5;
                
                if(startx < 0){
                    startx = 0;
                }
                
                if(starty < 0){
                    starty = 0;
                }
                
                endx = startx + 10;
                endy = starty + 10;
                
                if(endx > CHESS_GRID){
                    endx = CHESS_GRID;
                }
                
                if(endy > CHESS_GRID){
                    endy = CHESS_GRID;
                }
                analyzeChessMater(computerTable, BLACK, startx, starty, endx, endy);
                // 分析玩家的棋型/////////////////////////////////////////////////////
                analyzeChessMater(playerTable, WHITE, startx, starty, endx, endy);
                tmpPoint = findBetterPoint(startx, starty, endx, endy);
                if(betterPoint != null){
                    if(betterPoint.score <=  tmpPoint.score){
                        betterPoint = tmpPoint;
                        goodIdx = i;
                    }
                }
                else{
                    betterPoint = tmpPoint;
                    goodIdx = i;
                }
                
                mChessTable[fbpTmp[i].y][fbpTmp[i].x] = 0;
            }        
            tmpPoint = null;
            betterPoint = null;
            return fbpTmp[goodIdx];
        }

    }
OK,差不多就这样,看源码吧,应该还有问题,其实速度还算可以。我要睡觉了,明天还要上班。

posted on 2012-03-06 12:53 vagasnail 阅读(1110) 评论(0)  编辑  收藏 所属分类: Android


只有注册用户登录后才能发表评论。


网站导航: