上一期我们做了人人对战的五子棋,今天我们就来做下人机对战的模块,加入AI.

首先要知道可以用什么方法

1.权值算法

2.博弈树算法

然而第二种方法我是不会的,就介绍下权值算法吧,给出下列步骤:

1.创建权值表:HashMap hm = new HashMap();

<>:泛型(泛指类:类,接口,数组)
hm.put("1",20);
hm.put("11",200);
hm.put("111",2000);
hm.put("1111",3000);
hm.put("12",10);
hm.put("112",100);
hm.put("1112",1000);
hm.put("11112",2000);

2.人先下,判输输赢!

3.搜索棋盘上棋局情况,设置权值

定义chessValue[][]数组,保存棋盘上的权值

public void AI(){
for(int i=0;i
for(int j=0;j

//判断当前是否为空

if(chessArray[i][j] == 0){

//搜索该空位八个方向上棋局情况

//定义两个变量分别保存棋局,以及颜色

String code = "";
int color = 0;
//向下
for(int k=i+1;k
if(chessArray[k][j] == 0){
break;
}else{
if(color == 0){ //下边第一颗棋子
color = chessArray[k][j]; //保存颜色
code += chessArray[k][j]; //保存棋局
}else if(chessArray[k][j] == color){ //下边第二,三..同颜色棋子
code += chessArray[k][j]; //保存棋局
}else{ //下边不同颜色
code += chessArray[k][j]; //保存棋局
break;
}
}
}
//根据code取出hm对应的权值
Integer value = hm.get(code);
if(value != null){
chessValue[i][j] +=value; //权值累加
}
//剩余七个方向
code = "";
color = 0;
}
}
}
}

4.找出chessValue最大值的交点位置,该位置电脑下棋,判断输赢!

5.清空chessValue数组

这种方法其实就是逐个对棋盘上空着的下棋点进行各个方向权值的大小判断,在权值最大的下棋点下棋,不管是什么颜色的棋权值最大,下就对了。

那我们按照这些步骤来写代码:

继续建个类

在类里建一个ai()方法,导入权值表,再写八个方向权值加重的方法,经过八个方向的加重会得到该可下棋点的最终权值chessValue[] [],再逐个比较每个下棋点的权值大小,取最大点的横纵坐标,下棋(画上棋子),最后要将每个点的chessValue[] []清零,不影响下一次下棋的权值。

方法就这样写完了,接下来就是在事件类中调用。

首先,对【人机对战】按钮加上监听器,在actionPerformed 抽象方法中写入点击按钮后的执行方法。在此,我们是要点击按钮后改变下棋模式,将mode改为2(初始为1,代表人人对战),即点击后,判断mode是1还是2,令mode为1时是原来人机的代码,如果是2则进行另一种操作:先对点击点下黑棋,黑白数组赋值为1,再进行调用AI类里的ai(),这样就行啦。

不过点击换游戏模式后其实我们应该先清空棋盘进入新游戏的,所以可以在【人人对战】【人机对战】里写重新开始的方法,完善我们的简单五子棋游戏。

除此之外,还有很多地方可以完善,比如黑白棋先手的选择,背景颜色的选择,甚至算法上的完善,寻找更好的权值······

好啦,这期就到这里,下棋我们通过多线程做些弹球游戏~

不过你肯定想问,下期是什么时候呢,嘘·······

下期我再告诉你哈~~~

附上完整代码,走过路过请点赞(虽然这次写得好乱QAQ):

一、AI类:

import java.awt.Color;
import java.util.HashMap;
public class AI implements Config {
private Graphics g;
private int[][] chess;
private int[][] chessValue = new int[ROWS][COLUMNS];
private int maxi, maxj;
HashMap hm = new HashMap();
public AI(Graphics g, int[][] chess) {
this.g = g;
this.chess = chess;
//this.setai_i=setai_i;
//this.setai_j=setai_j;
}
public void ai() {
hm.put("1", 20);
hm.put("11", 400);
hm.put("111", 420);
hm.put("1111", 3000);
hm.put("12", 4);
hm.put("112", 40);
hm.put("1112", 400);
hm.put("11112", 10000);
hm.put("21111", 10000);
hm.put("2", 8);
hm.put("22", 80);
hm.put("222", 1000);
hm.put("2222", 5000);
hm.put("22221", 5000);
hm.put("222211", 5000);
hm.put("21", 6);
hm.put("221", 60);
hm.put("2221", 600);
hm.put("121", 5);
hm.put("1221", 5);
hm.put("2112", 5);
hm.put("212", 5);
for (int i = 0; i < chess.length; i++)
for (int j = 0; j < chess.length; j++) {
if (chess[i][j] == 0) {
// 向右
String code = "";
int color = 0;
for (int k = i + 1; k < chess.length; k++) {
if (chess[k][j] == 0)
break;
else {// 有棋子
if (color == 0) {
color = chess[k][j];// 保存第一颗棋子的颜色
code += chess[k][j];// 保存棋子相连的情况
} else if (chess[k][j] == color)
code += chess[k][j];// 保存棋子相连的情况
else {// 不同棋子跳出循环
code += chess[k][j];// 保存棋子相连的情况
break;
}
}
}
Integer value = hm.get(code);
if (value != null)
chessValue[i][j] += value; // 权值累加
// 向左
code = "";
color = 0;
for (int k = i - 1; k >= 0; k--) {
if (chess[k][j] == 0)
break;
else {
if (color == 0) {
color = chess[k][j];
code += chess[k][j];
} else if (chess[k][j] == color)
code += chess[k][j];
else {
code += chess[k][j];
break;
}
}
value = hm.get(code);
if (value != null)
chessValue[i][j] += value; // 权值累加
}
// 向下
code = "";
color = 0;
for (int k = j + 1; k < chess.length; k++) {
if (chess[i][k] == 0)
break;
else {
if (color == 0) {
color = chess[i][k];
code += chess[i][k];
} else if (chess[i][k] == color)
code += chess[i][k];
else {
code += chess[i][k];
break;
}
}
value = hm.get(code);
if (value != null)
chessValue[i][j] += value; // 权值累加
}
// 向上
code = "";
color = 0;
for (int k = j - 1; k >= 0; k--) {
if (chess[i][k] == 0)
break;
else {
if (color == 0) {
color = chess[i][k];
code += chess[i][k];
} else if (chess[i][k] == color)
code += chess[i][k];
else {
code += chess[i][k];
break;
}
}
value = hm.get(code);
if (value != null)
chessValue[i][j] += value; // 权值累加
}
// 左上
code = "";
color = 0;
for (int m = i - 1, n = j - 1; m >= 0 && n >= 0; m--, n--) {
if (chess[m][n] == 0)
break;
else if (color == 0) {
color = chess[m][n];
code += chess[m][n];
} else if (chess[m][n] == color)
code += chess[m][n];
else {
code += chess[m][n];
break;
}
value = hm.get(code);
if (value != null)
chessValue[i][j] += value; // 权值累加
}
// 右上
code = "";
color = 0;
for (int m = i + 1, n = j - 1; m < chess.length && n >= 0; m++, n--) {
if (chess[m][n] == 0)
break;
else {
if (color == 0) {
color = chess[m][n];
code += chess[m][n];
} else if (chess[m][n] == color)
code += chess[m][n];
else {
code += chess[m][n];
break;
}
}
value = hm.get(code);
if (value != null)
chessValue[i][j] += value; // 权值累加
}
// 左下
code = "";
color = 0;
for (int m = i - 1, n = j + 1; m >= 0 && n < chess.length; m--, n++) {
if (chess[m][n] == 0)
break;
else {
if (color == 0) {
color = chess[m][n];
code += chess[m][n];
} else if (chess[m][n] == color)
code += chess[m][n];
else {
code += chess[m][n];
break;
}
}
value = hm.get(code);
if (value != null)
chessValue[i][j] += value; // 权值累加
}
// 右下
code = "";
color = 0;
for (int m = i + 1, n = j + 1; m < chess.length && n < chess.length; m++, n++) {
if (chess[m][n] == 0)
break;
else {
if (color == 0) {
color = chess[m][n];
code += chess[m][n];
} else if (chess[m][n] == color)
code += chess[m][n];
else {
code += chess[m][n];
break;
}
}
value = hm.get(code);
if (value != null)
chessValue[i][j] += value; // 权值累加
}
}
}
int maxv = 0;
for (int j = 0; j < chess.length; j++)
for (int i = 0; i < chess.length; i++) {
if (maxv < chessValue[i][j]) {
maxv = chessValue[i][j];
maxi = i;
maxj = j;
}
}
g.setColor(Color.WHITE);
g.fillOval(X0 + maxi * SIZE - CHESS_SIZE / 2, Y0 + maxj * SIZE - CHESS_SIZE / 2, CHESS_SIZE, CHESS_SIZE);
chess[maxi][maxj] = 2;
Win win = new Win(chess);
win.isWin(maxi, maxj);
//
for (int j = 0; j < chess.length; j++)
for (int i = 0; i < chess.length; i++)
chessValue[i][j] = 0;
}
}
二、监听类(ChessListener):
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class ChessListener extends MouseAdapter implements Config,ActionListener{
private Graphics g;
private ChessBoard j;
private int x, y, xx, yy;
private int count = 0,mode = 1;//mode为游戏模式,默认为人人
// 保存棋子的数组
private int[][] chessArray;
private int[] setX = new int[ROWS * COLUMNS];
private int[] setY = new int[ROWS * COLUMNS];
private AI a;
public void setChessListener(Graphics g, int[][] chess,ChessBoard j) {
this.g = g;
this.chessArray = chess;
this.j = j;
a=new AI(g, chessArray);
}
public void mouseReleased(MouseEvent e) {
x = e.getX();
y = e.getY();
if ((x - X0) % SIZE > SIZE / 2) {
xx = (x - X0) / SIZE + 1;
} else {
xx = (x - X0) / SIZE;
}
if ((y - Y0) % SIZE > SIZE / 2) {
yy = (y - Y0) / SIZE + 1;
} else {
yy = (y - Y0) / SIZE;
}
if(mode==1){
if (chessArray[xx][yy] == 0) {
if (count % 2 == 0) {
g.setColor(Color.black );
chessArray[xx][yy] = 1;
} else {
g.setColor(Color.WHITE);
chessArray[xx][yy] = 2;
}
setX[count] = xx;
setY[count] = yy;
count++;
g.fillOval(xx * SIZE + X0 - CHESS_SIZE / 2, yy * SIZE + Y0 - CHESS_SIZE / 2, CHESS_SIZE, CHESS_SIZE);
Win win = new Win(chessArray);
win.isWin(xx,yy);
}
}
else if(mode==2){
g.setColor(Color.black);
chessArray[xx][yy] = 1;
g.fillOval(xx * SIZE + X0 - CHESS_SIZE / 2, yy * SIZE + Y0 - CHESS_SIZE / 2, CHESS_SIZE, CHESS_SIZE);
Win win = new Win(chessArray);
win.isWin(xx, yy);
count++;
}
}
public void actionPerformed(ActionEvent e) {
if ("悔棋".equals(e.getActionCommand())) {
if (count>0){
count--;
chessArray[setX[count]][setY[count]]=0;
j.repaint();
}
}
if ("重新开始".equals(e.getActionCommand())) {
for (int j = 0; j < chessArray.length; j++) {
for (int i = 0; i < chessArray.length; i++) {
chessArray[i][j] = 0;
count = 0;
}
}
j.repaint();
}
if ("人机对战".equals(e.getActionCommand())) {
for (int j = 0; j < chessArray.length; j++) {
for (int i = 0; i < chessArray.length; i++) {
chessArray[i][j] = 0;
count = 0;
}
}
System.out.println("人机准备");
mode = 2;
j.repaint();
}
if ("人人对战".equals(e.getActionCommand())) {
for (int j = 0; j < chessArray.length; j++) {
for (int i = 0; i < chessArray.length; i++) {
chessArray[i][j] = 0;
count = 0;
}
}
System.out.println("人人准备");
mode = 1;
j.repaint();
}
}
}

其他三个类(ChessBroad、Config、Win)见上一篇博客.