五子棋AI算法 Java实现

来源:互联网 发布:行助手检测网络 未通过 编辑:程序博客网 时间:2024/05/21 13:56

五子棋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;}@Overridepublic int hashCode() {return x + y;}@Overridepublic 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;@Overridepublic final List<Point> getMyPoints() {return myPoints;}@Overridepublic 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值形成,目前为1private static final int RANGE_STEP = 1;CalcuteRange currentRange = new CalcuteRange(0, 0, 0, 0);private void initRange(List<Point> comuters, List<Point> humans){currentRange.xStart = humans.get(0).getX()-RANGE_STEP;currentRange.yStart = humans.get(0).getY()-RANGE_STEP;currentRange.xStop = humans.get(0).getX()+RANGE_STEP;currentRange.yStop = humans.get(0).getY()+RANGE_STEP;for (Point point : humans) {if(point.getX()-RANGE_STEP<currentRange.xStart){currentRange.xStart = point.getX()-RANGE_STEP;}else if(point.getX()+RANGE_STEP>currentRange.xStop){currentRange.xStop = point.getX()+RANGE_STEP;}if(point.getY()-RANGE_STEP<currentRange.yStart){currentRange.yStart = point.getY()-RANGE_STEP;}else if(point.getY()+RANGE_STEP>currentRange.yStop){currentRange.yStop = point.getY()+RANGE_STEP;}}for (Point point : comuters) {if(point.getX()-RANGE_STEP<currentRange.xStart){currentRange.xStart = point.getX()-RANGE_STEP;}else if(point.getX()+RANGE_STEP>currentRange.xStop){currentRange.xStop = point.getX()+RANGE_STEP;}if(point.getY()-RANGE_STEP<currentRange.yStart){currentRange.yStart = point.getY()-RANGE_STEP;}else if(point.getY()+RANGE_STEP>currentRange.yStop){currentRange.yStop = point.getY()+RANGE_STEP;}}//如果范围扩大后超过了棋盘,则等于棋盘currentRange.xStart=currentRange.xStart<0?0:currentRange.xStart;currentRange.yStart=currentRange.yStart<0?0:currentRange.yStart;currentRange.xStop=currentRange.xStop>=maxX?maxX-1:currentRange.xStop;currentRange.yStop=currentRange.yStop>=maxY?maxY-1:currentRange.yStop;}// 分析当前形式的入口方法,分析总共分三个步骤,第三步骤可由子类干预以作难度控制private Point doAnalysis(List<Point> comuters, List<Point> humans) {if(humans.size()==1){//第一步return getFirstPoint(humans);}//初始化计算范围initRange(comuters, humans);//清除以前的结果initAnalysisResults();// 开始分析,扫描所有空白点,形成第一次分析结果Point bestPoint = doFirstAnalysis(comuters, humans);if(bestPoint!=null){//System.out.println("这个棋子最重要,只能下这个棋子");return bestPoint;}// 分析第一次结果,找到自己的最佳点位bestPoint = doComputerSencondAnalysis(computerFirstResults,computerSencodResults);if(bestPoint!=null){//System.out.println("快要赢了,就下这个棋子");return bestPoint;}computerFirstResults.clear();System.gc();// 分析第一次结果,找到敌人的最佳点位bestPoint = doHumanSencondAnalysis(humanFirstResults,humanSencodResults);if(bestPoint!=null){//System.out.println("再不下这个棋子就输了");return bestPoint;}humanFirstResults.clear();System.gc();//没找到绝杀点,第三次结果分析return doThirdAnalysis();}//下第一步棋子,不需要复杂的计算,根据人类第一步棋子X值减1完成private Point getFirstPoint(List<Point> humans) {Point point = humans.get(0);if(point.getX()==0 || point.getY()==0 || point.getX()==maxX && point.getY()==maxY)return new Point(maxX/2, maxY/2);else{return new Point(point.getX()-1,point.getY());}}//private int debugx,debugy;//用于DEBUG// 开始分析,扫描所有空白点,形成第一次分析结果private Point doFirstAnalysis(List<Point> comuters, List<Point> humans){int size = allFreePoints.size();Point computerPoint = null;Point humanPoint = null;int x,y;FirstAnalysisResult firstAnalysisResult;for (int i = 0; i < size; i++) {computerPoint = allFreePoints.get(i);//先把X、Y坐标记下来,因为在分析过程中会改变原来的对象x = computerPoint.getX();y = computerPoint.getY();if(x<currentRange.xStart || x>currentRange.xStop || y<currentRange.yStart || y>currentRange.yStop){continue;}//if(x==debugx && y==debugy){//System.out.println("sssssssssssss");//}//尝试在此位置上下一个棋子,并分析在“横向”这个方向上我方可形成的状态,如活4,活3,半活4,活2等所有状态firstAnalysisResult = tryAndCountResult(comuters,humans, computerPoint, HENG);computerPoint.setX(x).setY(y);//回复点位的原值,以供下次分析if(firstAnalysisResult!=null){//无返回结果此方向上不可能达到五个棋子,if(firstAnalysisResult.count==5)//等于5表示在此点上下棋子即可连成5个,胜利了,不再往下进行分析return computerPoint;//记录第一次分析结果addToFirstAnalysisResult(firstAnalysisResult,computerFirstResults);}//在“纵向”这个方向上重复上面的步骤firstAnalysisResult = tryAndCountResult(comuters,humans, computerPoint, ZHONG);computerPoint.setX(x).setY(y);if(firstAnalysisResult!=null){//死棋,不下if(firstAnalysisResult.count==5)return computerPoint;addToFirstAnalysisResult(firstAnalysisResult,computerFirstResults);}//正斜向firstAnalysisResult = tryAndCountResult(comuters,humans, computerPoint, ZHENG_XIE);computerPoint.setX(x).setY(y);if(firstAnalysisResult!=null){//死棋,不下if(firstAnalysisResult.count==5)return computerPoint;addToFirstAnalysisResult(firstAnalysisResult,computerFirstResults);}//反斜向firstAnalysisResult = tryAndCountResult(comuters,humans, computerPoint, FAN_XIE);computerPoint.setX(x).setY(y);if(firstAnalysisResult!=null){//死棋,不下if(firstAnalysisResult.count==5)return computerPoint;addToFirstAnalysisResult(firstAnalysisResult,computerFirstResults);}//在“横向”上分析此棋子可在敌方形成如何状态,如敌方的活3、半活4等firstAnalysisResult = tryAndCountResult(humans,comuters, computerPoint, HENG);computerPoint.setX(x).setY(y);if(firstAnalysisResult!=null){//死棋,不下if(firstAnalysisResult.count==5)humanPoint = computerPoint;addToFirstAnalysisResult(firstAnalysisResult,humanFirstResults);}//“纵向”firstAnalysisResult = tryAndCountResult(humans,comuters, computerPoint, ZHONG);computerPoint.setX(x).setY(y);if(firstAnalysisResult!=null){//死棋,不下if(firstAnalysisResult.count==5)humanPoint = computerPoint;addToFirstAnalysisResult(firstAnalysisResult,humanFirstResults);}//“正斜”firstAnalysisResult = tryAndCountResult(humans,comuters, computerPoint, ZHENG_XIE);computerPoint.setX(x).setY(y);if(firstAnalysisResult!=null){//死棋,不下if(firstAnalysisResult.count==5)humanPoint = computerPoint;addToFirstAnalysisResult(firstAnalysisResult,humanFirstResults);}//“反斜”firstAnalysisResult = tryAndCountResult(humans,comuters, computerPoint, FAN_XIE);computerPoint.setX(x).setY(y);if(firstAnalysisResult!=null){//死棋,不下if(firstAnalysisResult.count==5)humanPoint = computerPoint;addToFirstAnalysisResult(firstAnalysisResult,humanFirstResults);}}//如果没有绝杀棋子,第一次分析不需要返回结果return humanPoint;}//第二次分析,分析第一次形成的结果,第一次分析结果会把一步棋在四个方向上可形成的结果生成最多四个FirstAnalysisResult对象(敌我各四)//这里要把这四个对象组合成一个SencondAnalysisResult对象,private Point doComputerSencondAnalysis(Map<Point,List<FirstAnalysisResult>> firstResults,List<SencondAnalysisResult> sencodResults) {List<FirstAnalysisResult> list = null;SencondAnalysisResult sr = null;for (Point p : firstResults.keySet()) {sr = new SencondAnalysisResult(p);list = firstResults.get(p);for (FirstAnalysisResult result : list) {if(result.count==4){if(result.aliveState==ALIVE){//经过前面的过滤,双方都排除了绝杀棋,有活4就下这一步了,再下一步就赢了return result.point;//如果有绝杀,第一轮已返回,在此轮活4已经是好的棋子,直接返回,不再往下分析}else{sr.halfAlive4 ++;computer4HalfAlives.add(sr);}}else if(result.count==3){if(result.aliveState==ALIVE){sr.alive3++;if(sr.alive3==1){computer3Alives.add(sr);}else{computerDouble3Alives.add(sr);}}else{sr.halfAlive3++;computer3HalfAlives.add(sr);}}else{//半活2在第一阶段已被排除,不再处理sr.alive2++;if(sr.alive2==1){computer2Alives.add(sr);}else{computerDouble2Alives.add(sr);}}}sencodResults.add(sr);}//没有找到活4return null;}//这个方法和上面的基本一样,但为了性能,少作几次判断,将人类和电脑的分开了private Point doHumanSencondAnalysis(Map<Point,List<FirstAnalysisResult>> firstResults,List<SencondAnalysisResult> sencodResults) {List<FirstAnalysisResult> list = null;SencondAnalysisResult sr = null;for (Point p : firstResults.keySet()) {sr = new SencondAnalysisResult(p);list = firstResults.get(p);for (FirstAnalysisResult result : list) {if(result.count==4){if(result.aliveState==ALIVE){human4Alives.add(sr);}else{sr.halfAlive4 ++;human4HalfAlives.add(sr);}}else if(result.count==3){if(result.aliveState==ALIVE){sr.alive3++;if(sr.alive3==1){human3Alives.add(sr);}else{humanDouble3Alives.add(sr);}}else{sr.halfAlive3++;human3HalfAlives.add(sr);}}else{sr.alive2++;if(sr.alive2==1){human2Alives.add(sr);}else{humanDouble2Alives.add(sr);}}}sencodResults.add(sr);}//没有找到活4return null;}private void sleep(int miniSecond){try {Thread.sleep(miniSecond);} catch (InterruptedException e) {}}//第三次分析,双方都不可以制造活4,找双活3棋子,不行就找半活4,再不行就找单活3,双活2private Point doThirdAnalysis() {if(!computer4HalfAlives.isEmpty()){return computer4HalfAlives.get(0).point;}System.gc();sleep(300);Collections.sort(computerSencodResults);System.gc();//即将单活4,且我没有半活4以上的,只能堵Point mostBest = getBestPoint(human4Alives, computerSencodResults);if(mostBest!=null)return mostBest;Collections.sort(humanSencodResults);System.gc();mostBest = getBestPoint();if(mostBest!=null)return mostBest;//拿出各自排第一的,谁好就下谁return computerSencodResults.get(0).point;}//子类实现这个方法,并改变其顺序可以实现防守为主还是猛攻protected Point getBestPoint(){//即将单活4,且我没有半活4以上的,只能堵Point mostBest = getBestPoint(computerDouble3Alives, humanSencodResults);if(mostBest!=null)return mostBest;mostBest = getBestPoint(computer3Alives, humanSencodResults);if(mostBest!=null)return mostBest;mostBest = getBestPoint(humanDouble3Alives, computerSencodResults);if(mostBest!=null)return mostBest;mostBest = getBestPoint(human3Alives, computerSencodResults);if(mostBest!=null)return mostBest;mostBest = getBestPoint(computerDouble2Alives, humanSencodResults);if(mostBest!=null)return mostBest;mostBest = getBestPoint(computer2Alives, humanSencodResults);if(mostBest!=null)return mostBest;mostBest = getBestPoint(computer3HalfAlives, humanSencodResults);if(mostBest!=null)return mostBest;mostBest = getBestPoint(human4HalfAlives, computerSencodResults);if(mostBest!=null)return mostBest;mostBest = getBestPoint(humanDouble2Alives, computerSencodResults);if(mostBest!=null)return mostBest;mostBest = getBestPoint(human2Alives, computerSencodResults);if(mostBest!=null)return mostBest;mostBest = getBestPoint(human3HalfAlives, computerSencodResults);return mostBest;}//第三次分析的最后一步,第二次结果已经过排序,在此可以从前面选出最好的棋子protected Point getBestPoint(List<SencondAnalysisResult> myBest,List<SencondAnalysisResult> yourSencodResults){if(!myBest.isEmpty()){if(myBest.size()>1){for (SencondAnalysisResult your : yourSencodResults) {if(myBest.contains(your)){return your.point;}}return myBest.get(0).point;}else{return myBest.get(0).point;}}return null;}//第一次分析结果private final Map<Point,List<FirstAnalysisResult>> computerFirstResults = new HashMap<Point,List<FirstAnalysisResult>>();private final Map<Point,List<FirstAnalysisResult>> humanFirstResults = new HashMap<Point,List<FirstAnalysisResult>>();//第二次总结果protected final List<SencondAnalysisResult> computerSencodResults = new ArrayList<SencondAnalysisResult>();protected final List<SencondAnalysisResult> humanSencodResults = new ArrayList<SencondAnalysisResult>();//第二次分结果,电脑protected final List<SencondAnalysisResult> computer4HalfAlives = new ArrayList<SencondAnalysisResult>(2);protected final List<SencondAnalysisResult> computerDouble3Alives = new ArrayList<SencondAnalysisResult>(4);protected final List<SencondAnalysisResult> computer3Alives = new ArrayList<SencondAnalysisResult>(5);protected final List<SencondAnalysisResult> computerDouble2Alives = new ArrayList<SencondAnalysisResult>();protected final List<SencondAnalysisResult> computer2Alives = new ArrayList<SencondAnalysisResult>();protected final List<SencondAnalysisResult> computer3HalfAlives = new ArrayList<SencondAnalysisResult>();//第二次分结果,人类protected final List<SencondAnalysisResult> human4Alives = new ArrayList<SencondAnalysisResult>(2);protected final List<SencondAnalysisResult> human4HalfAlives = new ArrayList<SencondAnalysisResult>(5);protected final List<SencondAnalysisResult> humanDouble3Alives = new ArrayList<SencondAnalysisResult>(2);protected final List<SencondAnalysisResult> human3Alives = new ArrayList<SencondAnalysisResult>(10);protected final List<SencondAnalysisResult> humanDouble2Alives = new ArrayList<SencondAnalysisResult>(3);protected final List<SencondAnalysisResult> human2Alives = new ArrayList<SencondAnalysisResult>();protected final List<SencondAnalysisResult> human3HalfAlives = new ArrayList<SencondAnalysisResult>();//第一次分析前清空上一步棋子的分析结果private void initAnalysisResults(){computerFirstResults.clear();humanFirstResults.clear();//第二次总结果computerSencodResults.clear();humanSencodResults.clear();//第二次分结果computer4HalfAlives.clear();computerDouble3Alives.clear();computer3Alives.clear();computerDouble2Alives.clear();computer2Alives.clear();computer3HalfAlives.clear();//第二次分结果,人类human4Alives.clear();human4HalfAlives.clear();humanDouble3Alives.clear();human3Alives.clear();humanDouble2Alives.clear();human2Alives.clear();human3HalfAlives.clear();System.gc();}//加入到第一次分析结果中private void addToFirstAnalysisResult(FirstAnalysisResult result,Map<Point,List<FirstAnalysisResult>> dest){if(dest.containsKey(result.point)){dest.get(result.point).add(result);}else{List<FirstAnalysisResult> list = new ArrayList<FirstAnalysisResult>(1);list.add(result);dest.put(result.point, list);}}//第一次分析结果类private class FirstAnalysisResult{//连续数int count;//点位Point point;//方向int direction;//状态int aliveState;private FirstAnalysisResult(int count, Point point, int direction) {this(count, point, direction, ALIVE);}private FirstAnalysisResult(int count, Point point, int direction,int aliveState) {this.count = count;this.point = point;this.direction = direction;this.aliveState = aliveState;}private FirstAnalysisResult init(Point point,int direction,int aliveState){this.count = 1;this.point = point;this.direction = direction;this.aliveState = aliveState;return this;}private FirstAnalysisResult cloneMe(){return new FirstAnalysisResult(count, point, direction,aliveState);}}//第二次分析结果类class SencondAnalysisResult implements Comparable<SencondAnalysisResult>{int alive4 = 0;//活3数量int alive3 = 0;//半活4,一头封的int halfAlive4 = 0;//半活3,一头封的int halfAlive3 = 0;//活2数量int alive2 = 0;//点位Point point;@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((point == null) ? 0 : point.hashCode());return result;}@Overridepublic boolean equals(Object obj) {SencondAnalysisResult other = (SencondAnalysisResult) obj;if (point == null) {if (other.point != null)return false;} else if (!point.equals(other.point))return false;return true;}private SencondAnalysisResult(Point point) {this.point = point;}//第三次分析时,对第二次分析结果进行排序,此为排序回调函数@Overridepublic int compareTo(SencondAnalysisResult another) {return compareTowResult(this, another);}}//返加-1则第一个参数优先,1则第二个参数优先,0则按原来顺序private int compareTowResult(SencondAnalysisResult oneResult,SencondAnalysisResult another){if(oneResult.alive4>another.alive4){return -1;}if(oneResult.alive4<another.alive4){return 1;}if(oneResult.halfAlive4>another.halfAlive4){return -1;}if(oneResult.halfAlive4<another.halfAlive4){return 1;}if(oneResult.alive3>another.alive3){return -1;}if(oneResult.alive3<another.alive3){return 1;}if(oneResult.alive2>another.alive2){return -1;}if(oneResult.alive2<another.alive2){return 1;}if(oneResult.halfAlive3>another.halfAlive3){return -1;}if(oneResult.halfAlive3>another.halfAlive3){return 1;}return 0;}//一个临时对象,供第一次分析时临时存放分析结果使用,如果分析出有活1以上(不含)的结果,则调用其cloneMe方法获得结果,否则抛弃此结果private final FirstAnalysisResult far = new FirstAnalysisResult(1, null, HENG);// 分析如果在当前位下一子,会形成某个方向上多少个子,参数:当前己方已下的所有点,当前要假设的点,需要判断的方向private FirstAnalysisResult tryAndCountResult(List<Point> myPoints,List<Point> enemyPoints, Point point,int direction) {int x = point.getX();int y = point.getY();FirstAnalysisResult fr = null;int maxCountOnThisDirection = maxCountOnThisDirection(point, enemyPoints, direction, 1);if(maxCountOnThisDirection<5){//无意义的棋子return null;//此方向不足五个空位,已排除己方已下的棋子}else if(maxCountOnThisDirection==5){//半死状态,当是一头通fr = far.init(point, direction,HALF_ALIVE);}else{//两头皆通fr = far.init(point, direction,ALIVE);}//在前和后的方向上计算一次countPoint(myPoints,enemyPoints,point.setX(x).setY(y),fr,direction,FORWARD);countPoint(myPoints,enemyPoints,point.setX(x).setY(y),fr,direction,BACKWARD);if(fr.count<=1 || (fr.count==2 && fr.aliveState==HALF_ALIVE)){//活1,半活2及其以下结果,抛弃return null;}//返回复制的结果return fr.cloneMe();}//棋子出了墙private boolean isOutSideOfWall(Point point,int direction){if(direction==HENG){return point.getX()<0 || point.getX()>=maxX;//最大的X和Y值均在墙外所以用等号}else if(direction==ZHONG){return point.getY()<0 || point.getY()>=maxY;}else{//这里可能有问题return point.getX()<0 || point.getY()<0 || point.getX()>=maxX || point.getY()>=maxY;}}private Point pointToNext(Point point,int direction,boolean forward){switch (direction) {case HENG:if(forward)point.x++;elsepoint.x--;break;case ZHONG:if(forward)point.y++;elsepoint.y--;break;case ZHENG_XIE:if(forward){point.x++;point.y--;}else{point.x--;point.y++;}break;case FAN_XIE:if(forward){point.x++;point.y++;}else{point.x--;point.y--;}break;}return point;}//在某个方向(八个中的一个)可下多少棋子,这个方法是第一分析中的核心方法private void countPoint(List<Point> myPoints, List<Point> enemyPoints, Point point, FirstAnalysisResult fr,int direction,boolean forward) {if(myPoints.contains(pointToNext(point,direction,forward))){fr.count ++;if(myPoints.contains(pointToNext(point,direction,forward))){fr.count ++;if(myPoints.contains(pointToNext(point,direction,forward))){fr.count ++;if(myPoints.contains(pointToNext(point,direction,forward))){fr.count ++;}else if(enemyPoints.contains(point) || isOutSideOfWall(point,direction)){fr.aliveState=HALF_ALIVE;}}else if(enemyPoints.contains(point) || isOutSideOfWall(point,direction)){fr.aliveState=HALF_ALIVE;}}else if(enemyPoints.contains(point) || isOutSideOfWall(point,direction)){fr.aliveState=HALF_ALIVE;}}else if(enemyPoints.contains(point) || isOutSideOfWall(point,direction)){fr.aliveState=HALF_ALIVE;}}//在某个方向上是否还能下到满五个棋子private int maxCountOnThisDirection(Point point,List<Point> enemyPoints,int direction,int count){int x=point.getX(),y=point.getY();switch (direction) {//横向case HENG:while (!enemyPoints.contains(point.setX(point.getX()-1)) && point.getX()>=0 && count<6) {count ++;}point.setX(x);while (!enemyPoints.contains(point.setX(point.getX()+1)) && point.getX()<maxX && count<6) {count ++;}break;//纵向case ZHONG:while (!enemyPoints.contains(point.setY(point.getY()-1)) && point.getY()>=0) {count ++;}point.setY(y);while (!enemyPoints.contains(point.setY(point.getY()+1)) && point.getY()<maxY && count<6) {count ++;}break;//正斜向 /case ZHENG_XIE:while (!enemyPoints.contains(point.setX(point.getX()-1).setY(point.getY()+1)) && point.getX()>=0 && point.getY()<maxY) {count ++;}point.setX(x).setY(y);while (!enemyPoints.contains(point.setX(point.getX()+1).setY(point.getY()-1)) && point.getX()<maxX && point.getY()>=0 && count<6) {count ++;}break;//反斜 /case FAN_XIE:while (!enemyPoints.contains(point.setX(point.getX()-1).setY(point.getY()-1)) && point.getX()>=0 && point.getY()>=0) {count ++;}point.setX(x).setY(y);while (!enemyPoints.contains(point.setX(point.getX()+1).setY(point.getY()+1)) && point.getX()<maxX && point.getY()<maxY && count<6) {count ++;}break;}return count;}//下棋子,对外接口@Overridepublic void run(List<Point> humans,Point p) {//把人类下的最后一步棋子去除allFreePoints.remove(humans.get(humans.size()-1));//电脑可以下的一步棋子Point result = doAnalysis(myPoints, humans);//去除电脑下的棋子allFreePoints.remove(result);//加入到电脑棋子中,下棋了myPoints.add(result);}}
人类玩家实现起来就非常简单

import java.util.List;public class HumanPlayer extends BasePlayer {@Overridepublic void run(List<Point> enemyPoints,Point p) {getMyPoints().add(p);allFreePoints.remove(p);}}

总结:虽然是Java写的但算法已被抽象可以方便的修改成各种平台的实现。
原创粉丝点击