⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chessbot.java

📁 无禁手的五子棋带人工智能
💻 JAVA
字号:
///杨建国:ChessBot.java
// The fivelink bot

import java.math.*;
import java.lang.*;
import java.awt.*;


public class ChessBot
{
	class LinkInfo
	{
		public boolean isLinkN;
		public int isLive[];		//0死链,1半活链,2活链([0]-[3]表横竖左斜右斜)
		public int linknum[];		//([0]死链,[1]半活链,[2]活链)
		LinkInfo()
		{
			isLinkN=false;
			isLive=new int[4];
			linknum=new int[3];
		}
		public String toString()
		{
			String r=new String("isLinkN="+isLinkN+";isLive[0~3]="+isLive[0]+isLive[1]+isLive[2]+isLive[3]+";linknum[0~2]="+linknum[0]+linknum[1]+linknum[2]);
			return r;
		}
		public int getLiveNum()
		{
			int lvn=0;
			for(int i=0;i<4;i++)
				if(isLive[i]==2) lvn++;
			return lvn;
		}
		public int getHLiveNum()
		{
			int lvn=0;
			for(int i=0;i<4;i++)
				if(isLive[i]==1) lvn++;
			return lvn;
		}
		public int getDeathNum()
		{
			int lvn=0;
			for(int i=0;i<4;i++)
				if(isLive[i]==0) lvn++;
			return lvn;
		}
	}
	private int N;				//棋盘边长
	private int HUMAN;			//人下的棋子
	private int BOT;			//机器人下的棋子
	private int NONE;			//没有棋子
	private int isChessOn [][];	//存放棋局
	private int deep;			//递归深度
	private int MAXDEEP;		//最大递归深度
	private int step;			//当前是第几步
	private Point last[];//[0]是敌人,[1]是机器人
	
	ChessBot(int r_n)
	{
		N=r_n;
		HUMAN=1;
		BOT=-1;
		deep=0;
		MAXDEEP=1;
		step=0;
		isChessOn=new int[N][N];
		last=new Point[2];
	}
	public void restart()	//重开一局
	{
		
		HUMAN=1;
		BOT=-1;
		deep=0;
		
		step=0;
		for(int i=0;i<N;i++)
			for(int j=0;j<N;j++)
				isChessOn[i][j]=NONE;
		for(int i=0;i<2;i++)
		{
			last[i].x=0;
			last[i].y=0;
		}
	}
	public void rollback()	//悔棋
	{
		for(int i=0;i<2;i++)
			isChessOn[last[i].x][last[i].y]=NONE;
		step--;
	}
	public Point play(int x,int y)	//机器人走一步棋
	{
		deep=0;
		isChessOn[x][y]=HUMAN;
		
	//	System.out.println("x="+x+"  y="+y+"  isChessOn[x][y]="+isChessOn[x][y]);
		Point r=new Point();
		r=next(BOT);
		isChessOn[r.x][r.y]=BOT;
		step++;
		System.out.println("step "+step+":-----------------------------------------------");
		for(int i=0;i<N;i++,System.out.print("\n"))
			for(int j=0;j<N;j++)
				{
					if(isChessOn[j][i]!=-1)System.out.print(new String(" "+isChessOn[j][i]));
					else	System.out.print(isChessOn[j][i]);
				}
		
		last[0]=new Point(x,y);
		last[1]=new Point(r);
		return r;
	}
	
	public Point playfirst()		//机器人先手
	{
		isChessOn[7][7]=BOT;
		step++;
		last[0]=new Point(7,7);
		last[1]=last[0];
		return new Point(7,7);
	}
	

	private LinkInfo isLinkn(int x,int y,int type,int nn)	//计算当前位置type方是否有nn子相连,相连的情况
	{
		int i=0;
  		int j=0;
  		int i1,j1;
  		int successFactor_v=0;		//横向五子连珠
  		int successFactor_h=0;		//纵向五子连珠
  		int successFactor_l=0;		//左斜线五子连珠
  		int successFactor_r=0;		//右斜线五子连珠
  		int live_v=0;				//空格数
  		int live_h=0;
  		int live_l=0;
  		int live_r=0;
  		int islive1=0;				//计算半死和活的临时变量
  		int islive2=0;
  		boolean isInt=false;				//棋子链是(true)否(false)中断
  		int old=isChessOn[x][y];
  		LinkInfo r=new LinkInfo();
  		isChessOn[x][y]=type;
  		
  		islive1=0;
  		islive2=0;
  		for(i=0,isInt=false;i<5&&(x-i)>=0&&(isChessOn[x-i][y]!=(-1)*type);i++)//横向有几个棋子相连
  		{
  			if(isChessOn[x-i][y]==type&&!isInt) successFactor_v++;
  			if(isChessOn[x-i][y]==NONE)
  			{
  				live_v++;
  				islive1=1;
  				isInt=true;
  			}
  		}
  		
  		for(i=1,isInt=false;i<5+1&&(x+i)<N&&isChessOn[x+i][y]!=(-1)*type;i++)
  		{
  			if(isChessOn[x+i][y]==type&&!isInt) successFactor_v++;
  			if(isChessOn[x+i][y]==NONE)
  			{
  				islive2=1;
  				live_v++;
  				isInt=true;
  			}
  		}
  		r.isLive[0]=islive1+islive2;
  		if(successFactor_v+live_v<5) r.isLive[0]=0;
  		
  	
  		if(successFactor_v>=nn)
  		{
  			r.isLinkN=true;
  			//System.out.println("isLinkN=true is becanse Factor_v="+successFactor_v);
  			r.linknum[r.isLive[0]]++;
  		}
  		
  		
  		islive1=0;
  		islive2=0;
  		for(i=0,isInt=false;i<5&&(y-i)>=0&&(isChessOn[x][y-i]!=(-1)*type);i++)//纵向有几个棋子相连
  		{
  			if(isChessOn[x][y-i]==type&&!isInt) successFactor_h++;
  			if(isChessOn[x][y-i]==NONE)
  			{
  				live_h++;
  				islive1=1;
  				isInt=true;
  			}
  		}
  		
  		for(i=1,isInt=false;i<5+1&&(y+i)<N&&isChessOn[x][y+i]!=(-1)*type;i++)
  		{
  			if(isChessOn[x][y+i]==type&&!isInt) successFactor_h++;
  			if(isChessOn[x][y+i]==NONE)
  			{
  				islive2=1;
  				
  				live_h++;
  				isInt=true;
  			}
  		}
  		r.isLive[1]=islive1+islive2;
  		if(successFactor_h+live_h<5)  r.isLive[1]=0;
  		if(successFactor_h>=nn)
  		{
  			r.isLinkN=true;
  			//System.out.println("isLinkN=true is becanse Factor_h="+successFactor_h);
  			r.linknum[r.isLive[1]]++;
  		}
  		
  		islive1=0;
  		islive2=0;
  		for(i=0,isInt=false;i<5&&(x-i)>=0&&(y+i)<N&&(isChessOn[x-i][y+i]!=(-1)*type);i++)//左斜有几个棋子相连
  		{
  			if(isChessOn[x-i][y+i]==type&&!isInt) successFactor_l++;
  			if(isChessOn[x-i][y+i]==NONE)
  			{
  				live_l++;
  				islive1=1;
  				isInt=true;
  			}
  		}
  		
  		for(i=1,isInt=false;i<5+1&&(x+i)<N&&(y-i)>=0&&isChessOn[x+i][y-i]!=(-1)*type;i++)
  		{
  			if(isChessOn[x+i][y-i]==type&&!isInt) successFactor_l++;
  			if(isChessOn[x+i][y-i]==NONE)
  			{
  				islive2=1;
  				live_l++;
  				isInt=true;
  			}
  		}
  		r.isLive[2]=islive1+islive2;
  		if(successFactor_l+live_l<5)  r.isLive[2]=0;
  		if(successFactor_l>=nn)
  		{
  			r.isLinkN=true;
  		//	System.out.println("isLinkN=true is becanse Factor_l="+successFactor_l);
  			r.linknum[r.isLive[2]]++;
  		}
  		
  		islive1=0;
  		islive2=0;
  		for(i=0,isInt=false;i<5&&(x-i)>=0&&(y-i)>=0&&(isChessOn[x-i][y-i]!=(-1)*type);i++)//右斜有几个棋子相连
  		{
  			if(isChessOn[x-i][y-i]==type&&!isInt) successFactor_r++;
  			if(isChessOn[x-i][y-i]==NONE)
  			{
  				live_r++;
  				islive1=1;
  				isInt=true;
  			}
  		}
  		
  		for(i=1,isInt=false;i<5+1&&(x+i)<N&&(y+i)<N&&isChessOn[x+i][y+i]!=(-1)*type;i++)
  		{
  			if(isChessOn[x+i][y+i]==type&&!isInt) successFactor_r++;
  			if(isChessOn[x+i][y+i]==NONE)
  			{
  				islive2=1;
  				live_r++;
  				isInt=true;
  			}
  		}
  		r.isLive[3]=islive1+islive2;
  		if(successFactor_r+live_r<5)  r.isLive[2]=0;
  		if(successFactor_r>=nn)
  		{
  			r.isLinkN=true;
  			//System.out.println("isLinkN=true is becanse Factor_r="+successFactor_r);
  			r.linknum[r.isLive[3]]++;
  		}
  		
  		isChessOn[x][y]=old;
  		return r;
  	}
	private int haveOneInNGird(int x,int y,int type,int nn)		//当前位置附近能连成一线的子最大有几个
	{
		int i=0;
  		int j=0;
  	
  		int successFactor_v=0;		//横向五子连珠
  		int successFactor_h=0;		//纵向五子连珠
  		int successFactor_l=0;		//左斜线五子连珠
  		int successFactor_r=0;		//右斜线五子连珠
  		int live_v=0;				//空格数
  		int live_h=0;
  		int live_l=0;
  		int live_r=0;
  		
  		
  		int old=isChessOn[x][y];
  		LinkInfo r=new LinkInfo();
  		isChessOn[x][y]=type;
  		
  		
  		for(i=0;i<nn&&(x-i)>=0&&(isChessOn[x-i][y]!=(-1)*type);i++)//横向有几个棋子相连
  		{
  			if(isChessOn[x-i][y]==type) successFactor_v++;
  			if(isChessOn[x-i][y]==NONE)
  			{
  				live_v++;
  			}
  		}
  		
  		for(i=1;i<nn+1&&(x+i)<N&&isChessOn[x+i][y]!=(-1)*type;i++)
  		{
  			if(isChessOn[x+i][y]==type) successFactor_v++;
  			if(isChessOn[x+i][y]==NONE)
  			{
  				live_v++;
  			}
  		}
  		
  	
  		if(successFactor_v+live_v<5)
  		{
  			successFactor_v=0;
  		}
  		
  		
  		for(i=0;i<nn&&(y-i)>=0&&(isChessOn[x][y-i]!=(-1)*type);i++)//纵向有几个棋子相连
  		{
  			if(isChessOn[x][y-i]==type) successFactor_h++;
  			if(isChessOn[x][y-i]==NONE)
  			{
  				live_h++;
  			}
  		}
  		
  		for(i=1;i<nn+1&&(y+i)<N&&isChessOn[x][y+i]!=(-1)*type;i++)
  		{
  			if(isChessOn[x][y+i]==type) successFactor_h++;
  			if(isChessOn[x][y+i]==NONE)
  			{
  				live_h++;
  			}
  		}
  		
  		if(successFactor_h+live_h<5)
  		{
  			successFactor_h=0;
  		}
  		
  		
  		for(i=0;i<nn&&(x-i)>=0&&(y+i)<N&&(isChessOn[x-i][y+i]!=(-1)*type);i++)//左斜有几个棋子相连
  		{
  			if(isChessOn[x-i][y+i]==type) successFactor_l++;
  			if(isChessOn[x-i][y+i]==NONE)
  			{
  				live_l++;
  			}
   		}
  		
  		for(i=1;i<nn+1&&(x+i)<N&&(y-i)>=0&&isChessOn[x+i][y-i]!=(-1)*type;i++)
  		{
  			if(isChessOn[x+i][y-i]==type) successFactor_l++;
  			if(isChessOn[x+i][y-i]==NONE)
  			{
  				live_l++;
  			}
  		}
   		if(successFactor_l+live_l<5)
  		{
  			successFactor_l=0;
  		}
  		
  		
  		for(i=0;i<nn&&(x-i)>=0&&(y-i)>=0&&(isChessOn[x-i][y-i]!=(-1)*type);i++)//右斜有几个棋子相连
  		{
  			if(isChessOn[x-i][y-i]==type) successFactor_r++;
  			if(isChessOn[x-i][y-i]==NONE)
  			{
  				live_r++;
  			}
  		}
  		
  		for(i=1;i<nn+1&&(x+i)<N&&(y+i)<N&&isChessOn[x+i][y+i]!=(-1)*type;i++)
  		{
  			if(isChessOn[x+i][y+i]==type) successFactor_r++;
  			if(isChessOn[x+i][y+i]==NONE)
  			{
  				live_r++;
  			}
  		}
  		if(successFactor_r+live_r<5)  successFactor_r=0;
  		
  		isChessOn[x][y]=old;
  		int max=0;
  		if(successFactor_v>max) max=successFactor_v;
  		if(successFactor_h>max) max=successFactor_h;
  		if(successFactor_l>max) max=successFactor_l;
  		if(successFactor_r>max) max=successFactor_r;
  		return max;
	}
	private boolean isSuccess(int x,int y,int type)		//判断是否胜利
	{
		return isLinkn(x,y,type,5).isLinkN;  		
	}
	public int getPriv(int i,int j,int side)			//获得当前位置的优先权值
	{
		LinkInfo linkinfo=new LinkInfo();
		int link1=0,link2=0;
		int priv=0;
		if(isChessOn[i][j]==NONE)
		{
			
			isChessOn[i][j]=side;
				
			if(isSuccess(i,j,side))		//如果下一步能分出胜负
			{
				priv=50000000;
				link1=5;
			}
			if(isSuccess(i,j,(-1)*side))
			{
				priv=40000000;
				link2=5;
			}
					
			linkinfo=isLinkn(i,j,side,4);
			if(linkinfo.isLinkN&&link1<4)//我能四
			{
				priv+=linkinfo.linknum[1]*150000+linkinfo.linknum[2]*2000000;
				link1=4;
			//	System.out.println("Judge point x="+i+" y="+j);
			//	System.out.println("Aha,I will 4 linked!priv+200,linkinfo:"+linkinfo);
			}
			linkinfo=isLinkn(i,j,(-1)*side,4);
			if(linkinfo.isLinkN&&link2<4)//敌能四
			{
				priv+=linkinfo.linknum[2]*300000;
				if(linkinfo.linknum[1]>1) priv+=15200*linkinfo.linknum[1];
				else priv+=4600*linkinfo.linknum[1];
				link2=4;
			//	System.out.println("Judge point x="+i+" y="+j);
			//	System.out.println("Ohoo,You will 4 linked!priv+70,linkinfo:"+linkinfo);
			}
			linkinfo=isLinkn(i,j,side,3);
			if(linkinfo.isLinkN&&link1<3)//我能三
			{
				priv+=linkinfo.linknum[1]*570+linkinfo.linknum[2]*18600*(step>2?1:0);
				link1=3;
			//	System.out.println("Judge point x="+i+" y="+j);
			//	System.out.println("Aha,I will 3 linked!priv+50,linkinfo:"+linkinfo);
			}
			linkinfo=isLinkn(i,j,(-1)*side,3);
			if(linkinfo.isLinkN&&link2<3)//敌能三
			{
				priv+=linkinfo.linknum[1]*1000+linkinfo.linknum[2]*4650;
				link2=3;
			//	System.out.println("Judge point x="+i+" y="+j);
			//	System.out.println("Ohoo,You will 3 linked!priv+40,linkinfo:"+linkinfo);
			}
			linkinfo=isLinkn(i,j,side,2);
			if(linkinfo.isLinkN&&link1<2)//我能二
			{
				priv+=linkinfo.linknum[1]*20+linkinfo.linknum[2]*1150;
				link1=2;
			//	System.out.println("Judge point x="+i+" y="+j);
			//	System.out.println("Aha,I will 2 linked!priv+20,linkinfo:"+linkinfo);
			}
			linkinfo=isLinkn(i,j,(-1)*side,2);
			if(linkinfo.isLinkN&&link2<2)//敌能二
			{
				priv+=linkinfo.linknum[1]*10+linkinfo.linknum[2]*140;
				link2=2;
			//	System.out.println("Judge point x="+i+" y="+j);
			//	System.out.println("Ohoo,You will 2 linked!priv+20,linkinfo:"+linkinfo);
			}
			int add=haveOneInNGird(i,j,side,5);
			priv+=add*100;
			
		//	System.out.println("Have "+add+" chesses in a line!");
		//	System.out.println("------priv="+priv+"  i="+i+"  j="+j);
					
			isChessOn[i][j]=NONE;
					
		}//endif
		return priv;
				
	}
	private Point next(int side)	//计算机器人下步该走啥
	{
		Point r=new Point();
		LinkInfo linkinfo=new LinkInfo();
		int maxpriv=0;
		for(int i=0;i<N;i++)
		{
			for(int j=0;j<N;j++)
			{
				if(isChessOn[i][j]==NONE)
				{
					int priv=0;
					priv=getPriv(i,j,side);
				//	System.out.println("maxpriv="+maxpriv);
					if(priv>=maxpriv)
					{
						maxpriv=priv;
						r.x=i;
						r.y=j;
												
					}
				}
				
			}//endfor
		}//endfor
		
		return r;
	}//endnext
}//endclass

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -