java五子棋AI

思路:
①五子棋界面的实现
②交互下棋的实现
③重绘
④AI,实现人机对战

五子棋和简单AI的实现:
首先将五子棋的界面写出来。
首先我们写一个接口类,定义好棋盘的数据(目的是方便修改)。

public interface Config {
    public static final int X0=50;//左上角起点X值
    public static final int Y0=50;//左上角起点Y值
    public static final int ROWS=15;//横向线数
    public static final int COLUMNS=15;//纵向线数
    public static final int CHESSSIZE=40;//棋子直径
    public static final int SIZE=50;//单元格大小
}

再来写五子棋的界面。写界面的方法和画图板是一样的。

public class FiveChessUI extends JFrame  implements Config {
    static FiveChessUI fcUI = new FiveChessUI();
    public static void main(String[] args){
        fcUI.initUI();
    }
    private int [][] chesses = new int[ROWS][COLUMNS];//创建一个二维数组用来标记棋盘上的位置

    /**
     * 初始化五子棋窗体的方法
     */
    public void initUI(){
        ChessListener listener = new ChessListener(chesses,fcUI);
        this.setTitle("五子棋v1.0");
        this.setSize(900, 800);//设置界面尺寸
        this.setResizable(false);//界面不可改变大小
        this.setLocationRelativeTo(null);//设置界面居中
        this.setDefaultCloseOperation(3);//设置退出进程
        BorderLayout bl = new BorderLayout();//设置界面布局为窗体式布局
        this.setLayout(bl);
        JPanel jp = new JPanel();
        jp.setPreferredSize(new Dimension(100,0));
        this.add(jp,BorderLayout.EAST);
        String [] name ={"重新开始","黑棋先下","白棋先下","悔棋","人机对战","人人对战"};
        for(int i=0;i<name.length;i++){//依次给按钮添加动作监听,这里用循环可减少代码
            JButton jbu = new JButton(name[i]);
            jbu.setPreferredSize(new Dimension(95,30));
            jp.add(jbu);
            jbu.addActionListener(listener);

        }

        this.setVisible(true);//设置可见
        listener.gr = this.getGraphics();
        this.addMouseListener(listener);//给界面加上鼠标监听



    }
    /**
     * 重写绘制窗体的方法
     */
    public void paint(Graphics g){
        super.paint(g);
        //在重绘的同时绘制棋盘
        drawChessTable(g);
        //在重绘的同时绘制棋子
        drawChess(g);
    }
    public void drawChess(Graphics g){
        ImageIcon bai = new ImageIcon("C:\\Users\\Administrator\\Pictures\\五子棋\\baizi.png");//添加白子图片
        ImageIcon hei = new ImageIcon("C:\\Users\\Administrator\\Pictures\\五子棋\\heizi.png");//添加黑子图片
        for(int i=0;i<chesses.length;i++){
            for(int j=0;j<chesses.length;j++){
                if(chesses[i][j]==1){
                    g.drawImage(hei.getImage(), X0 + SIZE * i - Config.CHESSSIZE / 2, Y0 + SIZE * j - Config.CHESSSIZE / 2, Config.CHESSSIZE,
                            Config.CHESSSIZE, null);
                }else if(chesses[i][j]==-1){
                    g.drawImage(bai.getImage(), X0 + SIZE * i - Config.CHESSSIZE / 2, Y0 + SIZE * j - Config.CHESSSIZE / 2, Config.CHESSSIZE,
                            Config.CHESSSIZE, null);
                }
            }
        }
    }
    public void drawChessTable(Graphics g){
        //添加背景图片
        ImageIcon img= new ImageIcon("C:\\Users\\Administrator\\Pictures\\chesstable.jpg");
        g.drawImage(img.getImage(), 0, 0, 800, 800,null);
        //画棋盘横线
        for(int i=0;i<ROWS;i++){
            g.drawLine(X0, Y0+i*SIZE, X0+(COLUMNS-1)*SIZE, Y0+i*SIZE);
        }
        //画棋盘竖线
        for(int j=0;j<Config.COLUMNS;j++){
            g.drawLine(X0+j*SIZE, Y0, X0+j*SIZE,Y0+(ROWS-1)*SIZE );
        }
    }

}

监听器类代码如下:

import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;

import javax.swing.ImageIcon;
import javax.swing.JOptionPane;

public class ChessListener extends MouseAdapter implements Config, ActionListener {
    public Graphics gr;
    private int count = 0;// 计数器
    private int[][] chesses;// 创建一个二维数组用来存放棋子的坐标
    private String name;
    private int t, r;
    private int cl = 0, AI=2;
    private int i, j, x, y, z = 0, w = 0,zz=0,ww=0;
    private FiveChessUI fc;// 声明FiveChessUI类的一个对象
    private int setX[] = new int[ROWS * COLUMNS];// 创建一维数组setX[]
    private int setY[] = new int[ROWS * COLUMNS];// 创建一维数组setY[]
    private int[][] chessValue = new int[ROWS][COLUMNS];
    private int index = 0;// 创建数组的下标

    HashMap<String, Integer> hm = new HashMap<String, Integer>();//创建权值表

    public ChessListener(int[][] chesses, FiveChessUI fc) {
        this.fc = fc;
        this.chesses = chesses;
        //权值设置,这个需要自己慢慢调,小编写的一般,AI有时会出问题
        hm.put("1", 20);
        hm.put("11", 60);
        hm.put("111", 200);
        hm.put("1111", 1000);

        hm.put("-1", 20);
        hm.put("-1-1", 60);
        hm.put("-1-1-1", 200);
        hm.put("-1-1-1-1", 1000);

        hm.put("1-1", 20);
        hm.put("11-1", 30);
        hm.put("111-1", 80);
        hm.put("1111-1", 1000);

        hm.put("-11", 20);
        hm.put("-111", 30);
        hm.put("-1111", 80);
        hm.put("-11111", 1000);

        hm.put("1-1", 20);
        hm.put("-1-11", 30);
        hm.put("-1-1-11", 80);
        hm.put("-1-1-1-11", 1000);

        hm.put("1-1", 20);
        hm.put("1-1-1", 30);
        hm.put("1-1-1-1", 80);
        hm.put("1-1-1-1-1", 1000);


    }

    public void mouseReleased(MouseEvent e) {
        // 得到鼠标事件发生的时候光标的位置
        int x1 = e.getX();
        int y1 = e.getY();
        // 按行遍历棋盘,坐标(i,j)
        for (j = 0; j < ROWS; j++) {
            for (i = 0; i < ROWS; i++) {// 得到交叉点的坐标
                x = X0 + SIZE * i;// 横坐标
                y = Y0 + SIZE * j;// 纵坐标
                // 与圆心的误差为size/3
                if (x1 > x - SIZE * 5 / 12 && x1 < x + SIZE * 5 / 12 && y1 > y - SIZE * 5 / 12
                        && y1 < y + SIZE * 5 / 12) {
                    ImageIcon bai = new ImageIcon("C:\\Users\\Administrator\\Pictures\\baizi5.png");
                    ImageIcon hei = new ImageIcon("C:\\Users\\Administrator\\Pictures\\heizi4.png");
                    if (AI == 0) { // 人人对战
                        if (chesses[i][j] == 0) {// 如果选的位置没有棋子
                            if (count == 0) {
                                chesses[i][j] = 1;// 如果是黑子,就为1
                                count++;
                                gr.drawImage(hei.getImage(), X0 + SIZE * i - CHESSSIZE / 2,
                                        Y0 + SIZE * j - CHESSSIZE / 2, CHESSSIZE, CHESSSIZE, null);
                                cl = 0;
                            } else {
                                chesses[i][j] = -1;// 如果是白子就为-1
                                count--;
                                gr.drawImage(bai.getImage(), X0 + SIZE * i - CHESSSIZE / 2,
                                        Y0 + SIZE * j - CHESSSIZE / 2, CHESSSIZE, CHESSSIZE, null);
                                cl = 1;
                            }
                            setX[index] = i;// 将下的棋子的横坐标存入setX[]
                            setY[index] = j;// 将下的棋子的纵坐标存入setY[]
                            index++;// 存入一个坐标,一维数组角标加1
                            // 以交叉点画圆
                            checkRow(i, j);
                            z = 1;
                            w = 1;
                            return;
                        }
                    }
                    if (AI == 1) { // 人机对战

                        if (chesses[i][j] == 0) {// 如果选的位置没有棋子
                            if (count == 0) {
                                // 玩家下棋
                                chesses[i][j] = 1;// 如果是黑子,就为1
                                // count++;
                                gr.drawImage(hei.getImage(), X0 + SIZE * i - CHESSSIZE / 2,
                                        Y0 + SIZE * j - CHESSSIZE / 2, CHESSSIZE, CHESSSIZE, null);
                                cl = 0;
                                count++;
                                checkRow(i, j);//判断是否胜利
                                setX[index] = i;// 将下的棋子的横坐标存入setX[]
                                setY[index] = j;// 将下的棋子的纵坐标存入setY[]
                                index++;// 存入一个坐标,一维数组角标加1
                            }
                            this.AI();
                            if (count == 1) {
                                // 输出所有点的权值
                                for (int j = 0; j < chessValue.length; j++) {
                                    for (int i = 0; i < chessValue.length; i++) {
                                        System.out.print(chessValue[i][j] + " ");
                                    }
                                    System.out.println();
                                }
                                // 电脑下棋
                                // 筛选出chessValue最大值的交点坐标, 该坐标电脑下棋
                                for (int j = 0; j < chessValue.length; j++) {
                                    for (int i = 0; i < chessValue.length; i++) {
                                        if (chessValue[0][0] < chessValue[i][j]) {
                                            chessValue[0][0] = chessValue[i][j];
                                            t = i;
                                            r = j;
                                        }
                                    }
                                }
                                count--;
                                chesses[t][r] = -1;
                                gr.drawImage(bai.getImage(), X0 + SIZE * t - CHESSSIZE / 2,
                                        Y0 + SIZE * r - CHESSSIZE / 2, CHESSSIZE, CHESSSIZE, null);
                                cl = 1;
                                setX[index] = r;// 将下的棋子的横坐标存入setX[]
                                setY[index] = t;// 将下的棋子的纵坐标存入setY[]
                                index++;// 存入一个坐标,一维数组角标加1
                                checkRow(t, r);//判断是否胜利
                                zz = 1;//
                                ww = 1;
                                // 清空value
                                for (int i = 0; i < chessValue.length; i++) {
                                    for (int j = 0; j < chessValue.length; j++) {
                                        chessValue[i][j] = 0;
                                    }

                                }

                            }
                        }
                    }
                }
            }

        }

    }

    // 判断胜利的条件
    public int checkRow(int x, int y) {
        int count1 = 0, count2 = 0, count3 = 0, count4 = 0;// 定义4个棋子计数器,分别计数水平,竖直、斜向右下、斜向左下

        for (int i = x + 1; i < chesses.length; i++) {
            if (chesses[i][y] == chesses[x][y]) {
                count1++;

            } else
                break;
        }
        for (int i = x; i >= 0; i--) {
            if (chesses[i][y] == chesses[x][y]) {
                count1++;
            } else
                break;
        }
        for (int j = y + 1; j < chesses.length; j++) {
            if (chesses[x][j] == chesses[x][y]) {
                count2++;
            } else
                break;
        }
        for (int j = y; j >= 0; j--) {
            if (chesses[x][y] == chesses[x][j]) {
                count2++;
            } else
                break;
        }
        for (int i = x + 1, j = y + 1; i < chesses.length && j < chesses.length; i++, j++) {
            if (chesses[i][j] == chesses[x][y]) {
                count3++;
            } else
                break;

        }
        for (int i = x, j = y; i >= 0 && j >= 0; i--, j--) {
            if (chesses[i][j] == chesses[x][y]) {
                count3++;
            } else
                break;

        }
        for (int i = x, j = y; i < chesses.length && j >= 0; i++, j--) {
            if (chesses[i][j] == chesses[x][y]) {

                count4++;
            } else
                break;

        }
        for (int i = x - 1, j = y + 1; i >= 0 && j < chesses.length; i--, j++) {
            if (chesses[i][j] == chesses[x][y]) {
                count4++;
            } else
                break;

        }
        if (count1 >= 5 || count2 >= 5 || count3 >= 5 || count4 >= 5) {

            count = 0;
            if (cl == 0) {
                JOptionPane.showMessageDialog(null, "黑棋赢!");
                for (int i = 0; i < chesses.length; i++) {
                    for (int j = 0; j < chesses.length; j++) {
                        chesses[i][j] = 0;

                    }
                }
                fc.repaint();

            }
            if (cl == 1) {
                JOptionPane.showMessageDialog(null, "白棋赢!");
                for (int i = 0; i < chesses.length; i++) {
                    for (int j = 0; j < chesses.length; j++) {
                        chesses[i][j] = 0;
                    }
                }
                fc.repaint();
            }
        }
        return count;

    }

    public void actionPerformed(ActionEvent e) {
        name = e.getActionCommand();

        if ("重新开始".equals(name)) {
            count = 0;
            z = 0;
            w = 0;
            for (int i = 0; i < chesses.length; i++) {
                for (int j = 0; j < chesses.length; j++) {
                    chesses[i][j] = 0;
                }
            }

            fc.repaint();
        }
        if ("白棋先下".equals(name)) {
            if (z == 0) {
                count = 1;
                z = 1;
            }
        }
        if ("黑棋先下".equals(name)) {
            if (w == 0) {
                count = 0;
                w = 1;
            }
        }
        if ("悔棋".equals(name)) {
            this.huiqi();
        }
        if ("人机对战".equals(name)) {
            if(w==0){
            AI = 1;
            ww=1;
            }

        }
        if ("人人对战".equals(name)) {
            if(z==0){
            AI = 0;
            }
        }
    }

    public void huiqi() {
        if (index >= 0) {
            index--;
            if (index < 0) {
                index = 0;
            }
            x = setX[index];
            y = setY[index];

            if (chesses[x][y] == 1) {
                chesses[x][y] = 0;
                count = 0;
            }
            if (chesses[x][y] == -1) {
                chesses[x][y] = 0;
                count = 1;

            }
            if(chesses[t][r]==-1){
                chesses[t][r]=0;
                count=1;
            }
            fc.repaint();
        }
    }

    public void AI() {
        for (int i = 0; i < chesses.length; i++) {
            for (int j = 0; j < chesses.length; j++) {
                if (chesses[i][j] == 0) {// 判断当前位置是否有棋子
                    // 定义两个变量分别保存棋局,颜色
                    String code = "";
                    int color = 0;
                    // 向右
                    for (int k = i + 1; k < chesses.length; k++) {
                        if (chesses[k][j] == 0) {
                            break;
                        } else {
                            if (color == 0) {// 右边第一颗棋子
                                color = chesses[k][j];// 保存颜色
                                code += chesses[k][j];// 保存棋局
                            } else if (chesses[k][j] == color) {// 右边第二,第三同颜色棋子
                                code += chesses[k][j];// 保存棋局
                            } else { // 右边不同颜色
                                code += chesses[k][j];
                                break;
                            }
                        }
                    }
                    // 根据code取出hm对应的权值
                    Integer value = hm.get(code);
                    if (value != null) {
                        chessValue[i][j] += value;
                    }
                    // 向左方向
                    code = "";
                    color = 0;
                    for (int k = i - 1; k >= 0; k--) {
                        if (chesses[k][j] == 0) {
                            break;
                        } else {
                            if (color == 0) {// 右边第一颗棋子
                                color = chesses[k][j];// 保存颜色
                                code += chesses[k][j];// 保存棋局
                            } else if (chesses[k][j] == color) {// 右边第二,第三同颜色棋子
                                code += chesses[k][j];// 保存棋局
                            } else { // 右边不同颜色
                                code += chesses[k][j];
                                break;
                            }
                        }
                    }
                    // 根据code取出hm对应的权值
                    Integer value2 = hm.get(code);
                    if (value2 != null) {
                        chessValue[i][j] += value2;
                    }
                    // 向上方向
                    code = "";
                    color = 0;
                    for (int k = j - 1; k >= 0; k--) {
                        if (chesses[i][k] == 0) {
                            break;
                        } else {
                            if (color == 0) {// 右边第一颗棋子
                                color = chesses[i][k];// 保存颜色
                                code += chesses[i][k];// 保存棋局
                            } else if (chesses[i][k] == color) {// 右边第二,第三同颜色棋子
                                code += chesses[i][k];// 保存棋局
                            } else { // 右边不同颜色
                                code += chesses[i][k];
                                break;
                            }
                        }
                    }
                    // 根据code取出hm对应的权值
                    Integer value3 = hm.get(code);
                    if (value3 != null) {
                        chessValue[i][j] += value3;
                    }
                    // 向下方向
                    code = "";
                    color = 0;
                    for (int k = j + 1; k < chesses.length; k++) {
                        if (chesses[i][k] == 0) {
                            break;
                        } else {
                            if (color == 0) {// 右边第一颗棋子
                                color = chesses[i][k];// 保存颜色
                                code += chesses[i][k];// 保存棋局
                            } else if (chesses[i][k] == color) {// 右边第二,第三同颜色棋子
                                code += chesses[i][k];// 保存棋局
                            } else { // 右边不同颜色
                                code += chesses[i][k];
                                break;
                            }
                        }
                    }
                    // 根据code取出hm对应的权值
                    Integer value4 = hm.get(code);
                    if (value4 != null) {
                        chessValue[i][j] += value4;
                    }

                    // 右上方向
                    code = "";
                    color = 0;
                    for (int k = j + 1, l = i - 1; l >= 0 && k < chesses.length; l--, k++) {
                        if (chesses[l][k] == 0) {
                            break;
                        } else {
                            if (color == 0) {// 右边第一颗棋子
                                color = chesses[l][k];// 保存颜色
                                code += chesses[l][k];// 保存棋局
                            } else if (chesses[l][k] == color) {// 右边第二,第三同颜色棋子
                                code += chesses[l][k];// 保存棋局
                            } else { // 右边不同颜色
                                code += chesses[l][k];
                                break;
                            }
                        }
                    }
                    // 根据code取出hm对应的权值
                    Integer value6 = hm.get(code);
                    if (value6 != null) {
                        chessValue[i][j] += value6;
                    }
                    // 左下方向
                    code = "";
                    color = 0;
                    for (int k = i + 1, l = j - 1; l >= 0 && k < chesses.length; k++, l--) {
                        if (chesses[k][l] == 0) {
                            break;
                        } else {
                            if (color == 0) {// 右边第一颗棋子
                                color = chesses[k][l];// 保存颜色
                                code += chesses[k][l];// 保存棋局
                            } else if (chesses[k][l] == color) {// 右边第二,第三同颜色棋子
                                code += chesses[k][l];// 保存棋局
                            } else { // 右边不同颜色
                                code += chesses[k][l];
                                break;
                            }
                        }
                    }
                    // 根据code取出hm对应的权值
                    Integer value7 = hm.get(code);
                    if (value7 != null) {
                        chessValue[i][j] += value7;
                    }
                    // 右下方向
                    code = "";
                    color = 0;
                    for (int k = i - 1, l = j - 1; l >= 0 && k >= 0; l--, k--) {
                        if (chesses[k][l] == 0) {
                            break;
                        } else {
                            if (color == 0) {// 右边第一颗棋子
                                color = chesses[k][l];// 保存颜色
                                code += chesses[k][l];// 保存棋局
                            } else if (chesses[k][l] == color) {// 右边第二,第三同颜色棋子
                                code += chesses[k][l];// 保存棋局
                            } else { // 右边不同颜色
                                code += chesses[k][l];
                                break;
                            }
                        }
                    }
                    // 根据code取出hm对应的权值
                    Integer value8 = hm.get(code);
                    if (value8 != null) {
                        chessValue[i][j] += value8;
                    }
                    // 左上方向
                    code = "";
                    color = 0;
                    for (int k = i + 1, l = j + 1; k < chesses.length && l < chesses.length; l++, k++) {
                        if (chesses[k][l] == 0) {
                            break;
                        } else {
                            if (color == 0) {// 右边第一颗棋子
                                color = chesses[k][l];// 保存颜色
                                code += chesses[k][l];// 保存棋局
                            } else if (chesses[k][l] == color) {// 右边第二,第三同颜色棋子
                                code += chesses[k][l];// 保存棋局
                            } else { // 右边不同颜色
                                code += chesses[k][l];
                                break;
                            }
                        }
                    }
                    // 根据code取出hm对应的权值
                    Integer value5 = hm.get(code);
                    if (value5 != null) {
                        chessValue[i][j] += value5;
                    }
                }
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/lzq1326253299/article/details/81711057