Java五子棋AI实现代码
程序员文章站
2024-02-21 12:38:10
思路:
①五子棋界面的实现
②交互下棋的实现
③重绘
④ai,实现人机对战
五子棋和简单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; } } } } } }
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接
上一篇: Java实现循环体的过滤器的方法
下一篇: Java集合之HashMap用法详解