Java实现五子棋(保姆级教学)

阶段项目 五子棋

需求说明

五子棋棋盘是一个10 X 10的棋盘,五子棋玩家共2个(这里分别称为A和B),A在棋盘上落子后,B再落子,以此往复,直到一方胜利或者棋盘空间用完为止。判断胜利的条件是一条直线或者任意斜线上同时存在A或B的连续5颗棋子(见下图)。

在这里插入图片描述

技术实现

1.静态变量

语法

public static 数据类型 变量名 = 变量值;

解释说明

静态变量只能定义在类中,不能定义在方法中。静态变量可以在static修饰的方法中使用,也可以在非静态的方法中访问。主要解决在静态方法中不能访问非静态的变量的问题。

在这里插入图片描述

在这里插入图片描述

2.静态方法

语法

public static 返回值类型 方法名(){
    
}

解释说明

静态方法就相当于一个箱子,只是这个箱子中装的是代码,需要使用这些代码的时候,就把这个箱子放在指定的位置即可。

示例


/**
 * 静态变量和静态方法
 *
 */
public class StaticText {
    //静态变量只能定义在类中,不能定义在方法中
    public static String name = "张三";

    public static void main(String[] args) {
        System.out.println(name);
        show();//用下面定义的show方法来打印信息
    }

    public static void show() {
        System.out.println("张三");
        System.out.println("男");
        System.out.println("20");
    }
}

实现步骤分析

1.制作棋盘

a.使用输入法中的制表符在控制台直接打印出棋盘,然后寻找落子的特征

(制表图形作者用的是搜狗输入法—符号大全—制表符)

System.out.println("┌────┬────┬────┬────┬────┬────┬────┬────┬────┐");
System.out.println("│    │    │    │    │    │    │    │    │    │");
System.out.println("├────┼────┼────┼────┼────┼────┼────┼────┼────┤");
System.out.println("│    │    │    │    │    │    │    │    │    │");
System.out.println("├────┼────┼────┼────┼────┼────┼────┼────┼────┤");
System.out.println("│    │    │    │    │    │    │    │    │    │");
System.out.println("├────┼────┼────┼────┼────┼────┼────┼────┼────┤");
System.out.println("│    │    │    │    │    │    │    │    │    │");
System.out.println("├────┼────┼────┼────┼────┼────┼────┼────┼────┤");
System.out.println("│    │    │    │    │    │    │    │    │    │");
System.out.println("├────┼────┼────┼────┼────┼────┼────┼────┼────┤");
System.out.println("│    │    │    │    │    │    │    │    │    │");
System.out.println("├────┼────┼────┼────┼────┼────┼────┼────┼────┤");
System.out.println("│    │    │    │    │    │    │    │    │    │");
System.out.println("├────┼────┼────┼────┼────┼────┼────┼────┼────┤");
System.out.println("│    │    │    │    │    │    │    │    │    │");
System.out.println("├────┼────┼────┼────┼────┼────┼────┼────┼────┤");
System.out.println("│    │    │    │    │    │    │    │    │    │");
System.out.println("└────┴────┴────┴────┴────┴────┴────┴────┴────┘");

b.利用二维数组重新制作棋盘

/**
 * 五子棋
 *
 */
public class Gobang {

    public static char[][] chessboard = {
            {'┌','┬','┬','┬','┬','┬','┬','┬','┬','┐'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'└','┴','┴','┴','┴','┴','┴','┴','┴','┘'}
    };

    public static String separator = "────";

    public static void main(String[] args) {
        System.out.println("    0    1    2    3    4    5    6    7    8    9");
        for(int i=0; i<chessboard.length; i++){//外层循环控制行
            System.out.print(i + "   ");
            for(int j=0; j<chessboard[i].length; j++){//内层循环控制列
                if(j == chessboard[i].length - 1){//最后一列
                    System.out.print(chessboard[i][j]);
                } else {
                    System.out.print(chessboard[i][j] + separator);//使用print打印,不换行
                }
            }
            System.out.println();//打印完一行后换行
            if(i < chessboard.length-1) {//排除最后一行
                System.out.println("    │    │    │    │    │    │    │    │    │    │");
            }
        }
    }
}

c.棋盘在玩家使用过程中会反复展示,需要使用方法来进行优化

public class Gobang {

    public static char[][] chessboard = {
            {'┌','┬','┬','┬','┬','┬','┬','┬','┬','┐'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'└','┴','┴','┴','┴','┴','┴','┴','┴','┘'}
    };

    public static String separator = "────";

    public static void main(String[] args) {
        showChessboard();
    }

    public static void showChessboard() {

        System.out.println("========================================================");
        System.out.println("    0    1    2    3    4    5    6    7    8    9");
        for(int i=0; i<chessboard.length; i++){//外层循环控制行
            System.out.print(i + "   ");
            for(int j=0; j<chessboard[i].length; j++){//内层循环控制列
                if(j == chessboard[i].length - 1){//最后一列
                    System.out.print(chessboard[i][j]);
                } else {
                    System.out.print(chessboard[i][j] + separator);//使用print打印,不换行
                }
            }
            System.out.println();//打印完一行后换行
            if(i < chessboard.length-1) {//排除最后一行
                System.out.println("    │    │    │    │    │    │    │    │    │    │");
            }
        }
    }
}

2.落子

a.玩家A、B会交替落子
int totalPosition = chessboard.length * chessboard[0].length;
for(int times=0; times < totalPosition; times++){
    System.out.println(times % 2 == 0 ? "请玩家A落子" : "请玩家B落子");
}
b.落子位置必须是0~100之间的整数,且不能使用已经存在棋子的位置
import java.util.Scanner;

/**
 * 五子棋
 *
 */
public class Gobang {

    public static char[][] chessboard = {
            {'┌','┬','┬','┬','┬','┬','┬','┬','┬','┐'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'└','┴','┴','┴','┴','┴','┴','┴','┴','┘'}
    };

    public static String separator = "────";

    public static char pieceA = '○';//玩家A的棋子
    public static char pieceB = '■';//玩家B的棋子

    public static void main(String[] args) {
        showChessboard();
        Scanner sc = new Scanner(System.in);
        int totalPosition = chessboard.length * chessboard[0].length;
        for(int times=0; times < totalPosition; times++){
            System.out.println(times % 2 == 0 ? "请玩家A落子:" : "请玩家B落子:");
            char currentPiece = (times % 2 == 0) ? pieceA : pieceB;//当前使用的棋子
            while(true) {//保证落子成功才能够退出循环
                //检测Scanner中是否有输入的数据并且判断数据是否为整数,如果没有数据,就需要从控制台输入
                if(sc.hasNextInt()){
                    int position = sc.nextInt();
                    if (position >= 0 && position < totalPosition) {
                        //比如:position = 21在13 X 13的棋盘中,行号为21 / 13 = 1,列号为21 % 13 = 8
                        int row = position / chessboard.length;//位置除以棋盘数组的长度得到行号
                        int colo = position % chessboard[0].length;//位置取模棋盘总列数得到列号
                        if(chessboard[row][colo] == pieceA || chessboard[row][colo] == pieceB){
                            System.out.println("该位置已经有落子了,请重新选择落子位置");
                            continue;
                        } else {
                            chessboard[row][colo] = currentPiece;
                            break;
                        }
                    } else {
                        System.out.println("非法落子,请重新选择落子位置");
                    }
                } else {
                    System.out.println("非法落子,请输入整数");
                    sc.next();//将Scanner中存储的非法数据取出来,防止死循环
                }

            }
            //落子完成后,棋盘需重新展示
            showChessboard();
        }
    }

    public static void showChessboard() {
        System.out.println("========================================================");
        System.out.println("    0    1    2    3    4    5    6    7    8    9");
        for(int i=0; i<chessboard.length; i++){//外层循环控制行
            System.out.print(i + "   ");
            for(int j=0; j<chessboard[i].length; j++){//内层循环控制列
                if(j == chessboard[i].length - 1){//最后一列
                    System.out.print(chessboard[i][j]);
                } else {
                    System.out.print(chessboard[i][j] + separator);//使用print打印,不换行
                }
            }
            System.out.println();//打印完一行后换行
            if(i < chessboard.length-1) {//排除最后一行
                System.out.println("    │    │    │    │    │    │    │    │    │    │");
            }
        }
    }
}
c.落子完成后,需要校验是否获胜
import java.util.Scanner;

/**
 * 五子棋
 *
 */
public class Gobang {

    public static char[][] chessboard = {
            {'┌','┬','┬','┬','┬','┬','┬','┬','┬','┐'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'└','┴','┴','┴','┴','┴','┴','┴','┴','┘'}
    };

    public static String separator = "────";

    public static char pieceA = '○';//玩家A的棋子
    public static char pieceB = '■';//玩家B的棋子

    public static void main(String[] args) {
        showChessboard();
        Scanner sc = new Scanner(System.in);
        int totalPosition = chessboard.length * chessboard[0].length;
        outer:
        for(int times=0; times < totalPosition; times++){
            System.out.println(times % 2 == 0 ? "请玩家A落子:" : "请玩家B落子:");
            char currentPiece = (times % 2 == 0) ? pieceA : pieceB;//当前使用的棋子
            while(true) {//保证落子成功才能够退出循环
                //检测Scanner中是否有输入的数据并且判断数据是否为整数,如果没有数据,就需要从控制台输入
                if(sc.hasNextInt()){
                    int position = sc.nextInt();
                    if (position >= 0 && position < totalPosition) {
                        //比如:position = 21在13 X 13的棋盘中,行号为21 / 13 = 1,列号为21 % 13 = 8
                        int row = position / chessboard.length;//位置除以棋盘数组的长度得到行号
                        int colo = position % chessboard[0].length;//位置取模棋盘总列数得到列号
                        if(chessboard[row][colo] == pieceA || chessboard[row][colo] == pieceB){
                            System.out.println("该位置已经有落子了,请重新选择落子位置");
                            continue;
                        } else {
                            chessboard[row][colo] = currentPiece;
                            break;
                        }
                    } else {
                        System.out.println("非法落子,请重新选择落子位置");
                    }
                } else {
                    System.out.println("非法落子,请输入整数");
                    sc.next();//将Scanner中存储的非法数据取出来,防止死循环
                }

            }
            //落子完成后,棋盘需重新展示
            showChessboard();
            //判断获胜情况:一共4种
            for(int i=0; i<chessboard.length; i++){
                for(int j=0; j<chessboard[i].length; j++){
                    //第一种:水平方向上存在同一玩家的连续5颗棋子
                    //(i,j) (i,j+1) (i,j+2) (i,j+3) (i,j+4)
                    boolean case1 = (j + 4 < chessboard[i].length)
                            && chessboard[i][j]   == currentPiece
                            && chessboard[i][j+1] == currentPiece
                            && chessboard[i][j+2] == currentPiece
                            && chessboard[i][j+3] == currentPiece
                            && chessboard[i][j+4] == currentPiece;
                    //第二种:垂直方向上存在同一玩家的连续5颗棋子
                    //(i,j)(i+1,j)(i+2,j)(i+3,j)(i+4,j)
                    boolean case2 = (i + 4 <chessboard.length)
                            && chessboard[i][j]   == currentPiece
                            && chessboard[i+1][j] == currentPiece
                            && chessboard[i+2][j] == currentPiece
                            && chessboard[i+3][j] == currentPiece
                            && chessboard[i+4][j] == currentPiece;
                    //第三种:135°角存在同一玩家的连续5颗棋子
                    //(i,j) (i+1,j+1) (i+2,j+2) (i+3,j+3) (i+4,j+4)
                    boolean case3 = (i + 4 <chessboard.length)
                            && (j + 4 < chessboard[i].length)
                            && chessboard[i][j]      == currentPiece
                            && chessboard[i+1][j+1]  == currentPiece
                            && chessboard[i+2][j+2]  == currentPiece
                            && chessboard[i+3][j+3]  == currentPiece
                            && chessboard[i+4][j+4]  == currentPiece;
                    //第四种:45°角存在同一玩家的连续5颗棋子
                    //(i,j) (i-1,j+1) (i-2,j+2) (i-3,j+3) (i-4,j+4)
                    boolean case4 = (i - 4 >= 0)
                            && (j + 4 < chessboard[i].length)
                            && chessboard[i][j]      == currentPiece
                            && chessboard[i-1][j+1]  == currentPiece
                            && chessboard[i-2][j+2]  == currentPiece
                            && chessboard[i-3][j+3]  == currentPiece
                            && chessboard[i-4][j+4]  == currentPiece;
                    if(case1 || case2 || case3 || case4){
                        System.out.println(times % 2 == 0 ? "玩家A获得胜利":"玩家B获得胜利");
                        break outer;
                    }
                }
            }
        }
    }

    public static void showChessboard() {
        System.out.println("========================================================");
        System.out.println("    0    1    2    3    4    5    6    7    8    9");
        for(int i=0; i<chessboard.length; i++){//外层循环控制行
            System.out.print(i + "   ");
            for(int j=0; j<chessboard[i].length; j++){//内层循环控制列
                if(j == chessboard[i].length - 1){//最后一列
                    System.out.print(chessboard[i][j]);
                } else {
                    System.out.print(chessboard[i][j] + separator);//使用print打印,不换行
                }
            }
            System.out.println();//打印完一行后换行
            if(i < chessboard.length-1) {//排除最后一行
                System.out.println("    │    │    │    │    │    │    │    │    │    │");
            }
        }
    }
}
d.棋盘使用完毕还未分出胜负,需要提示(最终版)
import java.util.Scanner;

/**
 * 五子棋
 *
 */
public class Gobang {

    public static char[][] chessboard = {
            {'┌','┬','┬','┬','┬','┬','┬','┬','┬','┐'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'├','┼','┼','┼','┼','┼','┼','┼','┼','┤'},
            {'└','┴','┴','┴','┴','┴','┴','┴','┴','┘'}
    };

    public static String separator = "────";

    public static char pieceA = '○';//玩家A的棋子
    public static char pieceB = '■';//玩家B的棋子

    public static int times = 0; //记录棋盘使用次数,偶数次玩家A落子,奇数次玩家B落子

    public static void main(String[] args) {
        showChessboard();
        Scanner sc = new Scanner(System.in);
        int totalPosition = chessboard.length * chessboard[0].length;
        outer:
        while(times < totalPosition){
            System.out.println(times % 2 == 0 ? "请玩家A落子:" : "请玩家B落子:");
            char currentPiece = (times % 2 == 0) ? pieceA : pieceB;//当前使用的棋子
            while(true) {//保证落子成功才能够退出循环
                //检测Scanner中是否有输入的数据并且判断数据是否为整数,如果没有数据,就需要从控制台输入
                if(sc.hasNextInt()){
                    int position = sc.nextInt();
                    if (position >= 0 && position < totalPosition) {
                        //比如:position = 21在13 X 13的棋盘中,行号为21 / 13 = 1,列号为21 % 13 = 8
                        int row = position / chessboard.length;//位置除以棋盘数组的长度得到行号
                        int colo = position % chessboard[0].length;//位置取模棋盘总列数得到列号
                        if(chessboard[row][colo] == pieceA || chessboard[row][colo] == pieceB){
                            System.out.println("该位置已经有落子了,请重新选择落子位置");
                            continue;
                        } else {
                            chessboard[row][colo] = currentPiece;
                            break;
                        }
                    } else {
                        System.out.println("非法落子,请重新选择落子位置");
                    }
                } else {
                    System.out.println("非法落子,请输入整数");
                    sc.next();//将Scanner中存储的非法数据取出来,防止死循环
                }

            }
            //落子完成后,棋盘需重新展示
            showChessboard();
            //判断获胜情况:一共4种
            for(int i=0; i<chessboard.length; i++){
                for(int j=0; j<chessboard[i].length; j++){
                    //第一种:水平方向上存在同一玩家的连续5颗棋子
                    //(i,j) (i,j+1) (i,j+2) (i,j+3) (i,j+4)
                    boolean case1 = (j + 4 < chessboard[i].length)
                            && chessboard[i][j]   == currentPiece
                            && chessboard[i][j+1] == currentPiece
                            && chessboard[i][j+2] == currentPiece
                            && chessboard[i][j+3] == currentPiece
                            && chessboard[i][j+4] == currentPiece;
                    //第二种:垂直方向上存在同一玩家的连续5颗棋子
                    //(i,j)(i+1,j)(i+2,j)(i+3,j)(i+4,j)
                    boolean case2 = (i + 4 <chessboard.length)
                            && chessboard[i][j]   == currentPiece
                            && chessboard[i+1][j] == currentPiece
                            && chessboard[i+2][j] == currentPiece
                            && chessboard[i+3][j] == currentPiece
                            && chessboard[i+4][j] == currentPiece;
                    //第三种:135°角存在同一玩家的连续5颗棋子
                    //(i,j) (i+1,j+1) (i+2,j+2) (i+3,j+3) (i+4,j+4)
                    boolean case3 = (i + 4 <chessboard.length)
                            && (j + 4 < chessboard[i].length)
                            && chessboard[i][j]      == currentPiece
                            && chessboard[i+1][j+1]  == currentPiece
                            && chessboard[i+2][j+2]  == currentPiece
                            && chessboard[i+3][j+3]  == currentPiece
                            && chessboard[i+4][j+4]  == currentPiece;
                    //第四种:45°角存在同一玩家的连续5颗棋子
                    //(i,j) (i-1,j+1) (i-2,j+2) (i-3,j+3) (i-4,j+4)
                    boolean case4 = (i - 4 >= 0)
                            && (j + 4 < chessboard[i].length)
                            && chessboard[i][j]      == currentPiece
                            && chessboard[i-1][j+1]  == currentPiece
                            && chessboard[i-2][j+2]  == currentPiece
                            && chessboard[i-3][j+3]  == currentPiece
                            && chessboard[i-4][j+4]  == currentPiece;
                    if(case1 || case2 || case3 || case4){
                        System.out.println(times % 2 == 0 ? "玩家A获得胜利":"玩家B获得胜利");
                        break outer;
                    }
                }
            }
            times++;
        }
        if(times == totalPosition){ //说明棋盘已经用完还未分出胜负
            System.out.println("平局");
        }
    }

    public static void showChessboard() {
        System.out.println("========================================================");
        System.out.println("    0    1    2    3    4    5    6    7    8    9");
        for(int i=0; i<chessboard.length; i++){//外层循环控制行
            System.out.print(i + "   ");
            for(int j=0; j<chessboard[i].length; j++){//内层循环控制列
                if(j == chessboard[i].length - 1){//最后一列
                    System.out.print(chessboard[i][j]);
                } else {
                    System.out.print(chessboard[i][j] + separator);//使用print打印,不换行
                }
            }
            System.out.println();//打印完一行后换行
            if(i < chessboard.length-1) {//排除最后一行
                System.out.println("    │    │    │    │    │    │    │    │    │    │");
            }
        }
    }
}
    for(int j=0; j<chessboard[i].length; j++){//内层循环控制列
            if(j == chessboard[i].length - 1){//最后一列
                System.out.print(chessboard[i][j]);
            } else {
                System.out.print(chessboard[i][j] + separator);//使用print打印,不换行
            }
        }
        System.out.println();//打印完一行后换行
        if(i < chessboard.length-1) {//排除最后一行
            System.out.println("    │    │    │    │    │    │    │    │    │    │");
        }
    }
}

}


<think>好的,我需要帮助用户找到关于用Java实现五子棋的代码和教程。根据用户提供的引用内容,有三个相关的资料。首先,用户引用[1]提到一个教程,分为用户界面初始化、自定义棋盘画板和事件监听逻辑。引用[2]和[3]则涉及具体的代码片段,比如悔棋逻辑和窗口创建。 我应该先整理这些引用中的信息,看看如何构建一个五子棋的基本结构。用户需要具体的代码示例和教程步骤,所以需要分步骤讲解,可能包括窗口创建、棋盘绘制、事件处理、胜负判断和悔棋功能。同时,用户要求使用中文回答,并且按照系统指令中的格式要求,数学表达式用$...$,独立公式用$$...$$,但在这个问题中可能用不上数学公式,不过需要确保代码块正确。 接下来,我需要检查是否有遗漏的部分,比如胜负判断逻辑在引用中没有详细提到,可能需要补充。另外,悔棋功能的实现引用[2]中有部分代码,可以整合到示例中。同时,确保代码语法正确,比如Java的类和方法命名,事件监听的添加等。 用户的问题还可能包括相关的问题生成,比如如何实现胜负判断、如何优化界面、如何处理网络对战等。需要根据现有引用和常见开发问题来生成相关问题。 最后,确保回答结构清晰,分步骤说明,并正确引用提供的资料。需要验证代码片段是否完整,比如引用[3]中的MFrame类是否和TablePanel结合使用,事件监听部分如何与棋盘交互。如果有不确定的地方,可能需要假设或补充通用实现方法,比如鼠标点击事件获取坐标并落子。</think># Java五子棋实现教程 ### 一、基础框架搭建 1. **创建游戏窗口** ```java public class ChessWindow { public static void main(String[] args) { JFrame frame = new JFrame("五子棋 v1.0"); frame.setSize(800, 700); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(false); ChessBoard board = new ChessBoard(); frame.add(board); frame.setVisible(true); } } ``` 通过JFrame创建固定大小窗口,设置居中显示和关闭策略[^3]。 2. **棋盘绘制组件** ```java class ChessBoard extends JPanel { private static final int ROWS = 15; private int[][] chessData = new int[ROWS][ROWS]; // 0-空 1-黑 2-白 @Override protected void paintComponent(Graphics g) { super.paintComponent(g); // 绘制棋盘网格 for (int i=0; i<ROWS; i++) { g.drawLine(30, 30+i*40, 590, 30+i*40); g.drawLine(30+i*40, 30, 30+i*40, 590); } // 绘制棋子 for (int r=0; r<ROWS; r++) { for (int c=0; c<ROWS; c++) { if(chessData[r][c] == 1){ g.setColor(Color.BLACK); g.fillOval(30 + c*40 -15, 30 + r*40 -15, 30, 30); } else if(chessData[r][c] == 2) { g.setColor(Color.WHITE); g.fillOval(30 + c*40 -15, 30 + r*40 -15, 30, 30); } } } } } ``` 使用二维数组存储棋子状态,通过覆写paintComponent实现棋盘绘制[^3]。 ### 二、核心功能实现 1. **事件监听处理** ```java class ChessBoard extends JPanel implements MouseListener { private boolean isBlackTurn = true; public ChessBoard() { this.addMouseListener(this); } @Override public void mouseClicked(MouseEvent e) { int x = e.getX(); int y = e.getY(); // 坐标转换为行列索引 int row = Math.round((y-30)/40f); int col = Math.round((x-30)/40f); if(row >=0 && row < ROWS && col >=0 && col < ROWS && chessData[row][col] == 0) { chessData[row][col] = isBlackTurn ? 1 : 2; checkWin(row, col); isBlackTurn = !isBlackTurn; repaint(); } } // 其他MouseListener方法需空实现 } ``` 通过鼠标监听实现落子逻辑,注意坐标转换的精度处理[^3]。 2. **胜负判断(核心算法)** ```java private void checkWin(int row, int col) { int[][] directions = {{1,0}, {0,1}, {1,1}, {1,-1}}; int current = chessData[row][col]; for (int[] dir : directions) { int count = 1; // 正向检测 for(int i=1; i<=4; i++){ int r = row + dir[0]*i; int c = col + dir[1]*i; if(r <0 || r>=ROWS || c<0 || c>=ROWS) break; if(chessData[r][c] == current) count++; else break; } // 反向检测 for(int i=1; i<=4; i++){ int r = row - dir[0]*i; int c = col - dir[1]*i; if(r <0 || r>=ROWS || c<0 || c>=ROWS) break; if(chessData[r][c] == current) count++; else break; } if(count >=5) showWinDialog(current); } } ``` 采用四方向检测法,每个方向正反检测连续棋子数[^1]。 ### 三、功能扩展 1. **悔棋功能实现** ```java Stack<int[]> moveHistory = new Stack<>(); // 记录落子 chessData[row][col] = isBlackTurn ? 1 : 2; moveHistory.push(new int[]{row, col}); // 悔棋逻辑 public void undo() { if(moveHistory.isEmpty()) return; int[] last = moveHistory.pop(); chessData[last[0]][last[1]] = 0; isBlackTurn = !isBlackTurn; repaint(); } ``` 使用栈结构存储落子记录实现悔棋功能[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值