Java实现五子棋AI算法
五子棋AI算法也算是一个典型的游戏AI算法,一些棋类的AI算法都可以参考实现,下面是Java实现代码
棋盘抽象接口
importjava.util.List;
publicinterfaceIChessboard{
//取得棋盘最大横坐标
publicintgetMaxX();
//最大纵坐标
publicintgetMaxY();
//取得当前所有空白点,这些点才可以下棋
publicListgetFreePoints();
}
棋子类实现
//棋子类
publicclassPoint{
//这了性能,设成公有
publicintx;
publicinty;
publicintgetX(){
returnx;
}
publicPointsetX(intx){
this.x=x;
returnthis;
}
publicintgetY(){
returny;
}
publicPointsetY(inty){
this.y=y;
returnthis;
}
publicPoint(intx,inty){
this.x=x;
this.y=y;
}
@Override
publicinthashCode(){
returnx+y;
}
@Override
publicbooleanequals(Objectobj){
if(this==obj)
returntrue;
Pointother=(Point)obj;
if(x!=other.x)
returnfalse;
if(y!=other.y)
returnfalse;
returntrue;
}
}
玩家抽象接口
importjava.util.List;
publicinterfaceIPlayer{
//下一步棋子,传入对手已经下的棋子集合
publicvoidrun(ListenemyPoints,Pointpoint);
publicbooleanhasWin();
publicvoidsetChessboard(IChessboardchessboard);
publicListgetMyPoints();
}
玩家基础抽象类
importjava.util.ArrayList;
importjava.util.List;
publicabstractclassBasePlayerimplementsIPlayer{
//我已下的棋子
protectedListmyPoints=newArrayList(200);
//棋盘
protectedIChessboardchessboard;
//棋盘最大横坐标和纵标,
protectedintmaxX;
protectedintmaxY;
//所有空白棋子
protectedListallFreePoints;
@Override
publicfinalListgetMyPoints(){
returnmyPoints;
}
@Override
publicvoidsetChessboard(IChessboardchessboard){
this.chessboard=chessboard;
allFreePoints=chessboard.getFreePoints();
maxX=chessboard.getMaxX();
maxY=chessboard.getMaxY();
myPoints.clear();
}
privatefinalPointtemp=newPoint(0,0);
//我是否是否赢了
publicfinalbooleanhasWin(){
if(myPoints.size()<5){
returnfalse;
}
Pointpoint=myPoints.get(myPoints.size()-1);
intcount=1;
intx=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){
returntrue;
}
temp.setX(x).setY(y);
while(myPoints.contains(temp.setX(temp.getX()+1))&&temp.getX()=5){
returntrue;
}
//纵向|
count=1;
temp.setX(x).setY(y);
while(myPoints.contains(temp.setY(temp.getY()-1))&&temp.getY()>=0){
count++;
}
if(count>=5){
returntrue;
}
temp.setX(x).setY(y);
while(myPoints.contains(temp.setY(temp.getY()+1))&&temp.getY()=5){
returntrue;
}
//正斜向/
count=1;
temp.setX(x).setY(y);
while(myPoints.contains(temp.setX(temp.getX()-1).setY(temp.getY()+1))&&temp.getX()>=0&&temp.getY()=5){
returntrue;
}
temp.setX(x).setY(y);
while(myPoints.contains(temp.setX(temp.getX()+1).setY(temp.getY()-1))&&temp.getX()=0&&count<6){
count++;
}
if(count>=5){
returntrue;
}
//反斜\
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){
returntrue;
}
temp.setX(x).setY(y);
while(myPoints.contains(temp.setX(temp.getX()+1).setY(temp.getY()+1))&&temp.getX()=5){
returntrue;
}
returnfalse;
}
}
电脑AI类实现
importjava.util.ArrayList;
importjava.util.Collections;
importjava.util.HashMap;
importjava.util.List;
importjava.util.Map;
//算法核心类,算法的主体思想分三个步骤,
//第一步:根据双方的当前的形势循环地假设性的分别给自己和对方下一子(在某个范围内下子),并判断此棋子能带来的形势上的变化,如能不能冲4,能不能形成我方或敌方双3等,
//第二步:根据上一步结果,组合每一步棋子所带来的所有结果(如某一步棋子可能形成我方1个活3,1个冲4(我叫它半活4)等),包括敌方和我方的。
//第三步:根据用户给的规则对上一步结果进行排序,并选子(有进攻形、防守形规则)
publicclassBaseComputerAiextendsBasePlayer{
//四个方向,横-、纵|、正斜/、反斜\
privatestaticfinalintHENG=0;
privatestaticfinalintZHONG=1;
privatestaticfinalintZHENG_XIE=2;
privatestaticfinalintFAN_XIE=3;
//往前往后
privatestaticfinalbooleanFORWARD=true;
privatestaticfinalbooleanBACKWARD=false;
//标示分析结果当前点位是两头通(ALIVE)还是只有一头通(HALF_ALIVE),封死的棋子分析过程自动屏蔽,不作为待选棋子
privatestaticfinalintALIVE=1;
privatestaticfinalintHALF_ALIVE=0;
//privatestaticfinalintDEAD=-1;
//计算范围,太大的范围会有性能问题
privateclassCalcuteRange{
intxStart,yStart,xStop,yStop;
privateCalcuteRange(intxStart,intyStart,intxStop,intyStop){
this.xStart=xStart;
this.yStart=yStart;
this.xStop=xStop;
this.yStop=yStop;
}
}
//限定电脑计算范围,如果整个棋盘计算,性能太差,目前是根据所有已下的棋子的边界值加RANGE_STEP值形成,目前为1
privatestaticfinalintRANGE_STEP=1;
CalcuteRangecurrentRange=newCalcuteRange(0,0,0,0);
privatevoidinitRange(Listcomuters,Listhumans){
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(Pointpoint:humans){
if(point.getX()-RANGE_STEPcurrentRange.xStop){
currentRange.xStop=point.getX()+RANGE_STEP;
}
if(point.getY()-RANGE_STEPcurrentRange.yStop){
currentRange.yStop=point.getY()+RANGE_STEP;
}
}
for(Pointpoint:comuters){
if(point.getX()-RANGE_STEPcurrentRange.xStop){
currentRange.xStop=point.getX()+RANGE_STEP;
}
if(point.getY()-RANGE_STEPcurrentRange.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;
}
//分析当前形式的入口方法,分析总共分三个步骤,第三步骤可由子类干预以作难度控制
privatePointdoAnalysis(Listcomuters,Listhumans){
if(humans.size()==1){//第一步
returngetFirstPoint(humans);
}
//初始化计算范围
initRange(comuters,humans);
//清除以前的结果
initAnalysisResults();
//开始分析,扫描所有空白点,形成第一次分析结果
PointbestPoint=doFirstAnalysis(comuters,humans);
if(bestPoint!=null){
//System.out.println("这个棋子最重要,只能下这个棋子");
returnbestPoint;
}
//分析第一次结果,找到自己的最佳点位
bestPoint=doComputerSencondAnalysis(computerFirstResults,computerSencodResults);
if(bestPoint!=null){
//System.out.println("快要赢了,就下这个棋子");
returnbestPoint;
}
computerFirstResults.clear();
System.gc();
//分析第一次结果,找到敌人的最佳点位
bestPoint=doHumanSencondAnalysis(humanFirstResults,humanSencodResults);
if(bestPoint!=null){
//System.out.println("再不下这个棋子就输了");
returnbestPoint;
}
humanFirstResults.clear();
System.gc();
//没找到绝杀点,第三次结果分析
returndoThirdAnalysis();
}
//下第一步棋子,不需要复杂的计算,根据人类第一步棋子X值减1完成
privatePointgetFirstPoint(Listhumans){
Pointpoint=humans.get(0);
if(point.getX()==0||point.getY()==0||point.getX()==maxX&&point.getY()==maxY)
returnnewPoint(maxX/2,maxY/2);
else{
returnnewPoint(point.getX()-1,point.getY());
}
}
//privateintdebugx,debugy;//用于DEBUG
//开始分析,扫描所有空白点,形成第一次分析结果
privatePointdoFirstAnalysis(Listcomuters,Listhumans){
intsize=allFreePoints.size();
PointcomputerPoint=null;
PointhumanPoint=null;
intx,y;
FirstAnalysisResultfirstAnalysisResult;
for(inti=0;icurrentRange.xStop||ycurrentRange.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个,胜利了,不再往下进行分析
returncomputerPoint;
//记录第一次分析结果
addToFirstAnalysisResult(firstAnalysisResult,computerFirstResults);
}
//在“纵向”这个方向上重复上面的步骤
firstAnalysisResult=tryAndCountResult(comuters,humans,computerPoint,ZHONG);
computerPoint.setX(x).setY(y);
if(firstAnalysisResult!=null){//死棋,不下
if(firstAnalysisResult.count==5)
returncomputerPoint;
addToFirstAnalysisResult(firstAnalysisResult,computerFirstResults);
}
//正斜向
firstAnalysisResult=tryAndCountResult(comuters,humans,computerPoint,ZHENG_XIE);
computerPoint.setX(x).setY(y);
if(firstAnalysisResult!=null){//死棋,不下
if(firstAnalysisResult.count==5)
returncomputerPoint;
addToFirstAnalysisResult(firstAnalysisResult,computerFirstResults);
}
//反斜向
firstAnalysisResult=tryAndCountResult(comuters,humans,computerPoint,FAN_XIE);
computerPoint.setX(x).setY(y);
if(firstAnalysisResult!=null){//死棋,不下
if(firstAnalysisResult.count==5)
returncomputerPoint;
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);
}
}
//如果没有绝杀棋子,第一次分析不需要返回结果
returnhumanPoint;
}
//第二次分析,分析第一次形成的结果,第一次分析结果会把一步棋在四个方向上可形成的结果生成最多四个FirstAnalysisResult对象(敌我各四)
//这里要把这四个对象组合成一个SencondAnalysisResult对象,
privatePointdoComputerSencondAnalysis(Map>firstResults,ListsencodResults){
Listlist=null;
SencondAnalysisResultsr=null;
for(Pointp:firstResults.keySet()){
sr=newSencondAnalysisResult(p);
list=firstResults.get(p);
for(FirstAnalysisResultresult:list){
if(result.count==4){
if(result.aliveState==ALIVE){//经过前面的过滤,双方都排除了绝杀棋,有活4就下这一步了,再下一步就赢了
returnresult.point;//如果有绝杀,第一轮已返回,在此轮活4已经是好的棋子,直接返回,不再往下分析
}else{
sr.halfAlive4++;
computer4HalfAlives.add(sr);
}
}elseif(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);
}
//没有找到活4
returnnull;
}
//这个方法和上面的基本一样,但为了性能,少作几次判断,将人类和电脑的分开了
privatePointdoHumanSencondAnalysis(Map>firstResults,ListsencodResults){
Listlist=null;
SencondAnalysisResultsr=null;
for(Pointp:firstResults.keySet()){
sr=newSencondAnalysisResult(p);
list=firstResults.get(p);
for(FirstAnalysisResultresult:list){
if(result.count==4){
if(result.aliveState==ALIVE){
human4Alives.add(sr);
}else{
sr.halfAlive4++;
human4HalfAlives.add(sr);
}
}elseif(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);
}
//没有找到活4
returnnull;
}
privatevoidsleep(intminiSecond){
try{
Thread.sleep(miniSecond);
}catch(InterruptedExceptione){
}
}
//第三次分析,双方都不可以制造活4,找双活3棋子,不行就找半活4,再不行就找单活3,双活2
privatePointdoThirdAnalysis(){
if(!computer4HalfAlives.isEmpty()){
returncomputer4HalfAlives.get(0).point;
}
System.gc();
sleep(300);
Collections.sort(computerSencodResults);
System.gc();
//即将单活4,且我没有半活4以上的,只能堵
PointmostBest=getBestPoint(human4Alives,computerSencodResults);
if(mostBest!=null)
returnmostBest;
Collections.sort(humanSencodResults);
System.gc();
mostBest=getBestPoint();
if(mostBest!=null)
returnmostBest;
//拿出各自排第一的,谁好就下谁
returncomputerSencodResults.get(0).point;
}
//子类实现这个方法,并改变其顺序可以实现防守为主还是猛攻
protectedPointgetBestPoint(){
//即将单活4,且我没有半活4以上的,只能堵
PointmostBest=getBestPoint(computerDouble3Alives,humanSencodResults);
if(mostBest!=null)
returnmostBest;
mostBest=getBestPoint(computer3Alives,humanSencodResults);
if(mostBest!=null)
returnmostBest;
mostBest=getBestPoint(humanDouble3Alives,computerSencodResults);
if(mostBest!=null)
returnmostBest;
mostBest=getBestPoint(human3Alives,computerSencodResults);
if(mostBest!=null)
returnmostBest;
mostBest=getBestPoint(computerDouble2Alives,humanSencodResults);
if(mostBest!=null)
returnmostBest;
mostBest=getBestPoint(computer2Alives,humanSencodResults);
if(mostBest!=null)
returnmostBest;
mostBest=getBestPoint(computer3HalfAlives,humanSencodResults);
if(mostBest!=null)
returnmostBest;
mostBest=getBestPoint(human4HalfAlives,computerSencodResults);
if(mostBest!=null)
returnmostBest;
mostBest=getBestPoint(humanDouble2Alives,computerSencodResults);
if(mostBest!=null)
returnmostBest;
mostBest=getBestPoint(human2Alives,computerSencodResults);
if(mostBest!=null)
returnmostBest;
mostBest=getBestPoint(human3HalfAlives,computerSencodResults);
returnmostBest;
}
//第三次分析的最后一步,第二次结果已经过排序,在此可以从前面选出最好的棋子
protectedPointgetBestPoint(ListmyBest,ListyourSencodResults){
if(!myBest.isEmpty()){
if(myBest.size()>1){
for(SencondAnalysisResultyour:yourSencodResults){
if(myBest.contains(your)){
returnyour.point;
}
}
returnmyBest.get(0).point;
}else{
returnmyBest.get(0).point;
}
}
returnnull;
}
//第一次分析结果
privatefinalMap>computerFirstResults=newHashMap>();
privatefinalMap>humanFirstResults=newHashMap>();
//第二次总结果
protectedfinalListcomputerSencodResults=newArrayList();
protectedfinalListhumanSencodResults=newArrayList();
//第二次分结果,电脑
protectedfinalListcomputer4HalfAlives=newArrayList(2);
protectedfinalListcomputerDouble3Alives=newArrayList(4);
protectedfinalListcomputer3Alives=newArrayList(5);
protectedfinalListcomputerDouble2Alives=newArrayList();
protectedfinalListcomputer2Alives=newArrayList();
protectedfinalListcomputer3HalfAlives=newArrayList();
//第二次分结果,人类
protectedfinalListhuman4Alives=newArrayList(2);
protectedfinalListhuman4HalfAlives=newArrayList(5);
protectedfinalListhumanDouble3Alives=newArrayList(2);
protectedfinalListhuman3Alives=newArrayList(10);
protectedfinalListhumanDouble2Alives=newArrayList(3);
protectedfinalListhuman2Alives=newArrayList();
protectedfinalListhuman3HalfAlives=newArrayList();
//第一次分析前清空上一步棋子的分析结果
privatevoidinitAnalysisResults(){
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();
}
//加入到第一次分析结果中
privatevoidaddToFirstAnalysisResult(FirstAnalysisResultresult,Map>dest){
if(dest.containsKey(result.point)){
dest.get(result.point).add(result);
}else{
Listlist=newArrayList(1);
list.add(result);
dest.put(result.point,list);
}
}
//第一次分析结果类
privateclassFirstAnalysisResult{
//连续数
intcount;
//点位
Pointpoint;
//方向
intdirection;
//状态
intaliveState;
privateFirstAnalysisResult(intcount,Pointpoint,intdirection){
this(count,point,direction,ALIVE);
}
privateFirstAnalysisResult(intcount,Pointpoint,intdirection,intaliveState){
this.count=count;
this.point=point;
this.direction=direction;
this.aliveState=aliveState;
}
privateFirstAnalysisResultinit(Pointpoint,intdirection,intaliveState){
this.count=1;
this.point=point;
this.direction=direction;
this.aliveState=aliveState;
returnthis;
}
privateFirstAnalysisResultcloneMe(){
returnnewFirstAnalysisResult(count,point,direction,aliveState);
}
}
//第二次分析结果类
classSencondAnalysisResultimplementsComparable{
intalive4=0;
//活3数量
intalive3=0;
//半活4,一头封的
inthalfAlive4=0;
//半活3,一头封的
inthalfAlive3=0;
//活2数量
intalive2=0;
//点位
Pointpoint;
@Override
publicinthashCode(){
finalintprime=31;
intresult=1;
result=prime*result+((point==null)?0:point.hashCode());
returnresult;
}
@Override
publicbooleanequals(Objectobj){
SencondAnalysisResultother=(SencondAnalysisResult)obj;
if(point==null){
if(other.point!=null)
returnfalse;
}elseif(!point.equals(other.point))
returnfalse;
returntrue;
}
privateSencondAnalysisResult(Pointpoint){
this.point=point;
}
//第三次分析时,对第二次分析结果进行排序,此为排序回调函数
@Override
publicintcompareTo(SencondAnalysisResultanother){
returncompareTowResult(this,another);
}
}
//返加-1则第一个参数优先,1则第二个参数优先,0则按原来顺序
privateintcompareTowResult(SencondAnalysisResultoneResult,SencondAnalysisResultanother){
if(oneResult.alive4>another.alive4){
return-1;
}
if(oneResult.alive4another.halfAlive4){
return-1;
}
if(oneResult.halfAlive4another.alive3){
return-1;
}
if(oneResult.alive3another.alive2){
return-1;
}
if(oneResult.alive2another.halfAlive3){
return-1;
}
if(oneResult.halfAlive3>another.halfAlive3){
return1;
}
return0;
}
//一个临时对象,供第一次分析时临时存放分析结果使用,如果分析出有活1以上(不含)的结果,则调用其cloneMe方法获得结果,否则抛弃此结果
privatefinalFirstAnalysisResultfar=newFirstAnalysisResult(1,null,HENG);
//分析如果在当前位下一子,会形成某个方向上多少个子,参数:当前己方已下的所有点,当前要假设的点,需要判断的方向
privateFirstAnalysisResulttryAndCountResult(ListmyPoints,ListenemyPoints,Pointpoint,intdirection){
intx=point.getX();
inty=point.getY();
FirstAnalysisResultfr=null;
intmaxCountOnThisDirection=maxCountOnThisDirection(point,enemyPoints,direction,1);
if(maxCountOnThisDirection<5){
//无意义的棋子
returnnull;//此方向不足五个空位,已排除己方已下的棋子
}elseif(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及其以下结果,抛弃
returnnull;
}
//返回复制的结果
returnfr.cloneMe();
}
//棋子出了墙
privatebooleanisOutSideOfWall(Pointpoint,intdirection){
if(direction==HENG){
returnpoint.getX()<0||point.getX()>=maxX;//最大的X和Y值均在墙外所以用等号
}elseif(direction==ZHONG){
returnpoint.getY()<0||point.getY()>=maxY;
}else{//这里可能有问题
returnpoint.getX()<0||point.getY()<0||point.getX()>=maxX||point.getY()>=maxY;
}
}
privatePointpointToNext(Pointpoint,intdirection,booleanforward){
switch(direction){
caseHENG:
if(forward)
point.x++;
else
point.x--;
break;
caseZHONG:
if(forward)
point.y++;
else
point.y--;
break;
caseZHENG_XIE:
if(forward){
point.x++;
point.y--;
}else{
point.x--;
point.y++;
}
break;
caseFAN_XIE:
if(forward){
point.x++;
point.y++;
}else{
point.x--;
point.y--;
}
break;
}
returnpoint;
}
//在某个方向(八个中的一个)可下多少棋子,这个方法是第一分析中的核心方法
privatevoidcountPoint(ListmyPoints,ListenemyPoints,Pointpoint,FirstAnalysisResultfr,intdirection,booleanforward){
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++;
}elseif(enemyPoints.contains(point)||isOutSideOfWall(point,direction)){
fr.aliveState=HALF_ALIVE;
}
}elseif(enemyPoints.contains(point)||isOutSideOfWall(point,direction)){
fr.aliveState=HALF_ALIVE;
}
}elseif(enemyPoints.contains(point)||isOutSideOfWall(point,direction)){
fr.aliveState=HALF_ALIVE;
}
}elseif(enemyPoints.contains(point)||isOutSideOfWall(point,direction)){
fr.aliveState=HALF_ALIVE;
}
}
//在某个方向上是否还能下到满五个棋子
privateintmaxCountOnThisDirection(Pointpoint,ListenemyPoints,intdirection,intcount){
intx=point.getX(),y=point.getY();
switch(direction){
//横向
caseHENG:
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()=0){
count++;
}
point.setY(y);
while(!enemyPoints.contains(point.setY(point.getY()+1))&&point.getY()=0&&point.getY()=0&&count<6){
count++;
}
break;
//反斜/
caseFAN_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()humans,Pointp){
//把人类下的最后一步棋子去除
allFreePoints.remove(humans.get(humans.size()-1));
//电脑可以下的一步棋子
Pointresult=doAnalysis(myPoints,humans);
//去除电脑下的棋子
allFreePoints.remove(result);
//加入到电脑棋子中,下棋了
myPoints.add(result);
}
}
人类玩家实现起来就非常简单
importjava.util.List;
publicclassHumanPlayerextendsBasePlayer{
@Override
publicvoidrun(ListenemyPoints,Pointp){
getMyPoints().add(p);
allFreePoints.remove(p);
}
}
总结:虽然是Java写的但算法已被抽象可以方便的修改成各种平台的实现。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。