基于Java的五子棋游戏项目

  • 游戏规则:双人游戏。谁先完成五个棋子的连线(横向/纵向/斜向),谁胜利。
  • 代码介绍:一共有五个类,分别是:Chessboard(棋盘类)、Piece(棋子类)、Rule(规则类)、Location(坐标类)、Game(执行类)

界面展示(控制台输入输出)

源代码

Chessboard(棋盘类)

package com.crb.wuziqi;

public class Chessboard {
    public static final int ROW_COUNT = 15; // 行数
    public static final int COLUMN_COUNT = 15; // 列数
    // 存放棋子的二维数组
    private Piece[][] pieceArr = new Piece[ROW_COUNT][COLUMN_COUNT];

    /**
     * 初始化棋盘
     */
    public void initChessboard(){
        for (int i = 0; i < ROW_COUNT; i++) {
            for (int j = 0; j < COLUMN_COUNT; j++) {
                Piece piece = null;
                if (i == 0){
                    if(j == 0){
                        piece = new Piece(i,j,'┌'); // 左上角
                    }else if(j == COLUMN_COUNT - 1){
                        piece = new Piece(i,j,'┐'); // 右上角
                    }else{
                        piece = new Piece(i,j,'┬');
                    }
                } else if (i == ROW_COUNT - 1){
                    if (j == 0){
                        piece = new Piece(i,j,'└'); // 左下角
                    }else if(j == COLUMN_COUNT - 1){
                        piece = new Piece(i,j,'┘'); // 右下角
                    }else{
                        piece = new Piece(i,j,'┴');
                    }
                } else {
                    if (j == 0){
                        piece = new Piece(i,j,'├');
                    }else if(j == COLUMN_COUNT - 1){
                        piece = new Piece(i,j,'┤');
                    }else{
                        piece = new Piece(i,j,'┼');
                    }
                }
                pieceArr[i][j] = piece;
            }
        }
    }

    /**
     * 打印棋盘
     */
    public void printChessboard(){
        char[] number = {'1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        for (int j = 0; j < COLUMN_COUNT; j++) {
            System.out.print(" " + number[j]); // 打印列号
        }
        System.out.println();
        for (int i = 0; i < ROW_COUNT; i++) {
            System.out.print(number[i]); // 打印行号
            for (int j = 0; j < COLUMN_COUNT; j++) {
                System.out.print(pieceArr[i][j].getSymbol());
                if (j != pieceArr[i].length - 1)
                    System.out.print("─");
            }
            System.out.println();
        }
    }

    /**
     * 落子方法
     * @param piece 要下的棋子
     */
    public void putDownPiece(Piece piece){
        int row = piece.getRow(); // 获得棋子的行坐标
        int column = piece.getColumn(); // 获得棋子的纵坐标
        pieceArr[row][column] = piece; // 放到棋盘
    }

    /**
     * 判断棋盘上指定位置是否可以落子
     * @param location 指定位置
     * @return 如果能落子,返回true,如果不能,返回false
     */
    public boolean canPutDown(Location location){
        // 如果棋盘上此处已经有黑子 ● 或者白子 o ,返回 false,否则返回 true
        // 获取行号和列号
        int row = location.getRow();
        int column = location.getColumn();
        Piece piece = pieceArr[row][column];
        if (piece.getSymbol() == '●' || piece.getSymbol() == 'o'){
            return  false;
        }else {
            return true;
        }
    }

    /**
     * 根据行坐标和列坐标获取棋子对象
     * @param row 行坐标
     * @param column 列坐标
     * @return 返回指定棋子对象
     */
    public Piece getPiece(int row,int column){
        return pieceArr[row][column];
    }
}

Piece(棋子类)

package com.crb.wuziqi;

public class Piece {
    private int row; // 棋子的行坐标,从0开始,最大是14
    private int column; // 棋子的列坐标,从0开始,最大是14
    private char symbol; // 棋子的符号 黑子 ● 白子 o

    public Piece() {
    }

    public Piece(int row, int column, char symbol) {
        this.setRow(row);
        this.setColumn(column);
        this.symbol = symbol;
    }

    public int getRow() {
        return row;
    }

    public void setRow(int row) {
        if (row < 0){
            row = 0;
        }else if (row > 14){
            row = 14;
        }
        this.row = row;
    }

    public int getColumn() {
        return column;
    }

    public void setColumn(int column) {
        if (column < 0){
            column = 0;
        }else if (column > 14){
            column = 14;
        }
        this.column = column;
    }

    public char getSymbol() {
        return symbol;
    }

    public void setSymbol(char symbol) {
        this.symbol = symbol;
    }

    @Override
    public String toString() {
        return "symbol(" + row + "," + column + ')';
    }
}

Rule(规则类)

package com.crb.wuziqi;

import java.util.Scanner;

public class Rule {
    // 创建一个Scanner对象,用于接收用户输入内容
    private static Scanner scanner = new Scanner(System.in);

    /**
     * 获取落子位置
     * @return 返回当前落子位置
     */
    public static Location getLocation(){
        // 提取用户输入的全部内容
        String input = scanner.nextLine();
        // 只要输入的内容长度不是3 或者 输入的行号,列号不符合要求就让用户重新输入
        while(input.length() != 3 ||
                isRightCharacter(input.charAt(0)) == false ||
                input.charAt(1) != ',' ||
                isRightCharacter(input.charAt(2)) == false){
            System.out.print("位置输入有误,请重新输入: ");
            input = scanner.nextLine();
        }
        //System.out.println(input);
        // 获取用户输入的行号
        char rowChar = input.charAt(0);
        // 获取用户输入的列号
        char columnChar = input.charAt(2);

        // 用户输入的行号或列号是从1开始的,我们数组的下标是从0开始的
        // 行号或列号中有A,B,C,D,E,F 我们数组里只有数字 A应该是下标9,B应该是下标10,C应该是下标11
        int row = indexForChar(rowChar);
        int column = indexForChar(columnChar);

        Location location = new Location(row,column);
        return location;
    }

    /**
     * 判断给定的字符是否正确
     * @param c 给定的字符
     * @return 如果正确,返回 true,不正确则返回 false
     */
    private static boolean isRightCharacter(char c){
        if (c >= '1' && c <= '9'|| c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f'){
            return true;
        }
        return false;
    }

    /**
     * 把字符转换成数组下标
     * @param c 需要转换成下标的字符 c的取值范围是 字符 1-9, a-f, A-F
     * @return 返回字符对应的下标
     */
    private static int indexForChar(char c){
        // 假设 c的值是'5'
        int index = -1;
        if (c >= '1' && c <= '9'){
            index = c - '1'; // 假设 c 的值是‘5’ 53 - 49 = 4;
        }else if (c >= 'a' && c <= 'f'){
            index = c - 'a' + 9;  // 假设 c 的值是‘d’ 100 - 97 + 9 = 12;
        }else if (c >= 'A' && c <= 'F'){
            index = c - 'A' + 9;  // 假设 c 的值是‘D’ 68 - 65 + 9 = 12;
        }
        return index;
    }

    /**
     * 判断指定位置是否可以落子
     * @param location 指定位置
     * @return 如果能落子,返回 true,如果不能落子,返回 false
     */
    public static boolean canPutDown(Chessboard chessboard,Location location){
        // 如果棋盘上此处已经有黑子 ● 或者白子 o ,返回 false,否则返回 true
        return chessboard.canPutDown(location);
    }

    /**
     * 判断输赢
     * @param chessboard 当前棋盘
     * @param piece 当前最新下的棋子
     * @return 返回黑子获胜还是白子获胜
     */
    public static boolean isWin(Chessboard chessboard, Piece piece){
        // (一)判断横向是否达到5个或者更多同色子
        int row = piece.getRow(); // 获取棋子行号
        int column = piece.getColumn(); // 获取棋子列号
        char symbol = piece.getSymbol(); // 获取棋子颜色

        int count = 1; // 让count初始值是1,因为当前棋子就算一个
        // 计算当前棋子的左侧有几个同色棋子
        int i = row;
        int j = column - 1;
        while(j >= 0){
            Piece piece1 = chessboard.getPiece(i,j);
            char symbol1 = piece1.getSymbol();
            if (symbol1 == symbol){
                // 如果同色,让 count++
                count ++;
                j --; // 继续向左找棋子
            }else{
                // 如果不是同色,直接break
                break;
            }
        }
        // 计算当前棋子的右侧有几个同色的棋子
        i = row;
        j = column + 1;
        while (j <= Chessboard.COLUMN_COUNT - 1){
            Piece piece1 = chessboard.getPiece(i,j);
            char symbol1 = piece1.getSymbol();
            if (symbol1 == symbol){
                // 如果同色,让 count++
                count ++;
                j ++; // 继续向左找棋子
            }else{
                // 如果不是同色,直接break
                break;
            }
        }
        if (count >= 5){
            return true;
        }

        // (二)判断纵向是否达到 5 个或者更多同色子
        count = 1; // count需要重置为1
        // 计算当前棋子的上方有几个同色棋子
        i = row - 1;
        j = column;
        while (i >= 0){
            Piece piece1 = chessboard.getPiece(i,j);
            char symbol1 = piece1.getSymbol();
            if (symbol1 == symbol){
                // 如果同色,让 count++
                count ++;
                i --; // 继续向上找棋子
            }else{
                // 如果不是同色,直接break
                break;
            }
        }
        // 计算当前棋子的下侧有几个同色的棋子
        i = row + 1;
        j = column;
        while (i <= Chessboard.COLUMN_COUNT - 1){
            Piece piece1 = chessboard.getPiece(i,j);
            char symbol1 = piece1.getSymbol();
            if (symbol1 == symbol){
                // 如果同色,让 count++
                count ++;
                i ++; // 继续向下找棋子
            }else{
                // 如果不是同色,直接break
                break;
            }
        }
        if (count >= 5){
            return true;
        }

        //(三)判断斜着(左下右上)是否达到 5 个或者更多同色子
        count = 1; // count需要重置为1
        // 计算当前棋子的左下方有几个同色棋子
        i = row + 1;
        j = column - 1;
        while (i <= Chessboard.ROW_COUNT - 1 && j >= 0){
            Piece piece1 = chessboard.getPiece(i,j);
            char symbol1 = piece1.getSymbol();
            if (symbol1 == symbol){
                // 如果同色,让 count++
                count ++;
                i ++; // 向下移动位置
                j --; // 向左移动位置
            }else{
                // 如果不是同色,直接break
                break;
            }
        }
        // 计算当前棋子的右上方有几个同色的棋子
        i = row - 1;
        j = column + 1;
        while (i >= 0 && j <= Chessboard.COLUMN_COUNT - 1){
            Piece piece1 = chessboard.getPiece(i,j);
            char symbol1 = piece1.getSymbol();
            if (symbol1 == symbol){
                // 如果同色,让 count++
                count ++;
                i --; // 向上移动位置
                j ++; // 向右移动位置
            }else{
                // 如果不是同色,直接break
                break;
            }
        }
        if (count >= 5){
            return true;
        }

        //(四)判断斜着(左上右下)是否达到 5 个或者更多同色子
        count = 1; // count需要重置为1
        // 计算当前棋子的左上方有几个同色棋子
        i = row - 1;
        j = column - 1;
        while (i >= 0 && j >= 0){
            Piece piece1 = chessboard.getPiece(i,j);
            char symbol1 = piece1.getSymbol();
            if (symbol1 == symbol){
                // 如果同色,让 count++
                count ++;
                i --; // 向上移动位置
                j --; // 向左移动位置
            }else{
                // 如果不是同色,直接break
                break;
            }
        }
        // 计算当前棋子的右下方有几个同色的棋子
        i = row + 1;
        j = column + 1;
        while (i <= Chessboard.ROW_COUNT - 1 && j <= Chessboard.COLUMN_COUNT - 1){
            Piece piece1 = chessboard.getPiece(i,j);
            char symbol1 = piece1.getSymbol();
            if (symbol1 == symbol){
                // 如果同色,让 count++
                count ++;
                i ++; // 向上移动位置
                j ++; // 向右移动位置
            }else{
                // 如果不是同色,直接break
                break;
            }
        }
        if (count >= 5){
            return true;
        }

        return false;
    }
}

Location(坐标类)

package com.crb.wuziqi;

public class Location {
    private int row;
    private int column;

    public int getRow() {
        return row;
    }

    public void setRow(int row) {
        this.row = row;
    }

    public int getColumn() {
        return column;
    }

    public void setColumn(int column) {
        this.column = column;
    }

    public Location(int row, int column) {
        this.row = row;
        this.column = column;
    }

    public Location() {
    }

    @Override
    public String toString() {
        return "Location{" +
                "row=" + row +
                ", column=" + column +
                '}';
    }
}

Game(执行类)

package com.crb.wuziqi;

public class Game {
    public static void main(String[] args) {
        // 游戏开始之前,先创建棋盘
        Chessboard chessboard = new Chessboard();
        // 初始化棋盘
        chessboard.initChessboard();
        // 绘制棋盘(空棋盘)
        chessboard.printChessboard();
        // 开始游戏
        startGame(chessboard);
    }

    private static void startGame(Chessboard chessboard) {
        while(true){
            // (一)黑子下棋
            // 提示黑子下棋
            System.out.print("黑子下棋,请输入落子位置(例如:6,A):");
            // 获取黑子落子的位置
            Location location = Rule.getLocation();
            // 判断是否能在此处落子
            // 只要不能落子,就一直获取新的位置
            while (Rule.canPutDown(chessboard, location) == false){
                System.out.print("此处已有棋子,请输入新的位置(例如:6,A):");
                location = Rule.getLocation();
            }
            // 落子
            Piece piece = new Piece(location.getRow(), location.getColumn(),'●');
            chessboard.putDownPiece(piece);
            // 绘制棋盘
            chessboard.printChessboard();
            // 判断输赢
            if (Rule.isWin(chessboard,piece)){
                System.out.println("游戏结束!黑子获胜!");
                break;
            }

            // (二)白子下棋
            // 提示白子下棋
            System.out.print("白子下棋,请输入落子位置(例如:6,A):");
            // 获取白子落子的位置
            Location location1 = Rule.getLocation();
            // 判断是否能在此处落子
            // 只要不能落子,就一直获取新的位置
            while (Rule.canPutDown(chessboard, location1) == false){
                System.out.print("此处已有棋子,请输入新的位置(例如:6,A):");
                location1 = Rule.getLocation();
            }
            // 落子
            Piece piece1 = new Piece(location1.getRow(), location1.getColumn(),'o');
            chessboard.putDownPiece(piece1);
            // 绘制棋盘
            chessboard.printChessboard();
            // 判断输赢
            if (Rule.isWin(chessboard,piece1)){
                System.out.println("游戏结束!白子获胜!");
                break;
            }
        }
    }
}

写在最后的话

        最近开始实训啦,这就是最近做的一个小项目!老师说这个项目“麻雀虽小五脏俱全”,学完java基础和面向对象的基本知识之后,这个就可以当做一个练手的项目啦。有问题的话 评论或私聊都可以哈,看到了一定会回复的!!!加油加油!!!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值