千家信息网

用Java实现五子棋游戏的方法步骤

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,本篇内容主要讲解"用Java实现五子棋游戏的方法步骤",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"用Java实现五子棋游戏的方法步骤"吧!1.图形化界面的
千家信息网最后更新 2026年11月04日用Java实现五子棋游戏的方法步骤

本篇内容主要讲解"用Java实现五子棋游戏的方法步骤",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"用Java实现五子棋游戏的方法步骤"吧!

1.图形化界面的创建

1.1创建JFrame窗体容器

1)JFrame窗体需要设置基本的大小、布局、默认的关闭方式,以及最重要的设置可见。

1.2在JFrame上添加组件,用来绘制棋盘棋子和游戏操作。

1)棋盘棋子的绘制:自定义一个类去继承JPanel,把绘制棋盘和棋子的方法重写进入paint()方法里,这样当窗体发生变化(放大、缩小、移动等操作时,棋盘棋子不会消失,棋局得以保存)。

2)悔棋、认输等操作通过JButton按钮添加鼠标监听来实现。

2.关键点的实现

(使用六个类实现背后逻辑,UI类,DrawChessBoard类,GameMouse类,QiZi类,Location类以及AI类)。

2.1在棋盘点击的位置绘制棋子

1)给棋盘添加鼠标监听,获取点击位置的坐标

UI类负责初始化1中的图形化界面,并给DrawChessBoard类添加GameMouse类的监听。这样在鼠标点击棋盘时通过重写GameMouse类的mouseClicked(),就可以获取鼠标在棋盘上点击的像素坐标。

2)坐标转化成二位数组中的坐标

保存棋盘上所有棋子位置用到QiZi类中的int[][] memory二维数组,这样把像素坐标转化为二维数组中的坐标,并附上棋子颜色对应的值,就可以保存棋盘上所有棋子的位置。

3)在棋盘上画出棋子

在DrawChessBoard类paint()方法中遍历QiZi类中的int[][] memory二维数组非零值,就可以在相应位置调用画笔方法画出黑白棋子。

2.2判断输赢

1)下完棋子后,将下棋位置保存到QiZi类的int[][] memory二维数组中后,就可以以该点为中心计算其四个方向上连续棋子的数目,达到五个则通过JOptionPane类生成弹窗确定赢家。

2.2悔棋功能和提示最后落子位置功能的实现

1)每次成功下一颗棋子,就可以创建一个保存了棋子坐标的Location对象,并将该对象添加到 QiZi类的ArrayList或者Stack容器当中,当鼠标点击悔棋Button后,清除QiZi类的int[][] memory二维数组相应位置的数值(将之改为0即可),然后棋盘重绘棋子,就可以完成悔棋的效果。

2)同时可以找到容器中最后落子的位置,并在棋盘相应的坐标出画出最后落子提示。

2.3开始、认输的实现

1)开始游戏,即重置游戏,将棋子类的相应属性清零即可,比如int[][] memory二维数组(即棋谱),owener=1(重置为白色),以及清楚棋盘上面的棋子。

2)认输就可以判断当前QiZi.owner的值,来判断输的一方并给出提示即可。

2.4AI的实现

1)默认AI为黑方的情况下,需要在白色方落子之后调用AI下黑色棋子,所以在需要在GameMouse中下白棋的if分支中调用AI方法

2)AI的厉害与否取决于其设计,在这里提供一个思路:设置一个棋型对照表,给不同棋型赋值(如1111,代表白子四连,权重较高),轮到AI时,可以根据该表计算棋盘上每一个空位在八个方向总的权重大小,在权重最大处落子即可。棋型对照表中不同棋的权重设置,可以通过python等分析大量棋局来获取,以此来训练AI,当权重设置越合理,AI就越强。

3.其他功能

下子的动画效果音效等可以通过开辟不同的线程来实现,而网络对战则可增加网络通信相关模块即可。

4.源码

package wuziqi925; import javax.swing.*;import java.awt.*; public class GameUI {    public static void main(String[] args) {        GameUI gameUI=new GameUI();        gameUI.showUI();    }     public void showUI(){        //创建棋子对象        QiZi qizi=new QiZi();        //获取窗体        JFrame jFrame=new JFrame();        jFrame.setSize(1000,795);        jFrame.setDefaultCloseOperation(3);        jFrame.setLocationRelativeTo(null);        jFrame.setLayout(null);        jFrame.setTitle("五子棋");        jFrame.setResizable(false);         //窗体添加棋盘面板        DrawChessBoard chessBoard=new DrawChessBoard(qizi);        jFrame.add(chessBoard);        chessBoard.setSize(760,760);        chessBoard.setBackground(Color.ORANGE);          //测试JFrame框架像素大小,Insets[top=32,left=3,bottom=3,right=3]        //System.out.println(jFrame.getInsets());         //窗体添加选项面板,用来画棋盘        JPanel bp=new JPanel();        bp.setSize(236,760);        bp.setBackground(Color.lightGray);        bp.setLocation(760,0);        bp.setLayout(null);        jFrame.add(bp);          //选项面板添加按钮        JButton start=new JButton("开始");        start.setBackground(Color.white);        start.setFont(new Font("华文行楷",Font.BOLD,20));        start.setBounds(40,350,150,50);         JButton quit=new JButton("认输");        quit.setBackground(Color.white);        quit.setFont(new Font("华文行楷",Font.BOLD,20));        quit.setBounds(40,440,150,50);         JButton undo=new JButton("悔棋");        undo.setBackground(Color.white);        undo.setFont(new Font("华文行楷",Font.BOLD,20));        undo.setBounds(40,530,150,50);         bp.add(start);        bp.add(quit);        bp.add(undo);         //选择模式选项        ButtonGroup bg=new ButtonGroup();        JRadioButton rrdz=new JRadioButton("玩家对战");        JRadioButton rjdz=new JRadioButton("人机对战");        rrdz.setSize(120,30);        rrdz.setLocation(55,60);        rrdz.setFont(new Font("华文行楷",Font.BOLD,20));        rrdz.setVisible(true);        rjdz.setSize(120,30);        rjdz.setLocation(55,90);        rjdz.setFont(new Font("华文行楷",Font.BOLD,20));        rjdz.setVisible(true);        bg.add(rjdz);        bg.add(rrdz);        bp.add(rjdz);        bp.add(rrdz);        bp.setVisible(true);         //设置窗体可见        jFrame.setVisible(true);          AI ai=new AI(qizi,chessBoard);        //获取棋盘的鼠标监听和画笔并将该画笔添加给鼠标        Graphics g1=chessBoard.getGraphics();        GameMouse gameMouse=new GameMouse(qizi,chessBoard,ai);         chessBoard.addMouseListener(gameMouse);        start.addActionListener(gameMouse);        quit.addActionListener(gameMouse);        undo.addActionListener(gameMouse);        rrdz.addActionListener(gameMouse);        rjdz.addActionListener(gameMouse);    }}
package wuziqi925; import javax.swing.*;import java.awt.*;  public class DrawChessBoard extends JPanel {    QiZi qiZi;    private static int LINE_NUM = 15;    private static int MARGIN_WIDTH = 30;    public static int CELL_SIZE = 50;     public DrawChessBoard(QiZi qiZi) {        this.qiZi = qiZi;    }     @Override    public void paint(Graphics g) {        super.paint(g);        //画棋盘        for (int i = 0; i < LINE_NUM; i++) {            g.drawLine(MARGIN_WIDTH, MARGIN_WIDTH + i * CELL_SIZE, MARGIN_WIDTH + (LINE_NUM - 1) * CELL_SIZE, MARGIN_WIDTH + i * CELL_SIZE);            g.drawLine(MARGIN_WIDTH + i * CELL_SIZE, MARGIN_WIDTH, MARGIN_WIDTH + i * CELL_SIZE, MARGIN_WIDTH + (LINE_NUM - 1) * CELL_SIZE);        }        //画棋盘上的点        g.fillOval(CELL_SIZE*3+22,CELL_SIZE*3+22,16,16);        g.fillOval(CELL_SIZE*11+22,CELL_SIZE*3+22,16,16);        g.fillOval(CELL_SIZE*3+22,CELL_SIZE*11+22,16,16);        g.fillOval(CELL_SIZE*11+22,CELL_SIZE*11+22,16,16);        //画棋子        int[][] a = qiZi.memory;        for (int i = 0; i < a.length; i++) {            for (int j = 0; j < a[i].length; j++) {                if (a[i][j] == 1)    {                    g.setColor(Color.white);                    g.fillOval(CELL_SIZE * i + 7, CELL_SIZE * j + 7, 46, 46);                } else if (a[i][j] == 2) {                    g.setColor(Color.black);                    g.fillOval(CELL_SIZE * i + 7, CELL_SIZE * j + 7, 46, 46);                }            }        }        //画出最后一步棋子的位置上的十字架        if (qiZi.arr.size() > 0) {            Graphics2D g1=(Graphics2D)g;            g1.setColor(Color.red);            g1.setStroke(new BasicStroke(3.0f));             Location l = qiZi.arr.get(qiZi.arr.size() - 1);            g1.drawLine(CELL_SIZE * l.x + MARGIN_WIDTH - 8, CELL_SIZE * l.y + MARGIN_WIDTH, CELL_SIZE * l.x + MARGIN_WIDTH + 8, CELL_SIZE * l.y + MARGIN_WIDTH);            g1.drawLine(CELL_SIZE * l.x + MARGIN_WIDTH, CELL_SIZE * l.y + MARGIN_WIDTH - 8, CELL_SIZE * l.x + MARGIN_WIDTH, CELL_SIZE * l.y + MARGIN_WIDTH + 8);        }    }}
package wuziqi925; 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; public class GameMouse implements MouseListener, ActionListener {    QiZi qizi;    DrawChessBoard drawChessBoard;    AI ai;     public GameMouse() {    }     public GameMouse( QiZi qiZi, DrawChessBoard drawChessBoard,AI ai) {        this.qizi = qiZi;        this.drawChessBoard=drawChessBoard;        this.ai=ai;    }     @Override    public void mouseClicked(MouseEvent e) {        int cellSize= DrawChessBoard.CELL_SIZE;        int x=e.getX();        int xx=0;        int y=e.getY();        int yy=0;         //在点击位置画棋子,并将下子位置转换成棋子在二维数组中的坐标        if (qizi.owner==1) {            if ((x - 30) % cellSize > 25 & (y - 30) % cellSize > 25) {                xx=(x - 30) / cellSize + 1;                yy=(y - 30) / cellSize + 1;            } else if ((x - 30) % cellSize > 25 & (y - 30) % cellSize < 25) {                xx=(x - 30) / cellSize + 1;                yy=(y - 30) / cellSize;            } else if ((x - 30) % cellSize < 25 & (y - 30) % cellSize > 25) {                xx=(x - 30) / cellSize;                yy=(y - 30) / cellSize + 1;            } else if ((x - 30) % cellSize < 25 & (y - 30) % cellSize < 25) {                xx=(x - 30) / cellSize;                yy=(y - 30) / cellSize;            }            if(qizi.memory[xx][yy]==0) {//判断无子                qizi.x=xx;                qizi.y=yy;                qizi.memory[qizi.x][qizi.y] = qizi.owner;//下棋子并将棋子放入容器                Location location=new Location(qizi);//记录刚下的棋子位置顺序                qizi.arr.add(location);                drawChessBoard.repaint();//绘制刚下的棋子                qizi.judgeWinner();//判断输赢                 qizi.owner=2;//交换棋权            }            if (ai.state){                ai.initiateAI();            }         }else {            qizi.owner=2;            if ((x - 30) % cellSize > 25 & (y - 30) % cellSize > 25) {                xx=(x - 30) / cellSize + 1;                yy=(y - 30) / cellSize + 1;            } else if ((x - 30) % cellSize > 25 & (y - 30) % cellSize < 25) {                xx=(x - 30) / cellSize + 1;                yy=(y - 30) / cellSize;            } else if ((x - 30) % cellSize < 25 & (y - 30) % cellSize > 25) {                xx=(x - 30) / cellSize;                yy=(y - 30) / cellSize + 1;            } else if ((x - 30) % cellSize < 25 & (y - 30) % cellSize < 25) {                xx=(x - 30) / cellSize;                yy=(y - 30) / cellSize;            }            if(qizi.memory[xx][yy]==0) {                qizi.x=xx;                qizi.y=yy;                qizi.memory[qizi.x][qizi.y] = qizi.owner;//下棋子并将棋子放入容器                Location location=new Location(qizi);//记录刚下的棋子位置顺序                qizi.arr.add(location);                drawChessBoard.repaint();//绘制刚下的棋子                qizi.judgeWinner();//判断输赢                 qizi.owner=1;//交换棋权            }        }    }    @Override    public void actionPerformed(ActionEvent e) {        int cellSize= DrawChessBoard.CELL_SIZE;        String s=e.getActionCommand();        JOptionPane tc=new JOptionPane();         //悔棋功能的实现        if (s.equals("悔棋")){            if (qizi.arr.size()>0) {                Location l = qizi.arr.get(qizi.arr.size() - 1);                qizi.memory[l.x][l.y] = 0;                qizi.arr.remove(qizi.arr.size() - 1);                 if (qizi.owner == 1) {                    qizi.owner = 2;                } else if (qizi.owner == 2) {                    qizi.owner = 1;                }            }else {                tc.showMessageDialog(null,"无棋可毁,请下棋!");            }            //刷新棋盘            drawChessBoard.repaint();        }         if (s.equals("开始")){            qizi.owner=1;            qizi.memory=new int[15][15];            qizi.arr.clear();            qizi.win=false;            drawChessBoard.repaint();        }         if(s.equals("认输")){            int whiteCount=0;            int blackCount=0;            for (int i = 0; i < qizi.memory.length; i++) {                for (int j = 0; j < qizi.memory[i].length; j++) {                    if (qizi.memory[i][j]==1){                        whiteCount++;                    }else if (qizi.memory[i][j]==2){                        blackCount++;                    }                }            }            if (whiteCount==blackCount){                tc.showMessageDialog(null,qizi.owner==1 ?"黑方投降,白方胜!":"白方投降,黑方胜!");            }else if(whiteCount>blackCount){                tc.showMessageDialog(null,"黑方投降,白方胜!");            }else {                tc.showMessageDialog(null,"白方投降,黑方胜!");            }        }        if (s.equals("人机对战")){            ai.state=true;         }        if (s.equals("玩家对战")){            ai.state=false;         }    }     @Override    public void mousePressed(MouseEvent e) {     }     @Override    public void mouseReleased(MouseEvent e) {     }     @Override    public void mouseEntered(MouseEvent e) {     }     @Override    public void mouseExited(MouseEvent e) {     }  }
package wuziqi925; import javax.swing.*;import java.util.ArrayList; public class QiZi {    int x;    int y;    int owner=1;//1 代表白色,2代表黑色    int[][] memory;    ArrayList arr;    boolean win=false;     public QiZi() {        memory=new int[15][15];        arr=new ArrayList<>(50);    }     public void judgeWinner() {        JOptionPane tc=new JOptionPane();        int count1=0;        int count2=0;        int count3=0;        int count4=0;         //竖直方向检测        for (int i = y-1; i >-1 ; i--) {            if (memory[x][i]==owner){                count1++;            }else {                break;            }        }        for (int i = y+1; i <15; i++) {            if (memory[x][i]==owner){                count1++;            }else {                break;            }        }        if (count1 > 3){            tc.showMessageDialog(null,owner==1?"白方胜":"黑方胜");            win=true;            return;        }         //水平方向检测        for (int i = x-1; i >-1 ; i--) {            if (memory[i][y]==owner){                count2++;            }else {                break;            }        }        for (int i = x+1; i <15; i++) {            if (memory[i][y]==owner){                count2++;            }else {                break;            }        }        if (count2 > 3){            tc.showMessageDialog(null,owner==1?"白方胜":"黑方胜");            win=true;            return;        }         //在\方向上检测        int yy=y;        for (int i = x+1; i <15; i++) {            if(yy==14){                break;            }            yy++;            if (memory[i][yy]==owner){                count3++;            }else {                break;            }        }        yy=y;        for (int i = x-1; i >-1; i--) {            if (yy==0){                break;            }            yy--;            if (memory[i][yy]==owner){                count3++;            }else {                break;            }         }        if (count3 > 3){            tc.showMessageDialog(null,owner==1?"白方胜":"黑方胜");            win=true;            return;        }         //在/方向上检测        yy=y;        for (int i = x+1; i <15; i++) {            if(yy==0){                break;            }            yy--;            if (memory[i][yy]==owner){                count4++;            }else {                break;            }        }        yy=y;        for (int i = x-1; i >-1; i--) {            if(yy==14){                break;            }            yy++;            if (memory[i][yy]==owner){                count4++;            }else {                break;            }        }        if (count4 > 3){            tc.showMessageDialog(null,owner==1?"白方胜":"黑方胜");            win=true;            return;        }    }}
package wuziqi925; public class Location {    QiZi qiZi;    int x;    int y;     public Location(QiZi qiZi) {        //记录棋谱        x=qiZi.x;        y=qiZi.y;    }     public Location(int x, int y) {        this.x = x;        this.y = y;    }}
package wuziqi925; import java.util.*; public class AI {    boolean state=false;//true为on false为off    QiZi qiZi;    //存储棋型权值    private HashMap playValueTable=new HashMap<>();    //存储每个可下点的权重大小    private HashMap locationsAndValues=new HashMap<>();    DrawChessBoard drawChessBoard;    int AIDO=0;     public AI(QiZi qiZi,DrawChessBoard drawChessBoard){        this.drawChessBoard=drawChessBoard;        this.qiZi=qiZi;        //1代表该方向为白方棋子(玩家),2代表该方向为黑方棋子(AI)        playValueTable.put("22221",100);        playValueTable.put("2222",100);        playValueTable.put("11112",99);        playValueTable.put("1111",0);         playValueTable.put("2221",40);        playValueTable.put("222",45);        playValueTable.put("1112",35);        playValueTable.put("111",46);         playValueTable.put("22",25);        playValueTable.put("221",20);        playValueTable.put("11",15);        playValueTable.put("112",10);         playValueTable.put("21",5);        playValueTable.put("2",10);        playValueTable.put("1",8);        playValueTable.put("12",2);    }     public void initiateAI(){        if (qiZi.win){            return;        }        int chessValue=0;        //遍历棋盘找到空点        for (int i = 0; i  locationsAndValues进行排序找到最大值        Set> set=locationsAndValues.entrySet();        List> list=new ArrayList<>(set);        list.sort(new Comparator>() {            @Override            public int compare(Map.Entry o1, Map.Entry o2) {                return o2.getValue()-o1.getValue();            }        });        //排序完毕取最大//获取最大权重值对应的空点坐标        Map.Entry maxSet=list.get(0);        Location toDo=maxSet.getKey();         qiZi.x= toDo.x;        qiZi.y= toDo.y;        qiZi.memory[qiZi.x][qiZi.y]=qiZi.owner;        Location location=new Location(qiZi);//记录刚下的棋子位置顺序        qiZi.arr.add(location);        drawChessBoard.repaint();//绘制刚下的棋子        qiZi.judgeWinner();//判断输赢        qiZi.owner=1;//交换棋权        System.out.println(++AIDO);        locationsAndValues.clear();    }     private int countValue(int i,int j) {        int totalValue=0;        StringBuilder s1=new StringBuilder();        StringBuilder s2=new StringBuilder();        StringBuilder s3=new StringBuilder();        StringBuilder s4=new StringBuilder();        StringBuilder s5=new StringBuilder();        StringBuilder s6=new StringBuilder();        StringBuilder s7=new StringBuilder();        StringBuilder s8=new StringBuilder();        //八个方向去去判定        //North        for (int k = j-1; k >-1 ; k--) {            if (qiZi.memory[i][k]==1){                s1.append(1);            }else if (qiZi.memory[i][k]==2) {                s1.append(2);            }else {                break;            }        }        int count1=playValueTable.get(s1.toString())==null?0:playValueTable.get(s1.toString());        totalValue+=count1;         //South        for (int k = j+1; k <15; k++) {            if (qiZi.memory[i][k]==1){                s2.append(1);            }else if (qiZi.memory[i][k]==2) {                s2.append(2);            }else {                break;            }        }        int count2=playValueTable.get(s2.toString())==null?0:playValueTable.get(s2.toString());        totalValue+=count2;         //West        for (int k = i-1; k >-1 ; k--) {            if (qiZi.memory[k][j]==1){                s3.append(1);            }else if (qiZi.memory[k][j]==2) {                s3.append(2);            }else {                break;            }        }        int count3=playValueTable.get(s3.toString())==null?0:playValueTable.get(s3.toString());        totalValue+=count3;         //East        for (int k = i+1; k <15; k++) {            if (qiZi.memory[k][j]==1){                s4.append(1);            }else if (qiZi.memory[k][j]==2) {                s4.append(2);            }else {                break;            }        }        int count4=playValueTable.get(s4.toString())==null?0:playValueTable.get(s4.toString());        totalValue+=count4;         //SE        int yy=j;        for (int k = i+1; k < 15; k++) {            if(yy==14){                break;            }            yy++;            if (qiZi.memory[k][yy]==1){                s5.append(1);            }else if (qiZi.memory[k][yy]==2) {                s5.append(2);            }else {                break;            }        }        int count5=playValueTable.get(s5.toString())==null?0:playValueTable.get(s5.toString());        totalValue+=count5;         //NW        yy=j;        for (int k = i-1; k >-1; k--) {            if(yy==0){                break;            }            yy--;            if (qiZi.memory[k][yy]==1){                s6.append(1);            }else if (qiZi.memory[k][yy]==2) {                s6.append(2);            }else {                break;            }        }        int count6=playValueTable.get(s6.toString())==null?0:playValueTable.get(s6.toString());        totalValue+=count6;         //NE        yy=j;        for (int k = i+1; k <15; k++) {            if(yy==0){                break;            }            yy--;            if (qiZi.memory[k][yy]==1){                s7.append(1);            }else if (qiZi.memory[k][yy]==2) {                s7.append(2);            }else {                break;            }        }        int count7=playValueTable.get(s7.toString())==null?0:playValueTable.get(s7.toString());        totalValue+=count6;        //SW        yy=j;        for (int k = i-1; k >-1; k--) {            if(yy==14){                break;            }            yy++;            if (qiZi.memory[k][yy]==1){                s8.append(1);            }else if (qiZi.memory[k][yy]==2) {                s8.append(2);            }else {                break;            }        }        int count8=playValueTable.get(s8.toString())==null?0:playValueTable.get(s8.toString());        totalValue+=count8;        return totalValue;    }}

到此,相信大家对"用Java实现五子棋游戏的方法步骤"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0