评论

收藏

[Java] Java五子棋AI实现代码

编程语言 编程语言 发布于:2021-10-05 15:51 | 阅读数:255 | 评论:0

今天小编就为大家分享一篇关于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;
      }
    }
    }
  }
  }
}
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对CodeAE代码之家的支持。如果你想了解更多相关内容请查看下面相关链接
原文链接:https://blog.csdn.net/lzq1326253299/article/details/81711057

关注下面的标签,发现更多相似文章