Java控制台五子棋编码学习

目录


主要经验

  • 方法的功能要单一。
  • 类中某一方法的功能实现可以依赖于其他方法,调用过程中传入正确的参数,使用this.方法名即可;编写过程中编写了一个是否获胜的方法,该方法需要判断四个方向的棋子数量,变量太多,出了很多错误。然后把四个方向的方法单独出来,统计方法调用四个方法,再做判断。
  • 学会了调试代码。F5深入代码,F6运行下一步。期间出现过输入1次坐标后,任何输入控制台都不读取的情况,Debug多次发现是某方法中if语句下的break一句被注销了。
  • 自己写的判断是否满足5个棋子的算法。
  • 学会break和continue的用法区别。前者直接退出循环体,后者继续执行而不再执行后边的语句。
  • 变量(含类)定义的地方,决定了它能被使用的范围。
  • 不足一:写完后对于代码的可扩展性没有任何意识;
  • 不足二:软件设计的理念方法写完代码后也没有任何意识。
  • 不足三:在编写过程中,不停的测试,并没有严格的按照流程来。

游戏描述

参考的是《疯狂Java实战演义》——杨恩雄(文字版)中第一章内容。


Java源代码

GobangGame.java

package practise.fiveChess;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class GobangGame {
    private int WIN_COUNT = 5;
    private int posX, posY;
    Chessboard chessboard = new Chessboard();

    public int getPosX() {
        return posX;
    }

    public void setPosX(int posX) {
        this.posX = posX;
    }

    public int getPosY() {
        return posY;
    }

    public void setPosY(int posY) {
        this.posY = posY;
    }

    public static void main(String[] args) {
        //游戏初始化
        boolean isOver = false;
        System.out.println("游戏开始!");
        GobangGame gobangGame = new GobangGame();
        Chessboard chessboard = new Chessboard();
        chessboard.initBorad();
        chessboard.printBoard();
        //执行游戏交互
        do {
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                String inputStr = null;
                // 判断输入是否合法
                while ((inputStr = br.readLine()) != null && gobangGame.isValid(inputStr) && isOver == false) {
                    int posX = gobangGame.getPosX();
                    int posY = gobangGame.getPosY();
                    String colorDark = Chessman.BLACK.getChessman();
                    String colorWhite = Chessman.WHITE.getChessman();
                    // 放棋子,如果失败则重放
                    if (!chessboard.setBoardByMan(posX, posY, colorDark)
                            || !chessboard.setBoardByComputer(colorWhite)) {
                        continue;
                    }
                    // 打印棋盘
                    chessboard.printBoard();
                    // 判断是否有赢家
                    if (gobangGame.isWin(chessboard, posX, posY, colorDark)
                            || gobangGame.isWin(chessboard, posX, posY, colorWhite)) {
                        if (gobangGame.isWin(chessboard, posX, posY, colorDark) == true) {
                            System.out.println("比赛结束!" + colorDark + "获得胜利");
                            System.out.println("是否继续游戏?y/n");
                            // 用户确认是否继续游戏,继续则初始化棋盘,否则退出程序
                            if (br.readLine().contentEquals("y")) {
                                chessboard.initBorad();
                                System.out.println("游戏开始!");
                                chessboard.printBoard();
                                continue;
                            } else {
                                isOver = true;
                                break;
                            }
                        }
                        if (gobangGame.isWin(chessboard, posX, posY, colorWhite) == true) {
                            System.out.println("比赛结束!" + colorWhite + "获得胜利");
                            System.out.println("是否继续游戏?y/n");
                            // 用户确认是否继续游戏,继续则初始化棋盘,否则退出程序
                            if (br.readLine().contentEquals("y")) {
                                chessboard.initBorad();
                                System.out.println("游戏开始!");
                                chessboard.printBoard();
                                continue;
                            } else {
                                isOver = true;
                                break;
                            }
                        }
                    }
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        } while (isOver == false);
        System.out.println("Game Over!");
    }

    // 输入合法性检测
    public boolean isValid(String str) {
        String[] posStrArr = str.split(",");
        try {
            posX = Integer.parseInt(posStrArr[0]);
            posY = Integer.parseInt(posStrArr[1]);
            if (posX > chessboard.BOARD_SIZE || posY > chessboard.BOARD_SIZE || posX < 0 || posY < 0) {
                System.out.println("输入不合法,请输入合法的坐标范围:0--" + (chessboard.BOARD_SIZE - 1));
                return false;
            }
        } catch (NumberFormatException e) {
            //chessboard.printBoard();
            System.out.println("输入不合法,请重新按"x,y"的形式输入");
            return false;
        }
        return true;
    }
    //是否继续游戏方法
    public boolean isReplay(String enterStr) {
        if (enterStr == "y" || enterStr == "Y") {
            return true;
        } else {
            return false;
        }
    }

    //以下方法基于输入棋子坐标,按不同方向(基于棋子坐标),东西|南北|东北-西南|西北-东南。
    //东西
    public boolean conetX(Chessboard chessboard, int posX, int posY, String chessColor) {
        String[][] board;
        board = chessboard.getBord();
        int count = 1;
        try {
            int tmpY = posY - 1;
            // 输入点不是起点所在列则判断
            // 输入点左侧
            while (posY >= tmpY && tmpY > 0) {
                if (board[posX][tmpY] != chessColor) {
                    break;
                } else {
                    count++;
                    tmpY--;
                }
            }
            // 输入点右侧
            tmpY = posY + 1;
            while (posY <= tmpY && tmpY < chessboard.BOARD_SIZE) {
                if (board[posX][tmpY] != chessColor) {
                    break;
                } else {
                    count++;
                    tmpY++;
                }
            }
            if (count >= WIN_COUNT) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            System.out.println("异常错误:" + e.getMessage());
            return false;
        }
    }

    /**
     * 南北统计
     */
    public boolean conetY(Chessboard chessboard, int posX, int posY, String chessColor) {
        String[][] board;
        board = chessboard.getBord();
        int count = 1;
        try {
            int tmpX = posX - 1;
            // 输入点上方,如果输入的是原点则不计
            while (tmpX >= 0) {
                if (board[tmpX][posY] != chessColor) {
                    break;
                } else {
                    count++;
                    tmpX--;
                }
            }
            // 输入点下方
            tmpX = posX + 1;
            while (posX < tmpX && tmpX < chessboard.BOARD_SIZE) {
                if (board[tmpX][posY] != chessColor) {
                    break;
                } else {
                    count++;
                    tmpX++;
                }
            }
            // 累加后是否符合要求
            if (count >= WIN_COUNT) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            System.out.println("异常错误:" + e.getMessage());
            return false;
        }

    }

    /**
     * 东北西南斜线方向
     */
    public boolean conetEN(Chessboard chessboard, int posX, int posY, String chessColor) {
        String[][] board;
        board = chessboard.getBord();
        int count = 1;

        try {
            int tmpX1 = posX - 1;
            int tmpY1 = posY - 1;

            // 西北线
            while (tmpX1 < posX && tmpX1 >= 0 && tmpY1 < posY && tmpY1 >= 0) {
                if (board[tmpX1][tmpY1] != chessColor) {
                    break;
                } else {
                    count++;
                    tmpY1--;
                    tmpX1--;
                }
            }
            // 东南线
            int tmpX2 = posX + 1;
            int tmpY2 = posY + 1;
            while (tmpX2 > posX && tmpX2 < chessboard.BOARD_SIZE && tmpY2 > posY && tmpY2 < chessboard.BOARD_SIZE) {
                if (board[tmpX2][tmpY2] != chessColor) {
                    break;
                } else {
                    count++;
                    tmpY2++;
                    tmpX2++;
                }
            }
            if (count >= WIN_COUNT) {
                return true;
            } else {
                return false;
            }

        } catch (Exception e) {
            System.out.println("异常错误:" + e.getMessage());
            return false;
        }
    }

    /**
     * 东北西南斜线方向
     */
    public boolean conetES(Chessboard chessboard, int posX, int posY, String chessColor) {
        String[][] board;
        board = chessboard.getBord();
        int count = 1;
        count = 1;
        try {
            int tmpX1 = posX - 1;
            int tmpY1 = posY + 1;
            // 东北线
            while (tmpX1 < posX && tmpX1 >= 0 && tmpY1 >= posY && tmpY1 < chessboard.BOARD_SIZE) {
                if (board[tmpX1][tmpY1] != chessColor) {
                    break;
                } else {
                    count++;
                    tmpY1++;
                    tmpX1--;
                }
            }
            // 西南线
            int tmpX2 = posX + 1;
            int tmpY2 = posY - 1;
            while (tmpX2 < chessboard.BOARD_SIZE && tmpX2 > posX && tmpY2 < posY && tmpY2 >= 0) {
                if (board[tmpX2][tmpY2] != chessColor) {
                    break;
                } else {
                    count++;
                    tmpY2--;
                    tmpX2++;
                }
            }
            if (count >= WIN_COUNT) {
                return true;
            } else {
                return false;
            }

        } catch (Exception e) {
            System.out.println("异常错误:" + e.getMessage());
            return false;
        }
    }

    // 判断所输入打棋子是否能够赢得比赛
    public boolean isWin(Chessboard chessboard, int posX, int posY, String chessColor) {
        boolean isWinx = this.conetX(chessboard, posX, posY, chessColor);
        boolean isWiny = this.conetY(chessboard, posX, posY, chessColor);
        boolean isWinEN = this.conetEN(chessboard, posX, posY, chessColor);
        boolean isWinES = this.conetES(chessboard, posX, posY, chessColor);
        if (isWinx || isWiny || isWinEN || isWinES) {
            return true;
        } else {
            return false;
        }
    }
}

Chessman.java

public enum Chessman {
    BLACK("●"), WHITE("○");
    private String chessman;
    private Chessman(String chessman) {
        this.chessman = chessman;
    }
    public String getChessman() {
        return this.chessman;
    }
}

Chessboard.java

package practise.fiveChess;

public class Chessboard {

    static int  BOARD_SIZE=22;
    String[][] board=new String[BOARD_SIZE][BOARD_SIZE];
    //初始化棋盘
    public void initBorad(){
        for (Integer i = 0; i < BOARD_SIZE; i++) {
            for (Integer j = 0; j < BOARD_SIZE; j++) {
                board[i][j]="╂";
            }
        }
    }
    //打印棋盘
    public void printBoard(){
        for (int i = 0; i < BOARD_SIZE; i++) {
            //System.out.print(i);
            for (int j = 0; j < BOARD_SIZE; j++) {
                System.out.print(board[i][j]);
            }
            System.out.println();
        }
    }

    //人执黑棋下棋落子
    public boolean setBoardByMan(int posX,int posY,String color){
            if(board[posX][posY]!="╂"){ 
                System.out.println("输入位置已有棋子,请重新输入");
                return false;
            }else{
                board[posX][posY]="●";
                return true;
            }
    }
    //电脑执白棋
    public boolean setBoardByComputer(String color){
        int posX,posY;
        posX=(int)((Math.random())*BOARD_SIZE);
        posY=(int)((Math.random())*BOARD_SIZE);
        if(board[posX][posY]!="╂"){ 
            setBoardByComputer(color);
            return false;
        }else{
            board[posX][posY]="○";
            return true;
        }

    }
    //返回棋盘,二维数组
    public String[][] getBord(){
        return board;
    }

}
原文地址:https://www.cnblogs.com/windanchaos/p/6398818.html