五子棋AI算法 也算是一个典型的游戏AI算法,一些棋类的AI算法都可以参考实现,下面是Java实现代码
棋盘抽象接口
import java.util.List;
public interface IChessboard {
//取得棋盘最大横坐标
public int getMaxX();
//最大纵坐标
public int getMaxY();
//取得当前所有空白点,这些点才可以下棋
public List<Point> getFreePoints();
}
棋子类实现
//棋子类
public class Point {
// 这了性能,设成公有
public int x;
public int y;
public int getX() {
return x;
}
public Point setX(int x) {
this.x = x;
return this;
}
public int getY() {
return y;
}
public Point setY(int y) {
this.y = y;
return this;
}
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
return x + y;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
Point other = (Point) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
玩家抽象接口
import java.util.List;
public interface IPlayer {
//下一步棋子,传入对手已经下的棋子集合
public void run(List<Point> enemyPoints, Point point);
public boolean hasWin();
public void setChessboard(IChessboard chessboard);
public List<Point> getMyPoints();
}
玩家基础抽象类
import java.util.ArrayList;
import java.util.List;
public abstract class BasePlayer implements IPlayer {
//我已下的棋子
protected List<Point> myPoints = new ArrayList<Point>(200);
//棋盘
protected IChessboard chessboard;
//棋盘最大横坐标和纵标,
protected int maxX;
protected int maxY;
//所有空白棋子
protected List<Point> allFreePoints;
@Override
public final List<Point> getMyPoints() {
return myPoints;
}
@Override
public void setChessboard(IChessboard chessboard) {
this.chessboard = chessboard;
allFreePoints = chessboard.getFreePoints();
maxX = chessboard.getMaxX();
maxY = chessboard.getMaxY();
myPoints.clear();
}
private final Point temp = new Point(0, 0);
//我是否是否赢了
public final boolean hasWin(){
if(myPoints.size()<5){
return false;
}
Point point = myPoints.get(myPoints.size()-1);
int count = 1;
int x=point.getX(),y=point.getY();
//横向--
temp.setX(x).setY(y);
while (myPoints.contains(temp.setX(temp.getX()-1)) && temp.getX()>=0 && count<5) {
count ++;
}
if(count>=5){
return true;
}
temp.setX(x).setY(y);
while (myPoints.contains(temp.setX(temp.getX()+1)) && temp.getX()<maxX && count<5) {
count ++;
}
if(count>=5){
return true;
}
//纵向|
count = 1;
temp.setX(x).setY(y);
while (myPoints.contains(temp.setY(temp.getY()-1)) && temp.getY()>=0) {
count ++;
}
if(count>=5){
return true;
}
temp.setX(x).setY(y);
while (myPoints.contains(temp.setY(temp.getY()+1)) && temp.getY()<maxY && count<5) {
count ++;
}
if(count>=5){
return true;
}
//正斜向 /
count =1;
temp.setX(x).setY(y);
while (myPoints.contains(temp.setX(temp.getX()-1).setY(temp.getY()+1)) && temp.getX()>=0 && temp.getY()<maxY) {
count ++;
}
if(count>=5){
return true;
}
temp.setX(x).setY(y);
while (myPoints.contains(temp.setX(temp.getX()+1).setY(temp.getY()-1)) && temp.getX()<maxX && temp.getY()>=0 && count<6) {
count ++;
}
if(count>=5){
return true;
}
//反斜 \
count = 1;
temp.setX(x).setY(y);
while (myPoints.contains(temp.setX(temp.getX()-1).setY(temp.getY()-1)) && temp.getX()>=0 && temp.getY()>=0) {
count ++;
}
if(count>=5){
return true;
}
temp.setX(x).setY(y);
while (myPoints.contains(temp.setX(temp.getX()+1).setY(temp.getY()+1)) && temp.getX()<maxX && temp.getY()<maxY && count<5) {
count ++;
}
if(count>=5){
return true;
}
return false;
}
}
电脑AI类实现
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//算法核心类,算法的主体思想分三个步骤,
//第一步:根据双方的当前的形势循环地假设性的分别给自己和对方下一子(在某个范围内下子),并判断此棋子能带来的形势上的变化,如能不能冲4,能不能形成我方或敌方双3等,
//第二步:根据上一步结果,组合每一步棋子所带来的所有结果(如某一步棋子可能形成我方1个活3,1个冲4(我叫它半活4)等),包括敌方和我方的。
//第三步:根据用户给的规则对上一步结果进行排序,并选子(有进攻形、防守形规则)
public class BaseComputerAi extends BasePlayer {
// 四个方向,横- 、纵| 、正斜/ 、反斜\
private static final int HENG = 0;
private static final int ZHONG = 1;
private static final int ZHENG_XIE = 2;
private static final int FAN_XIE = 3;
//往前往后
private static final boolean FORWARD = true;
private static final boolean BACKWARD = false;
//标示分析结果当前点位是两头通(ALIVE)还是只有一头通(HALF_ALIVE),封死的棋子分析过程自动屏蔽,不作为待选棋子
private static final int ALIVE = 1;
private static final int HALF_ALIVE = 0;
//private static final int DEAD = -1;
//计算范围,太大的范围会有性能问题
private class CalcuteRange{
int xStart,yStart,xStop,yStop;
private CalcuteRange(int xStart, int yStart, int xStop, int yStop) {
this.xStart = xStart;
this.yStart = yStart;
this.xStop = xStop;
this.yStop = yStop;
}
}
//限定电脑计算范围,如果整个棋盘计算,性能太差,目前是根据所有已下的棋子的边界值加RANGE_STEP值形成,目前为1
private static final int RANGE_STEP = 1;
CalcuteRange currentRange = new CalcuteRange(0, 0, 0, 0);
private void initRan