这一篇接Java之简单人机五子棋(一),讲一下AI算法实现的大致思路。主要思路是分别对黑白棋的局势进行打分,然后在找到评分最高的地方落点。
具体结构如下:
- 首先,point函数负责接收某点坐标和棋子颜色,然后返回对该点的评分。评分函数有四个,分别负责四个方向上的评分,即检测连子情况,依据不同的情况给予相应的分数。
- 其次,wholePoints负责在全局上对每一个点针对某种颜色进行评分,存到形参传入的15*15的评分数组中。
- best_posits负责遍历数组,找到评分最大的点位和个数,放入专门设计用来存储评分最大点的信息的类对象中。
- play 函数则负责对整体局势进行判断,综合比较取评分最高的点进行落子。
代码如下:
package renju;
class BestInfo{
int bestPoint,bestSum;
public BestInfo() {
bestPoint = 0;
bestSum = 0;
// TODO 自动生成的构造函数存根
}
public BestInfo(int i,int j){
bestPoint = i;
bestSum = j;
}
}
public class AI {
int color; //记录AI棋子的颜色
int points_b[][]; //记录黑棋各落点分数
int points_w[][]; //记录白棋各落点分数
position best_b[]; // 记录黑棋最大分数对应的落点位置
position best_w[]; //记录白棋最大分数对应的落点位置
BestInfo blackInfo,whiteInfo; //记录黑白棋分别的最大分数值和最大分数对应的落点位置个数
public AI() {
if(MyControlBoard.whiteC == 1) {
color = 2;
}
else {
color = 1;
}
points_b = new int[15][15]; //记录黑棋各落点分数
points_w = new int[15][15]; //记录白棋各落点分数
best_b = new position[250]; // 记录黑棋最大分数对应的落点位置
best_w = new position[250]; //记录白棋最大分数对应的落点位置
blackInfo = new BestInfo();
whiteInfo = new BestInfo();
}
public void play() {
if(!MyControlBoard.started) {
// System.out.println("didn't start");
return;
}
if(color == 2 && MyChessBoard.isEmpty) {
MyChessBoard.chess[7][7] = color;
MyChessBoard.record(7,7);
// System.out.println("empty");
return;
}
int iC,jC = 0,count = 0;
int xC = 0,yC = 0;
for(iC =0;iC<15;iC++)
for(jC = 0;jC < 15;jC++) {
if(MyChessBoard.chess[iC][jC] != 0) {
count+=1;
if(count==1) {
xC=iC;
yC=jC;
}
}
}
if(count == 1 && color == 1) {
try {
MyChessBoard.chess[xC-1][yC - 1] =color;
MyChessBoard.record(xC-1,yC-1);
// System.out.println("return1");
return;
}catch(Exception e){
MyChessBoard.chess[xC+1][yC + 1] =color;
MyChessBoard.record(xC-1,yC-1);
// System.out.println("return2");
return;
}
}
wholePoints(points_b, 2);
wholePoints(points_w, 1);
best_posits(points_w, best_w,whiteInfo);
best_posits(points_b, best_b,blackInfo);
// System.out.println("color AI ="+color);
// System.out.println("black"+blackInfo.bestPoint+"\twhite"+whiteInfo.bestPoint);
if( blackInfo.bestPoint > whiteInfo.bestPoint ) //黑棋最高分高过白棋,在黑棋最高分对应的位置中选出白棋分数最大的位置落子
{
int a[] = new int[20];
// System.out.println("blackInfo.bestSum"+blackInfo.bestSum);
for(int i = 0;i < blackInfo.bestSum;i++)
{
a[i] = point(best_b[i],1);
}
int max_w = MAX(a, blackInfo.bestSum);
for(int i = 0;i < blackInfo.bestSum;i++)
{
if(a[i] == max_w)
{
MyChessBoard.chess[best_b[i].x][best_b[i].y] = color;
MyChessBoard.record(best_b[i].x,best_b[i].y);
// System.out.println("return3");
return;
}
}
}
if( blackInfo.bestPoint < whiteInfo.bestPoint ) //白棋最高分高过黑棋,在白棋最高分对应的位置中选出黑棋分数最大的位置落子
{
int a[] = new int[20];
for(int i = 0;i < whiteInfo.bestSum;i++)
{
a[i] = point(best_w[i], 2);
}
int max_b = MAX(a, blackInfo.bestSum);
for(int i = 0;i < whiteInfo.bestSum;i++)
{
if(a[i] == max_b)
{
MyChessBoard.chess[best_w[i].x][best_w[i].y] = color;
MyChessBoard.record(best_w[i].x,best_w[i].y);
// System.out.println("return4");
return;
}
}
}
//最高分相等,则优先进行进攻