Java 实现五子棋简单游戏

版权声明:本文为博主原创文章,欢迎分享转载。 https://blog.csdn.net/qq_29897369/article/details/82534596

简单五子棋实现

该游戏参考之前一些前辈经验加上自己理解开发。具体游戏Demo上传到我的github 对熟悉java 连手是个不错的选择!

Demo地址:https://github.com/dairuijie/GameGobang

基本思路:、

  • 编写需要公共静态变量的接口
> package com.drj.game;
import java.util.HashMap;
/**
 * 
 * @ClassName:  Goconfig   
 * @Description:TODO(公用的变量)   
 * @author: drj 
 * @date:   2018年9月8日 下午7:49:11   
 *     
 * @Copyright: 2018 
 *
 */
public interface Goconfig {
    public static final String TITLE = "简单五子棋";
    public static final String PC_TYPE="人机对战";
    public static final String PP_TYPE = "人人对站";
    public static final String START_GAME = "开始游戏";
    public static final String RETURN_GO = "悔棋";
    public static final String LOSER = "认输";
    public static final String WHITE_WIN = "白棋胜利!";
    public static final String BLACK_WIN = "黑棋胜利!";
    public static final String WARING_INFO = "请点击在棋盘内";
    public static final String DEUCE = "恭喜你们打成平手";
    public static final int ROW=6;  //棋谱行数
    public static final int COLUMN = 6; //棋谱列数
    public static final int SQUARE_SIZE=35;  //棋谱每个方格的大小
    public static final int RADIUS=12;  //棋子的半径长度
    public static Piece go[][]=new Piece[ROW][ROW];  //存放棋谱上棋子的颜色
    public static int weightarr[][]=new int[ROW][ROW];  //存放棋子的权重,也就是权重越大 优先级越高
    public static HashMap<String,Integer> map = new HashMap<String,Integer>();   //存放 白旗或是黑棋 存在的路线组合举个例子: 0 代表空位 1 白色 棋子 2 黑色棋子  010 表示 只有一个白色棋子两边都是空位 0110  代表两个棋子相连两头是空位的 
}
  • 搭建swing 窗体

>

package com.drj.game;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * 
 * @ClassName: GameMain
 * @Description:TODO(启动主类、初始化窗体)
 * @author: drj
 * @date: 2018年9月8日 下午7:48:17
 * qq:3343217807
 * @Copyright: 2018
 *
 */
public class GameMain extends JPanel implements Goconfig {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    /**
     * 存放棋子可能的组合 活一连 两头都是空位 就是活几连 有几个一起相连的就是几 活二连 眠一连 一头是对方棋子 一头是空位
     * 
     */
    static {
        map.put("01", 20);
        map.put("02", 20);
        map.put("010", 42);
        map.put("020", 42);
        map.put("011", 300);
        map.put("022", 300);
        map.put("0110", 400);
        map.put("0220", 400);
        map.put("0111", 400);
        map.put("0222", 400);
        map.put("01111", 3000);
        map.put("02222", 3000);
        map.put("01110", 3000);
        map.put("02220", 3000);
        map.put("011110", 10000);
        map.put("022220", 10000);
        map.put("012", 23);
        map.put("021", 23);
        map.put("0112", 200);
        map.put("0221", 200);
        map.put("01112", 500);
        map.put("02221", 500);
        map.put("022221", 3000);
        map.put("011112", 3000);
    }

    JButton buttonStart = new JButton(START_GAME);
    JButton buttonregret = new JButton(RETURN_GO);
    JButton buttonlose = new JButton(LOSER);

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        GameMain main = new GameMain();
        main.Init();
        main.PieceInit();
        main.setButton(false);
    }

    /**
     * 初始化窗体 1窗体大小 2窗体中布局 3按钮、下拉框 4添加事件监听
     */
    public void Init() {
        JFrame jf = new JFrame();
        jf.setTitle(TITLE);
        jf.setSize(650, 580);
        jf.setLocationRelativeTo(null);
        jf.setResizable(true);
        jf.setDefaultCloseOperation(3);
        jf.setLayout(new BorderLayout());
        jf.add(this);
        JPanel eastp = new JPanel();
        eastp.setPreferredSize(new Dimension(100, 0));
        String[] itemArray = { PP_TYPE, PC_TYPE };
        JComboBox<String> cbItem = new JComboBox<String>(itemArray);
        buttonStart.setPreferredSize(new Dimension(90, 40));
        buttonregret.setPreferredSize(new Dimension(90, 40));
        buttonlose.setPreferredSize(new Dimension(90, 40));
        cbItem.setPreferredSize(new Dimension(90, 40));
        JPanel eastp_tmp = new JPanel();
        eastp_tmp.setPreferredSize(new Dimension(90, 30));
        eastp.add(eastp_tmp);
        eastp.add(buttonStart);
        eastp.add(buttonregret);
        eastp.add(buttonlose);
        eastp.add(cbItem);
        jf.add(eastp, BorderLayout.EAST);
        jf.setVisible(true);
        GameListener cl = new GameListener(this, cbItem);
        buttonStart.addActionListener(cl);
        buttonregret.addActionListener(cl);
        buttonlose.addActionListener(cl);
        cbItem.addActionListener(cl);
    }

    /**
     * 存放棋子的数组 开始都是空位
     */
    private void PieceInit() {
        for (int i = 0; i < ROW; i++) {
            for (int j = 0; j < ROW; j++) {
                go[i][j] = new Piece(0);
            }
        }
    }

    /**
     * 画棋谱格子
     */
    public void paint(Graphics g) {
        super.paint(g);
        for (int i = 0; i < ROW; i++) {
            g.drawLine(30, 30 + i * SQUARE_SIZE, 30 + SQUARE_SIZE * (ROW - 1), 30 + i * SQUARE_SIZE);
            g.drawLine(30 + i * SQUARE_SIZE, 30, 30 + i * SQUARE_SIZE, 30 + SQUARE_SIZE * (ROW - 1));
        }
        for (int i = 0; i < ROW; i++) {
            for (int j = 0; j < ROW; j++) {
                if (go[i][j].color != 0) {
                    int x = 30 + i * SQUARE_SIZE;
                    int y = 30 + j * SQUARE_SIZE;
                    if (go[i][j].color == 1)
                        g.setColor(Color.BLACK);
                    else
                        g.setColor(Color.WHITE);
                    g.fillOval(x - 12, y - 12, 24, 24);
                }
            }
        }
    }

    public void setButton(boolean flag) {
        buttonregret.setEnabled(flag);
        buttonlose.setEnabled(flag);
    }
}
  • 棋子对象 Chess

 package com.drj.game;

/**
 * 
 * @ClassName:  Chess   
 * @Description:TODO(棋子类 存放棋子 xy 坐标)   
 * @author: drj 
 * @date:   2018年9月8日 下午7:45:52   
 *     
 * @Copyright: 2018 
 *  */
public class Chess {
    public int x,y;
    public Chess(int x,int y) {
        this.x=x;
        this.y=y;
    }
}
  • 监听窗体事件类GameListene
package com.drj.game;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;

/**
 - 
 - @ClassName: GameListener
 - @Description:TODO(监听窗体事件)
 - @author: drj
 - @date: 2018年9月8日 下午7:47:16
 - 
 - @Copyright: 2018
 -  */
public class GameListener extends MouseAdapter implements ActionListener, Goconfig {
    private GameMain main;// 窗体对象
    private Graphics2D g;// 画图对象
    private String gameModel = PP_TYPE;// 游戏模式
    private boolean flag = true;// 默认 黑棋
    private JComboBox<String> cbItem;// 存放游戏选择 人人 还是人机 数组对象
    private ArrayList<Chess> list = new ArrayList<Chess>();

    public GameListener(GameMain main, JComboBox<String> cbItem) {
        this.main = main;
        this.cbItem = cbItem;
    }

    /**
     * 鼠标点击事件
     */
    public void mouseClicked(MouseEvent e) {
        if (g == null) {// 获取 画棋子的对象
            g = (Graphics2D) main.getGraphics();
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        }
        int x = e.getX() - 30;// 获取鼠标点击的x 坐标
        int y = e.getY() - 30;// 获取鼠标点击的y 坐标
        int length = (ROW - 1) * SQUARE_SIZE + 30;
        if (x < 0 || y < 0 || x > length || y > length) {
            System.out.println(555);
            JOptionPane.showMessageDialog(main, WARING_INFO);

        } else {
            int cx = x - (x / SQUARE_SIZE) * SQUARE_SIZE;
            int cy = y - (y / SQUARE_SIZE) * SQUARE_SIZE;
            // 当 点击 x在方格中间 位置 按离他最近的点 放置
            if (cx > (SQUARE_SIZE / 2)) {
                x = (x / SQUARE_SIZE + 1) * SQUARE_SIZE;
            } else {
                x = (x / SQUARE_SIZE) * SQUARE_SIZE;
            }
            // 当 点击在 y 在方格中间 位置 按离他最近的点 放置
            if (cy > (SQUARE_SIZE / 2)) {
                y = (y / SQUARE_SIZE + 1) * SQUARE_SIZE;
            } else {
                y = (y / SQUARE_SIZE) * SQUARE_SIZE;
            }
            int zx = x / SQUARE_SIZE;
            int zy = y / SQUARE_SIZE;
            System.out.println(zx + "===" + zy);
            Chess tmpchess = new Chess(zx, zy);
            if (go[zx][zy].color == 0) {// 是空位就是画棋子
                draw(tmpchess);
                if (list.size() == Math.pow(ROW, 2)) {
                    gameOverClear(main, cbItem);
                    JOptionPane.showMessageDialog(main, DEUCE);
                    return;
                }
                if (PC_TYPE.equals(gameModel)) {// 人机模式
                    Piece.weightReset();
                    tmpchess = Piece.weight();
                    draw(tmpchess); // 画出该子,并判断输赢
                }
            }
        }
    }

    /**
     * 绘画黑白棋子
     * 
     * @param tmpchess
     */
    public void draw(Chess tmpchess) {
        int zx = tmpchess.x;
        int zy = tmpchess.y;
        int x = zx * SQUARE_SIZE + 30;
        int y = zy * SQUARE_SIZE + 30;
        if (flag) {
            g.setColor(Color.BLACK);
        } else {
            g.setColor(Color.WHITE);
        }
        g.fillOval(x - RADIUS, y - RADIUS, RADIUS * 2, RADIUS * 2);
        Color col = g.getColor();
        if (col == Color.BLACK) {
            go[zx][zy].color = 1;
        } else if (col == Color.WHITE) {
            go[zx][zy].color = 2;
        }
        if (go[zx][zy].judge(zx, zy) != 0) {
            if (flag) {
                JOptionPane.showMessageDialog(main, BLACK_WIN);
            } else {
                JOptionPane.showMessageDialog(main, WHITE_WIN);
            }
            gameOverClear(main, cbItem);
            return;
        }
        flag = !flag;
        list.add(tmpchess);
    }

    /**
     * 针对窗体上事件的拦截
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals(START_GAME)) {
            for (int i = 0; i < ROW; i++) {
                for (int j = 0; j < COLUMN; j++) {
                    go[i][j].color = 0;
                }
            }
            Piece.weightReset(); // 开始前重置棋盘的权重
            flag = true; // 黑色 定义为 true
            cbItem.setEnabled(false);// 下拉框 置为不可选
            list.clear(); // 清空棋子数组
            main.repaint();// 窗体重绘
            // main.removeMouseListener(this); //移除监听对象
            main.addMouseListener(this);// 添加监听对象
            main.setButton(true); // 设置悔棋、认输可点
        } else if (e.getActionCommand().equals(RETURN_GO)) {
            if (list.size() >= 1) {
                Chess chess = list.remove(list.size() - 1);// 删除最后加入的棋子对象
                go[chess.x][chess.y].color = 0;// 将最后棋子 位置 颜色置为 0
                flag = !flag;// 悔棋后 需要是悔棋重新下
                main.repaint();// 棋谱重新画
            }
        } else if (e.getActionCommand().equals(LOSER)) {
            if (flag) {
                JOptionPane.showMessageDialog(main, WHITE_WIN);
            } else {
                JOptionPane.showMessageDialog(main, BLACK_WIN);
            }
            gameOverClear(main, cbItem);
        } else if (e.getSource() instanceof JComboBox) {
            @SuppressWarnings("unchecked")
            JComboBox<String> cbItem = (JComboBox<String>) e.getSource();// 获取事件源对象
            gameModel = cbItem.getSelectedItem().toString(); // 获取选择的对战模式
            System.out.println("select is" + gameModel);
        }
    }

    /**
     * 游戏结束 处理公共代码
     * 
     * @param main
     * @param cbItem
     */
    public void gameOverClear(GameMain main, JComboBox<String> cbItem) {
        main.removeMouseListener(this); // 移除棋盘面板上的鼠标动作监听方法和事件处理类对象
        cbItem.setEnabled(true); // 游戏模式可以操作
        main.setButton(false); // 悔棋 禁止操作
    } }
  • 棋子的颜色、判断是否成功、计算ai权值
 - package com.drj.game;
/**
 * 
 * @ClassName:  Piece   
 * @Description:TODO(描述棋子的颜色、判断是否成功、计算ai权值 )   
 * @author: drj 
 * @date:   2018年9月8日 下午7:45:01   
 *     
 * @Copyright: 2018 
 *
 */
class Piece implements Goconfig {
    public Piece(int color) {
        this.color = 0;
    }

    public int color = 0;// 0 代表空位
    // 权值重置

    public static void weightReset() {
        for (int i = 0; i < weightarr.length; i++) {
            for (int j = 0; j < weightarr[i].length; j++) {
                weightarr[i][j] = 0;
            }
        }
    }

    /**
     * 计算权重
     * 
     * @return
     */
    public static Chess weight() {
        int maxWeight = 0;
        int x = 0, y = 0;
        for (int i = 0; i < go.length; i++) {
            for (int j = 0; j < go[i].length; j++) {
                if (go[i][j].color == 0) {// 只有空位的 才去计算权值
                    String key1 = "0";
                    String key2 = "0";
                    int upx = i, upy = j, downx = i, downy = j;
                    // 左斜方向判断 西北方
                    int first1 = 0, first2 = 0;
                    while ((upx - 1) >= 0 && (upy - 1) >= 0) {
                        int first = go[i - 1][j - 1].color;
                        first1 = first;
                        if (first == 0)
                            break;
                        else {
                            --upx;
                            --upy;
                            if (go[upx][upy].color == first) {
                                key1 += go[upx][upy].color;
                            } else {
                                key1 += go[upx][upy].color;
                                break;
                            }
                        }
                    }
                    // 东南方
                    while ((downx + 1) <= (ROW - 1) && (downy + 1) <= (ROW - 1)) {
                        int first = go[i + 1][j + 1].color;
                        first2 = first;
                        if (first == 0)
                            break;
                        else {
                            ++downx;
                            ++downy;
                            if (go[downx][downy].color == first) {
                                key2 += go[downx][downy].color;
                            } else {
                                key2 += go[downx][downy].color;
                                break;
                            }
                        }
                    }
                    System.out.println("one" + key1 + "===" + key2);

                    Integer res1 = map.get(key1);
                    Integer res2 = map.get(key2);
                    int value1 = 0, value2 = 0;
                    if (res1 != null)
                        value1 = res1.intValue();
                    if (res2 != null)
                        value2 = res2.intValue();
                    int value = value1 + value2;
                    if ((first1 == first2) && first1 != 0) {
                        value *= 2;
                    }
                    key1 = "0";
                    key2 = "0";
                    upx = i;
                    upy = j;
                    downx = i;
                    downy = j;
                    // 绔栫洿鏂瑰悜鍒ゆ柇
                    first1 = 0;
                    first2 = 0;
                    while ((upy - 1) >= 0) {
                        int first = go[i][j - 1].color;
                        first1 = first;
                        if (first == 0)
                            break;
                        else {
                            --upy;
                            if (go[upx][upy].color == first) {
                                key1 += go[upx][upy].color;
                            } else {
                                key1 += go[upx][upy].color;
                                break;
                            }
                        }
                    }
                    while ((downy + 1) <= (ROW - 1)) {
                        int first = go[i][j + 1].color;
                        first2 = first;
                        if (first == 0)
                            break;
                        else {
                            ++downy;
                            if (go[downx][downy].color == first) {
                                key2 += go[downx][downy].color;
                            } else {
                                key2 += go[downx][downy].color;
                                break;
                            }
                        }
                    }
                    System.out.println("tow" + key1 + "===" + key2);
                    res1 = map.get(key1);
                    res2 = map.get(key2);
                    value1 = 0;
                    value2 = 0;
                    if (res1 != null)
                        value1 = res1.intValue();
                    if (res2 != null)
                        value2 = res2.intValue();
                    value += value1 + value2;
                    if ((first1 == first2) && first1 != 0) {
                        value *= 2;
                    }
                    key1 = "0";
                    key2 = "0";
                    upx = i;
                    upy = j;
                    downx = i;
                    downy = j;
                    first1 = 0;
                    first2 = 0;
                    while ((upx - 1) >= 0) {
                        int first = go[i - 1][j].color;
                        first1 = first;
                        if (first == 0)
                            break;
                        else {
                            --upx;
                            if (go[upx][upy].color == first) {
                                key1 += go[upx][upy].color;
                            } else {
                                key1 += go[upx][upy].color;
                                break;
                            }
                        }
                    }
                    while ((downx + 1) <= (ROW - 1)) {
                        int first = go[i + 1][j].color;
                        first2 = first;
                        if (first == 0)
                            break;
                        else {
                            ++downx;
                            if (go[downx][downy].color == first) {
                                key2 += go[downx][downy].color;
                            } else {
                                key2 += go[downx][downy].color;
                                break;
                            }
                        }
                    }
                    System.out.println("three" + key1 + "===" + key2);
                    res1 = map.get(key1);
                    res2 = map.get(key2);
                    value1 = 0;
                    value2 = 0;
                    if (res1 != null)
                        value1 = res1.intValue();
                    if (res2 != null)
                        value2 = res2.intValue();
                    value += value1 + value2;
                    if ((first1 == first2) && first1 != 0)
                        value *= 2;

                    key1 = "0";
                    key2 = "0";
                    upx = i;
                    upy = j;
                    downx = i;
                    downy = j;
                    first1 = 0;
                    first2 = 0;
                    while ((upx + 1) <= (ROW - 1) && (upy - 1) >= 0) {
                        int first = go[i + 1][j - 1].color;
                        first1 = first;
                        if (first == 0)
                            break;
                        else {
                            ++upx;
                            --upy;
                            if (go[upx][upy].color == first) {
                                key1 += go[upx][upy].color;
                            } else {
                                key1 += go[upx][upy].color;
                                break;
                            }
                        }
                    }
                    while ((downx - 1) >= 0 && (downy + 1) <= (ROW - 1)) {
                        int first = go[i - 1][j + 1].color;
                        first2 = first;
                        if (first == 0)
                            break;
                        else {
                            --downx;
                            ++downy;
                            if (go[downx][downy].color == first) {
                                key2 += go[downx][downy].color;
                            } else {
                                key2 += go[downx][downy].color;
                                break;
                            }
                        }
                    }
                    System.out.println("four" + key1 + "===" + key2);
                    res1 = map.get(key1);
                    res2 = map.get(key2);
                    value1 = 0;
                    value2 = 0;
                    if (res1 != null)
                        value1 = res1.intValue();
                    if (res2 != null)
                        value2 = res2.intValue();
                    value += value1 + value2;
                    if ((first1 == first2) && first1 != 0)
                        value *= 2; 
                    weightarr[i][j] += value;
                    if (weightarr[i][j] >= maxWeight) {
                        maxWeight = weightarr[i][j];
                        x = i;
                        y = j;
                    }

                }
            }
        }
        System.out.println(maxWeight);
        return new Chess(x, y);
    }

    /**
     * 判断是否五子连接成功
     * 
     * @param x
     * @param y
     * @return
     */
    public int judge(int x, int y) {
        for (int i = 0; i < 4; i++) {
            int upx = x, upy = y, downx = x, downy = y;
            int count = 1;
            if (i == 0) {
                while ((upx - 1) >= 0 && (upy - 1) >= 0) {
                    if (go[--upx][--upy].color == this.color)
                        count++;
                    else
                        break;
                }
                while ((downx + 1) <= (ROW - 1) && (downy + 1) <= (ROW - 1)) {
                    if (go[++downx][++downy].color == this.color)
                        count++;
                    else
                        break;
                }
                if (count >= 5) {
                    System.out.print(this.color + "胜利");
                    return this.color;
                }
            } else if (i == 1) {
                while ((upy - 1) >= 0) {
                    if (go[upx][--upy].color == this.color)
                        count++;
                    else
                        break;
                }
                while ((downy + 1) <= (ROW - 1)) {
                    if (go[downx][++downy].color == this.color)
                        count++;
                    else
                        break;
                }
                if (count >= 5) {
                    System.out.print(this.color + "胜利");
                    return this.color;
                }
            } else if (i == 2) {
                while ((upx + 1) <= (ROW - 1) && (upy - 1) >= 0) {
                    if (go[++upx][--upy].color == this.color)
                        count++;
                    else
                        break;
                }
                while ((downx - 1) >= 0 && (downy + 1) <= (ROW - 1)) {
                    if (go[--downx][++downy].color == this.color)
                        count++;
                    else
                        break;
                }
                if (count >= 5) {
                    System.out.print(this.color + "胜利");
                    return this.color;
                }
            } else if (i == 3) {
                while ((downx - 1) >= 0) {
                    if (go[--downx][downy].color == this.color)
                        count++;
                    else
                        break;
                }
                while ((upx + 1) <= (ROW - 1)) {
                    if (go[++upx][upy].color == this.color)
                        count++;
                    else
                        break;
                }
                if (count >= 5) {
                    System.out.print(this.color + "胜利");
                    return this.color;
                }
            }
        }
        return 0;
    }

}

猜你喜欢

转载自blog.csdn.net/qq_29897369/article/details/82534596