首页 > 编程 > Java > 正文

Java五子棋AI实现代码

2019-11-26 09:17:29
字体:
来源:转载
供稿:网友

思路:

  • ①五子棋界面的实现
  • ②交互下棋的实现
  • ③重绘
  • ④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;          }        }      }    }  }}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对武林网的支持。如果你想了解更多相关内容请查看下面相关链接

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表