这几天编了一个五子棋的简单程序,现在将中间判断胜负的Java程序说一下.



五子棋的规则就不再述了.



1. 先将棋盘(15x15的)分成13个区域(见下图)



2. 编写一个判断胜负的Java类方法(包括一个代表胜负的boolean返回值,两个代表当前一方下子的位子参数posX,posY,及一个表示所下棋子种类(黑棋还是白棋,用"黑"实心圆String表示,用"白"空心圆String表示)的String参数.



3.此方法中实现了一个棋盘类对象,因为这里主要讲判断胜负,所以棋盘类就不详细讲了.只要知道它有

  一个表示棋盘上每一格状态(黑棋,白棋还是没棋)的二维数组public String[][] board; 一个表示棋盘大小的常量public static final int BOARD_SIZE = 15;一个初始化棋盘方法public void initBoard(),和一个打印棋盘的方法public void printBoard().



4.判段是否"胜"可以将棋盘扫描一边,也可以以最后所下子为中心向周围不同方向辐射来计算.我们当然采用第二种.这样我门就有四条线要判断,横向,纵向,左上到右下的斜向,右上到左下的斜向.


5.横向和纵向比较简单,前两段实现了此功能.


6."左上到右下的斜向,右上到左下的斜向"比较复杂,要判断所下子是否在13区域以外的其他区域,以相应的减少斜向X和Y坐标的起始位和终止位(这是关键和难点).


7.其他具体的请看以下代码中的注释.


 




    public boolean isWin(int posX, int posY, String chessman){
        //计算后的X轴起始点("左上到右下的斜向"时为左上点X坐标,"右上到左下的斜向"时为右上点X坐标)
        int startX = 0;                             

        //计算后的Y轴起始点("左上到右下的斜向"时为左上点Y坐标,"右上到左下的斜向"时为左下点Y坐标)
        int startY = 0;
        //计算后的X轴终止位("左上到右下的斜向"时为右下点X坐标,"右上到左下的斜向"时为左下点X坐标)

        int endX = Chessboard.BOARD_SIZE - 1;
        //计算后的Y轴终止位("左上到右下的斜向"时为右下点Y坐标,"右上到左下的斜向"时为右上点Y坐标)

        int endY = Chessboard.BOARD_SIZE - 1;

        //posX - WIN_COUNT + 1 的值
        int minX = 0;

        //posY - WIN_COUNT + 1 的值
        int minY = 0;

        //posX + WIN_COUNT - 1 的值
        int maxX = Chessboard.BOARD_SIZE - 1;
        //posY + WIN_COUNT - 1 的值
        int maxY = Chessboard.BOARD_SIZE - 1;
        int sameCount = 0;
        
        //calculate min X position and Y position 
        minX = posX - WIN_COUNT + 1;
        startX = minX < 0 ? 0 : minX;
        minY =posY - WIN_COUNT + 1;
        startY = minY < 0 ? 0 : minY;
        
        //calculate max X position and Y position
        maxX = posX + WIN_COUNT - 1;
        endX = maxX > Chessboard.BOARD_SIZE - 1 ? Chessboard.BOARD_SIZE - 1 : maxX;
        maxY =posY + WIN_COUNT - 1;
        endY = maxY > Chessboard.BOARD_SIZE - 1 ? Chessboard.BOARD_SIZE - 1 : maxY;
        String[][] board = chessboard.getBoard();

        //Col position chess check 计算横向是否胜
        for(int i = startY; i < endY; i++){
            if(board[posX][i] == chessman && board[posX][i+1] == chessman){
                sameCount++;
            }else if(sameCount < WIN_COUNT - 1){
            sameCount = 0;
            }
        }
        //Vol position chess check 计算纵向是否胜

        for(int i = startX; i < endX; i++){
            if(board[i][posY] == chessman && board[i+1][posY] == chessman){
                sameCount++;
            }else if(sameCount < WIN_COUNT - 1){
            sameCount = 0;
            }
        }
        //Inclined position chess check
        //Left top to right bottom 计算左上到右下的斜向是否胜,这里要判断所下子是否在13区域以外的其他区域,以相应的减少斜向X和Y坐标的起始位和终止位.
        //calculate start X position and Y position
        //startX
        if (minX < 0){
            //area 1
            if(posX > posY){
                startX = posX - posY;
            }
            //area 2,3,4,9
            else{
                startX = 0;
            }
        }
        //area 7,8,12
        else if(minY < 0){
            startX = posX - posY;
        }
        //area 5,6,10,11,13
        else{
            startX = minX;
        }
        
        //startY
        if (minY < 0){
            //area 2
            if(posX < posY){
                startY = posY - posX;
            }
            //area 1,7,8,12
            else{
                startY = 0;
            }
        }
        //area 3,4,9
        else if(minX < 0){
            startY = posY - posX;
        }
        //area 5,6,10,11,13
        else{
            startY = minY;
        }
        
        //calculate end X position and Y position
        //endX
        if (maxX > Chessboard.BOARD_SIZE - 1){
            //area 5
            if(posX < posY){
                endX = Chessboard.BOARD_SIZE - 1 - (posY - posX);
            }
            //area 6,7,8,11
            else{
                endX = Chessboard.BOARD_SIZE - 1;
            }
        }
        //area 3,4,10
        else if(maxY > Chessboard.BOARD_SIZE - 1){
            endX = Chessboard.BOARD_SIZE - 1 - (posY - posX);
        }
        //area 1,2,9,12,13
        else{
            endX = maxX;
        }
        
        //endY
        if (maxY > Chessboard.BOARD_SIZE - 1){
            //area 6
            if(posX > posY){
                endY = Chessboard.BOARD_SIZE - 1 - (posX - posY);
            }
            //area 3,4,5,10
            else{
                endY = Chessboard.BOARD_SIZE - 1;
            }
        }
        //area 7,8,11
        else if(maxX > Chessboard.BOARD_SIZE - 1){
            endY = Chessboard.BOARD_SIZE - 1 - (posX - posY);
        }
        //area 1,2,9,12,13
        else{
            endY = maxY;
        }
        
        int j = startY;
        for(int i = startX; i < endX; i++){
            if(board[i][j] == chessman && board[i+1][j+1] == chessman){
                sameCount++;
            }else if(sameCount < WIN_COUNT - 1){
                sameCount = 0;
            }
            if (j < endY){
                j++;
            }
        }
        //Right top to left bottom 计算右上到左下的斜向是否胜,这里要判断所下子是否在13区域以外的其他区域,以相应的减少斜向X和Y坐标的起始位和终止位.
        //calculate start X position and Y position
        //startX
        if (minX < 0){
            //area 4
            if(posX > (Chessboard.BOARD_SIZE - 1 - posY)){
                startX = minX + (maxY - (Chessboard.BOARD_SIZE - 1));
            }
            //area 1,2,3,9
            else{
                startX = 0;
            } 
        }
        //area 5,6,10
        else if(maxY > Chessboard.BOARD_SIZE - 1){
                startX = minX + (maxY - (Chessboard.BOARD_SIZE - 1));
        }
        //area 7,8,11,12,13
        else{
            startX = minX;
        }
        
        //startY
        if (minY < 0){
            //area 7
            if((Chessboard.BOARD_SIZE - 1 - posX) < posY){
                startY = minY + (maxX - (Chessboard.BOARD_SIZE - 1));
            }
            //area 1,2,8,12
            else{
            startY = 0;
            }
        }
        //area 5,6,11
        else if(maxX > Chessboard.BOARD_SIZE - 1){
                startY = minY + (maxX - (Chessboard.BOARD_SIZE - 1));
        }
        //area 3,4,9,10,13
        else{
            startY = minY;
        }
        
        //calculate end X position and Y position
        //endX
        if (maxX > Chessboard.BOARD_SIZE - 1){
            //area 8
            if((Chessboard.BOARD_SIZE - 1 - posX) > posY){
//                endX = Chessboard.BOARD_SIZE - 1 - ((Chessboard.BOARD_SIZE - 1 - posX) - posY);
                endX = maxX + minY;
            }
            //area 5,6,7,11
            else{
                endX = Chessboard.BOARD_SIZE - 1;
            }
        }
        //area 1,2,12
        else if(minY < 0){
                endX = maxX + minY;
        }
        //area 3,4,9,10,13
        else{
            endX = maxX;
        }
        
        //endY
        if (maxY > Chessboard.BOARD_SIZE - 1){
            //area 3
            if(posX < (Chessboard.BOARD_SIZE - 1 - posY)){
                endY = minX + maxY;
            }
            //area 4,5,6,10
            else{
                endY = Chessboard.BOARD_SIZE - 1;
            }
        }
        //area 1,2,9
        else if(minX < 0){
                endY = minX + maxY;
        }
        //area 7,8,11,12,13
        else{
            endY = maxY;
        }

        int k = endY;
        for(int i = startX; i < endX; i++){
            if(board[i][k] == chessman && board[i+1][k-1] == chessman){
                sameCount++;
            }else if(sameCount < WIN_COUNT - 1){
                sameCount = 0;
            }
            if (k > startY){
                k--;
            }
        }
        //判断是否胜,返回boolean值
        if (sameCount >= WIN_COUNT - 1){
            return true;
        }else{
            return false;
        }
    }