JAVA 五子棋程序

一个简单的五子棋程序,实现了人机对战、人人对战、悔棋、认输功能。

一、首先是制作界面,也就是下棋界面。要画一个棋盘,添加按钮实现各种功能。
(1)创建一个ChessTable类来存放棋盘的基础数据,比如横向线的条数、纵向线的条数、单元格的大小、棋子的直径等。定义一个类是为了更改棋盘基础数据的时候更加方便。

public interface ChessTable {
    public int x0 = 50; //表格左上角起点的x值
    public int y0 = 70; //表格左上角起点的y值
    public int rows = 11; //横向线的条数
    public int columns = 11; //纵向线的条数
    public int chess_size = 30; //棋子的直径
    public int size = 40; //单元格的大小

}

(2)接下来是下棋界面的设计,考虑到后面要实现悔棋和改变界面大小,就要用到重绘。所以在创建类的时候直接继承JFrame,然后在类里面重写paint()方法来实现重绘。
JPanel是一个容器组件,可以把按钮添加到JPanel中。然后指定JPanel存放的位置。
通过ImageIcon可以在界面中添加背景图片,增加观赏性。

public class Gobang extends JFrame {
   

    public static void main(String[] args) {
        Gobang gb = new Gobang();
        gb.showJFrame();
    }

    //初始化窗体的方法
    public void showJFrame() {
        this.setTitle("五子棋");
        this.setSize(650, 550);
        this.setDefaultCloseOperation(3);
        this.setLocationRelativeTo(null);
        this.setResizable(false);//界面不可改变大小
        this.setLayout(new BorderLayout());
        //添加容器组件
        JPanel jl = new JPanel();
        jl.setPreferredSize(new Dimension(150,0));
        jl.setBackground(Color.LIGHT_GRAY);
        JButton start = new JButton("开始新游戏");
        start.setPreferredSize(new Dimension(100,30));
        jl.add(start);
        JButton back = new JButton("悔棋");
        back.setPreferredSize(new Dimension(80,30));
        jl.add(back);
        JButton giveup = new JButton("认输");
        giveup.setPreferredSize(new Dimension(80,30));
        jl.add(giveup);

        String[] type = {
  "人人对战","人机对战"};
        JComboBox<String> box = new JComboBox<>(type);
        box.setPreferredSize(new Dimension(90,30));
        jl.add(box);

        this.add(jl,BorderLayout.EAST);
        this.setVisible(true);
    }

    //重写绘制界面的方法
    public void paint(Graphics g) {
       //在界面加上图片
       ImageIcon image = new ImageIcon("C:\\Users\\某某某\\Desktop\\文档\\五子棋背景图\\1.jpg");
        g.drawImage(image.getImage(),50,70,400,400,null);
    }

    //画棋盘
    public void drawChessTable(Graphics g) {
        //画横线
        for(int i = 0;i < ChessTable.rows;i++) {
            g.drawLine(ChessTable.x0, ChessTable.y0+i*ChessTable.size, 
                    ChessTable.x0+(ChessTable.columns - 1)*ChessTable.size, ChessTable.y0+i*ChessTable.size);
        }
        //画竖线
        for(int j = 0;j < ChessTable.rows;j++) {
            g.drawLine(ChessTable.x0+j*ChessTable.size, ChessTable.y0, 
                    ChessTable.x0+j*ChessTable.size, ChessTable.y0+(ChessTable.rows - 1)*ChessTable.size);
        }
    }

}

效果图如下:
这里写图片描述
(3)添加监听器,收集按钮上的信息。
收集按钮上的信息通过addActionListener()监听方法。
要实现下棋,就要获取点击位置的坐标,需要addMouseListener()监听方法。
添加监听方法就要有事件处理类,创建GobangListener类作为事件处理类。
继承MouseAdapter鼠标适配类,MouseAdapter类里继承了MouseListener, MouseWheelListener, MouseMotionListener。继承MouseAdapter是因为MouseAdapter只需要重写用到的方法,不需要重写所有的抽象方法。
同时,还要继承ActionListener。

//实例化事件处理类的对象,并把画笔、数组传递过去
GobangListener gl = new GobangListener(this,chesses);
//添加动作监听方法
start.addActionListener(gl);
back.addActionListener(gl);
giveup.addActionListener(gl);
box.addActionListener(gl);
public class GobangListener extends MouseAdapter implements ActionListener {
   
         //重写抽象方法
    }

(4)定义一个数组来存放棋子信息,当你在该位置下棋后,就不能再下棋了。
将窗体传递到GobangListener类,可以在窗体中获取画笔,也可以添加MouseListener监听方法。

public class Gobang extends JFrame {
   
    //定义一个二维数组,用来标记棋盘上的位置
    private int[][] chesses = new int[ChessTable.rows][ChessTable.columns];
}   
public class GobangListener extends MouseAdapter implements ActionListener {
   

    private Gobang ct;
    private Graphics2D g;
    private int[][] chesses;

    // 构造方法
    public GobangListener(Gobang G, int[][] chesses) {
        this.ct = G;
        this.chesses = chesses;
        // 获取窗体上的画笔对象
        g = (Graphics2D) this.ct.getGraphics();
        //画笔防锯齿
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 设置画笔抗锯齿
    }
}

(5)实现下棋、悔棋、和重绘。
用count来计数,判断轮到谁下棋。
通过chesses[i][j]来判断该位置是否能下棋。
悔棋要通过数组队列来实现,定义一个数组队列ArrayList。Point是一个类,可以直接用,可以获取x,y坐标值。
重绘则根据chesses数组中的信息再画一次。
调用判断输赢方法judge(),决出胜利后,移除MouseListener()不能再下棋。

//重写绘制窗体的方法
public void paint(Graphics g) {
        super.paint(g);
        ImageIcon image = new ImageIcon("C:\\Users\\庞志贤\\Desktop\\文档\\五子棋背景图\\1.jpg");
        g.drawImage(image.getImage(),50,70,400,400,null);
        drawChessTable(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);// 设置画笔抗锯齿
        //按照数组中的信息进行重绘
        for(int j = 0;j < ChessTable.rows;j++) {
   
             for(int i = 0;i < ChessTable.columns;i++) {
   
                 int x = ChessTable.x0 + i*ChessTable.size;
                 int y = ChessTable.y0 + j*ChessTable.size;
                 if(chesses[i][j] == 1) {
                     g.setColor(Color.black);
                     g.fillOval(x - ChessTable.chess_size / 2, y - ChessTable.chess_size / 2,
                             ChessTable.chess_size, ChessTable.chess_size);
                 }else if(chesses[i][j] == -1) {
                     g.setColor(Color.WHITE);
                     g.fillOval(x - ChessTable.chess_size / 2, y - ChessTable.chess_size / 2,
                             ChessTable.chess_size, ChessTable.chess_size);
                 } 
             }
        }

    }
public class GobangListener extends MouseAdapter implements ActionListener {
   

    private Gobang ct;
    private Graphics2D g;
    private int[][] chesses;
    private int count;
    private ArrayList<Point> list = new ArrayList<Point>();

    public void mouseReleased(MouseEvent e) {
        // 获取鼠标事件发生时光标的位置
        int x1 = e.getX();
        int y1 = e.getY();
        for (int j = 0; j < ChessTable.rows; j++) {
            for (int i = 0; i < ChessTable.columns; i++) {
                int x = ChessTable.x0 + i * ChessTable.size;
                int y = ChessTable.y0 + j * ChessTable.size;
                if (x1 > x - ChessTable.size / 3 && x1 < x + ChessTable.size / 3 && y1 > y - ChessTable.size / 3
                        && y1 < y + ChessTable.size / 3) {
                    // 如果选择的位置没有棋子
                    if (chesses[i][j] == 0) {
                        if (count == 0) {
                            // 如果是黑子就为1
                            chesses[i][j] = 1;
                            g.setColor(Color.black);
                            count++;
                            // 调用判断输赢的方法
                            if (judge(i, j)) {
                                System.out.println("执黑子胜利");
                                // 判断输赢后移除鼠标监听方法,不能再下棋子
                 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值