栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java五子棋AI实现代码

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

监听器类代码如下:

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 hm = new HashMap();//创建权值表
  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;
   }
 }
      }
    }
  }
}

总结

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/139004.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号