从零实现五子棋

界面开发部分:

1 :创建窗体
继承 JFrame 调用 JFrame 设置标题 尺寸 关闭 可视化 布局等功能
设置布局为 null 布局 ,按钮都需要指定位置
2 :绘制棋盘
重写 JFrame paint 方法
绘制背景矩形 绘制网格

监听器部分:

1 : 按钮监听 ActionListener
2 : 鼠标监听器: MouseListener

存储棋子部分:

1 : 二维数组存储棋子
2 : 实现重绘棋子 在重绘的方法中 paint 方法中
3 : 判断输赢

悔棋:

1:    知道每一颗棋子的顺序
2:    创建一个棋子类,将棋子的坐标以及棋子标识设置为属性 每次下棋时 创建一个棋子对象 存入一个棋子对象一维数组中
3;    点击悔棋按钮时,将棋子对象数组中的最后一个棋子对象取出获取其行列值 删除二维数组中的数据 再删除一维数组中的棋子对象 重置标识 自动刷新
package Gobang;

import javax.swing.*;
import java.awt.*;
public class GoUI extends JFrame {

    int X = 50, Y = 75, SIZE = 50, ROWS = 15, COLS = 15;

    GoListener goListener = new GoListener();
    public void showUI() {
// 子类调用父类的方法 继承到的方法
        setTitle("五子棋");
        setSize(1000, 900);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setLayout(null);// 空布局

        JButton btn1 = new JButton("开始游戏");
        JButton btnRb = new JButton("悔棋");
// 设置位置 和 尺寸
        btn1.setBounds(X + COLS * SIZE + SIZE, 100, 100, 35);
        btnRb.setBounds(X + COLS * SIZE + SIZE, 150, 100, 35);

        Font font = new Font("宋体", Font.BOLD, 15);
        btn1.setFont(font);
        btnRb.setFont(font);

        add(btn1);// 添加到窗体上
        add(btnRb);

        setVisible(true);
// 窗体添加鼠标监听器

        addMouseListener(goListener);
//按钮添加动作监听器
        btn1.addActionListener(goListener);
        btnRb.addActionListener(goListener);
// 获取窗体对象上的画笔对象
        Graphics gr = getGraphics();
// 讲画笔对象名中存储画笔对象地址 复制一份给监听器中的对象变量名
// 初始化监听器中的画笔对象变量名 赋值
        goListener.g = gr;
    }

    int count = 0;

    // 重写paint方法了
    @Override
//自动刷新

    public void paint(Graphics g){
        super.paint(g);
        goListener.paintChessPad(g);
    }

    public static void main(String[] args) {
        GoUI goUI = new GoUI();
        goUI.showUI();
    }
}

这段代码是一个使用Java编写的五子棋(Gobang)游戏界面,使用Swing库来创建GUI界面。

package Gobang;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.concurrent.ConcurrentSkipListSet;

public class GoListener implements MouseListener, ActionListener{
    Graphics g;// 图形渲染工具 绘制一些基础图形 直线 圆 矩形 文字
    // 1: 必须在组件上获取 窗体对象上获取 只能在窗体上获取,使用的坐标系也是窗体的坐标系
// 2: 必须在可视化之后获取 在窗体可视化之前获取的话,获取到的是空值
    int X = 50, Y = 75, SIZE = 50, ROWS = 15, COLS = 15;
    int chessFlag=0;// 0不能下棋 1黑棋 2白棋

    int[][] chessArr = new int[ROWS+1][COLS+1];

    //存储棋子数组线性

    Chess[] chessList =  new Chess[(ROWS+1)*(COLS+1)];
    int listIndex=0;

    public void actionPerformed(ActionEvent e){
        System.out.println ("按钮被点击了");
// 获取按钮的文本
        String btnStr = e.getActionCommand ();
// 获取按钮的对象
        JButton btn = (JButton) e.getSource ();
        if(btnStr.equals ("开始游戏")){
            chessFlag=1;// 设置标识 为 黑棋先下
// 点击开始游戏按钮之后 将文本替换成 结束游戏
            btn.setText ("结束游戏");
        }else if(btnStr.equals ("结束游戏")){
            chessFlag=0;// 设置标识 不能下棋
            chessArr = new int[ROWS+1][COLS+1];
            paintChessPad(g);
// 点击结束游戏按钮 替换成开始游戏
            btn.setText ("开始游戏");
        } else if (btnStr.equals("悔棋")) {
            if (listIndex <= 1) {
                JOptionPane.showMessageDialog(null, "已经没有棋子可以悔棋了");
                return;
            }
            Chess chess = chessList[listIndex - 1];
            // 最后一个棋子
            chessArr[chess.r][chess.c] = 0;// 删棋盘上的数据
            chessList[listIndex - 1] = null;// 删除棋子对象
            listIndex--;// 下标减1

            chessFlag = chess.chessFlag;
            paintChessPad(g);//刷新棋盘界面
        }
        }

    @Override
    public void mousePressed(MouseEvent e) {
        System.out.println("鼠标按下");
        if (chessFlag == 0) {
            System.out.println("游戏未开始");
// 弹窗
            JOptionPane.showMessageDialog(null, "游戏未开始");
            return;// 结束方法
        }
        int x = e.getX();
        int y = e.getY();
        System.out.println("x = " + x + " y = " + y);
// 校正坐标 1步: 将x y 换算成 行列值 0-0 开始
        int c = (x - 50 + 25) / 50;
        int r = (y - 75 + 25) / 50;
        System.out.println("c = " + c + " r = " + r);
// 根据行列值判断下棋的范围
        if (c < 0 || c > 15 || r < 0 || r > 15) {
            System.out.println("此处不能下棋");
// 弹窗
            JOptionPane.showMessageDialog(null, "此处不能下棋");
            return;// 结束下棋 结束方法
        }

        //判断是否重复下棋
        if (chessArr[r][c] != 0) {
            JOptionPane.showMessageDialog(null, "此处已有棋子,请重新下棋");
            return;
        }
// 将棋子存入棋盘数组
        chessArr[r][c] = chessFlag;

//将数据转为一个棋子对象
        Chess chess = new Chess();
        chess.r=r;
        chess.c=c;
        chess.chessFlag= chessFlag;

//存入棋子对象数组中
        chessList[listIndex]=chess;
        listIndex++;

// 能够确定可以下棋了 才能设置颜色 交换标识

// 2步:根据行列还原 标准坐标

        int chessX = c * 50 + 50 - 25;
        int chessY = r * 50 + 75 - 25;

        if (chessFlag == 1) {
            for (int i = 0; i < SIZE; i++) {
                Color color = new Color(1+i , 1+i , 1+i );
                g.setColor(color);
                g.fillOval(chessX + i / 2, chessY + i / 2, SIZE - i, SIZE - i);
            }
            chessFlag = 2;
        } else if (chessFlag == 2) {
            for (int i = 0; i < SIZE; i++) {
                Color color = new Color(210 + i, 200 + i, 200 + i);
                g.setColor(color);
                g.fillOval(chessX + i / 2, chessY + i / 2, SIZE - i, SIZE - i);
                chessFlag = 1;
            }


        }

        //判断输赢c
        boolean winFlag = GoIsWin.isWin(r,c,chessArr);
        if(winFlag) {
            if (chessFlag == 1) {
                JOptionPane.showMessageDialog(null, "白棋赢了");
            } else if (chessFlag == 2) {
                JOptionPane.showMessageDialog(null, "黑棋赢了");
            }
            chessFlag = 0;
        }
        //g.fillOval(chessX, chessY, SIZE, SIZE);
        /*if(chessFlag==1){
            g.setColor (Color.BLACK);
            chessFlag=2;
        }else if(chessFlag==2){
            g.setColor (Color.WHITE);
            chessFlag=1;
        }*/

    }
//自动刷新
    public void paintChessPad(Graphics g){

// 绘制背景
        Color color = new Color(84, 190, 163);//0-255
        g.setColor(color);
        g.fillRect(X - SIZE / 2, Y - SIZE / 2, SIZE * ROWS + SIZE, SIZE * ROWS + SIZE);
// 绘制棋盘
        int X = 50, Y = 75, SIZE = 50, ROWS = 15, COLS = 15;
        g.setColor(Color.PINK);
        for (int i = 0; i <= 15; i++) {
            g.drawLine(X, Y + i * SIZE, X + COLS * SIZE, Y + i * SIZE);
            g.drawLine(X + i * SIZE, Y, X + i * SIZE, Y + ROWS * SIZE);
        }

        g.setColor(Color.PINK);
        g.drawRect(X - 25, Y - 25, SIZE * COLS + SIZE, SIZE * ROWS + SIZE);



        //使用监听器调用二维数组


        for (int i = 0; i < chessArr.length; i++) {
            for (int j = 0; j < chessArr[i].length; j++) {
                int n = chessArr[i][j];
// 先判断是不是0 0代表没有棋子
                if (n != 0) {
                    int chessX = j * 50 + 50 - 25;
                    int chessY = i * 50 + 75 - 25;
                    // g.fillOval(X+j*SIZE-SIZE/2, Y+i*SIZE-SIZE/2, SIZE, SIZE);
                    if (n == 1) {
                        for (int m = 0; m < SIZE; m++) {
                            Color color2 = new Color(m * 5, m * 5, m * 5);
                            g.setColor(color2);
                            g.fillOval(chessX + m / 2, chessY + m / 2, SIZE - m, SIZE - m);
                        }
                    }
                    else if (n == 2) {
                        for (int m = 0; m < SIZE; m++) {
                            Color color1 = new Color(200 + m, 200 + m, 200 + m);
                            g.setColor(color1);
                            g.fillOval(chessX + m / 2, chessY + m / 2, SIZE - m, SIZE - m);
                        }
                    }

                }
            }
        }
    }

    @Override
    public void mouseClicked(MouseEvent e){
    }
    @Override
    public void mouseReleased(MouseEvent e){
    }
    @Override
    public void mouseEntered(MouseEvent e){
    }
    @Override
    public void mouseExited(MouseEvent e){
    }
}

 这段代码是五子棋游戏的事件监听器类 GoListener,它实现了 MouseListenerActionListener 接口,用于处理鼠标事件和按钮点击事件。

package Gobang;


public class GoIsWin {
    public static boolean isWin(int r,int c,int[][] chessArr){
    if(row(r,c,chessArr) >= 5 ||
       col(r,c,chessArr)  >=  5||
       left(r,c,chessArr) >=  5||
       right(r,c,chessArr)  >=  5){
        return true;
    }
    return false;
}

private static int right(int r, int c, int[][] chessArr) {
        int count = 0;
        int c1 = chessArr[r][c];
// 右上方
        for (int i = r - 1, j = c + 1; i >= 0 && j < chessArr[0].length; i--, j++) {
            if (c1 == chessArr[i][j]) {
                count++;
            } else {
                break;
            }
        }
        for (int i = r + 1, j = c - 1; i < chessArr.length && j >= 0; i++, j--) {
            if (c1 == chessArr[i][j]) {
                count++;
            } else {
                break;
            }
        }
        count ++;
        return count;
    }

private static int left(int r, int c, int[][] chessArr) {
       int count = 0;
       int c1 = chessArr[r][c];
                for (int i = r + 1, j = c + 1; i < chessArr.length && j < chessArr[0].length; i++, j++) {
                    if (c1 == chessArr[i][j]) {
                        count++;
                    } else {
                        break;
                    }
                }
                for (int i = r - 1, j = c - 1; i >= 0 && j >= 0; i--, j--) {
                    if (c1 == chessArr[i][j]) {
                        count++;
                    } else {
                        break;
                    }
                }
                count++;
                return count;

            }

            private static int col ( int r, int c, int[][] chessArr){

                int count = 0;
                int c1 = chessArr[r][c];
                for (int i = r + 1; i < chessArr.length; i++) {
                    if (c1 == chessArr[i][c]) {
                        count++;
                    } else {
                        break;
                    }
                }
                for (int i = r - 1; i >= 0; i++) {
                    if (c1 == chessArr[i][c]) {
                        count++;
                    } else {
                        break;
                    }
                }
                count++;
                return count;
            }

            private static int row ( int r, int c, int[][] chessArr){
                int count = 0;
                int c1 = chessArr[r][c];
                for (int i = 0; i < chessArr.length; i++) {
                    if (c1 == chessArr[r][i]) {
                        count++;
                    } else {
                        break;
                    }
                }


                for (int i = c - 1; i >= 0; i--) {
                    if (c1 == chessArr[r][i]) {
                        count++;
                    } else {
                        break;
                    }
                }
                count++;
                return count;
            }

        }

五子棋游戏中的胜利判断逻辑,用于检测玩家是否获胜。以下是代码的主要功能和解释:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值