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

📄 telent.java

📁 这是一个Java编写的手机象棋游戏
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
//本次搜索深度为6;每一步可引起对方的最大变化数为107;

public class Telent
{
	private	int[][]		chess = null;
	private	ChessCanvas	chessCanvas = null;
	private	int[][]	IDS = null;
	private	int[][]	LDS = null;
	//总值number的绝对值超过5000时,则胜负已分
	private	int		number = 0;
	//动棋优先级定义
	private	int		jiangP = 1;
	private	int		bingP = 2;
	private	int		shiP = 3;
	private	int		xiangP = 4;
	private	int		maP = 5;
	private	int		paoP = 6;
	private	int		cheP = 7;
	private	int		guohezuP = 8;
	//分值确定
	private	int		bingN = 10;
	private	int		guhezuN = 20;
	private	int		xiangshiN = 50;
	private	int		paomaN = 150;
	private	int		cheN = 250;
	private	int		jiangN = 10000;
	//**************用到的自定义数据结构
	private int[][]	greenOne ,greenTwo ,greenThree ,redOne ,redTwo ,redThree;
	private	int		greenOneDelY = -1, greenOneDelX = 0, redOneDelY = -1, redOneDelX = 0, greenTwoDelY = -1, greenTwoDelX = 0, redTwoDelY = -1, redTwoDelX = 0, greenThreeDelY = -1, greenThreeDelX = 0;
	//每一步引起对方可能的最大反应数目
	private	final	int	nextNumber = 107;
	
	public Telent(ChessCanvas	cc)
	{
		//这个类中的chess与chesscanvas中chess的数据是否同步?
		chessCanvas = cc;
		updateChess();
		initIDS();
	}
	public void	 delLDS(int code)
	{
		LDS[code][1] = -1;
	}
	public void updateChess()
	{
		LDS = new int[32][3];
		for(int i = 0 ;i < 32 ;i++)
		{
			LDS[i][0] = i;
			LDS[i][1] = -1;
		}
		chess = chessCanvas.getChessState();
		//按照chess里面的值更新LDS
		for(int i = 0;i < 10;i++)
		{
			for(int j = 0;j < 9;j++)
			{
				if(chess[i][j] != 32)
				{
					int tempN = chess[i][j];
					LDS[tempN][1] = i;
					LDS[tempN][2] = j;
					//System.out.println("初始化完成后,LDS里面的数据为code:"+tempN+"y:"+i+"x:"+j);
				}
			}
		}
	}
	public void modifyChess(int m, int n, int y, int x)
	{
		//更新LDS数组
		int c = chess[y][x];
		int d = chess[m][n];
		if(c < 32)
			LDS[c][1] = -1;
		LDS[d][1] = y;
		LDS[d][2] = x;
		//更新chess数组
		chess[y][x] = chess[m][n];
		chess[m][n] = 32;
	}
	public int[] go()
	{//每调用一次该方法,返回三个数据:走棋代号,Y值,X值
		//System.out.println("进入go()方法,开始计算走步");
		updateChess();
		int[]	result = new int[4];
		result[3] = -5000;
		greenOne = new int[nextNumber][4];
		greenTwo = new int[nextNumber][4];
		greenThree = new int[nextNumber][4];
		redOne = new int[nextNumber][4];
		redTwo = new int[nextNumber][4];
		redThree = new int[nextNumber][4];
		//每个数组的长度
		int[][]	tempCollection = null;
		//以下定义的变量均为每个循环内的局部变量
		int numberGreenOne = 0;
		//System.out.println("greeOne:局部变量初始化完成");
		for(int i = 0; i < 16; i++)
		{
			//若该棋子已经不存在,则检查下一个
			if(LDS[i][1] == -1)
				continue;
			//生成greenOne数组
			//System.out.println("greeOne:开始棋子代号为"+LDS[i][0]+"的获取走步集合y:"+LDS[i][1]+",x:"+LDS[i][2]);
			tempCollection = getPath(i, LDS[i][1] ,LDS[i][2]);
			//System.out.println("greeOne:棋子代号为"+LDS[i][0]+"集合获取完毕,得到的数组长度为:"+tempCollection.length);
			for(int j = 0; j < tempCollection.length; j++)
			{
				//System.out.println("greenOne开始存储棋子代号");
				greenOne[numberGreenOne][0] = i;
				//System.out.println("greenOne开始存储坐标");
				greenOne[numberGreenOne][1] = tempCollection[j][0];
				greenOne[numberGreenOne][2] = tempCollection[j][1];
				//System.out.println("greenOne开始获取打分");
				greenOne[numberGreenOne][3] = getNumber(i, tempCollection[j][0] ,tempCollection[j][1]);
				//System.out.println("greeOne:获取打分完成");
				//System.out.println("本次棋子代号为:"+greenOne[numberGreenOne][0]+"获取的坐标数据为:"+"y:"+greenOne[numberGreenOne][1]+"x:"+greenOne[numberGreenOne][2]+"得到的分值为:"+greenOne[numberGreenOne][3]);
				numberGreenOne++;
			}
			//System.out.println("greeOne:*********************获取一次走步集合");
		}
		//System.out.println("greenOne的长度是"+greenOne.length);
		//对greenOne进行排序
		greenOne = sortArray(greenOne, 11);
		greenOne = selectArray(greenOne ,11);
		//System.out.println("greenOne构造完成");
		for(int m = 0; m< greenOne.length; m++)
		{
			//System.out.println("************************************************************************greenOne中,棋子代号为:"+greenOne[m][0]+",y:"+greenOne[m][1]+",x:"+greenOne[m][2]);
			if(m != 0)
				updateChess();
			//棋盘变化反映到chess中去,为getPath()方法服务
			int greenOneCode = greenOne[m][0];
			int greenOneM = LDS[greenOneCode][1];
			int greenOneN = LDS[greenOneCode][2];
			int greenOneY = greenOne[m][1];
			int greenOneX = greenOne[m][2];
			modifyChess(greenOneM, greenOneN, greenOneY, greenOneX);
			int numberRedOne = 0;
			for(int gRedOne = 16; gRedOne < 32; gRedOne++)
			{
				if(LDS[gRedOne][1] == -1)
					continue;
				//System.out.println("greenOne中:开始获取代号为"+LDS[gRedOne][0]+"的棋子的走步集合y:"+LDS[gRedOne][1]+",x:"+LDS[gRedOne][2]);
				tempCollection = getPath(gRedOne, LDS[gRedOne][1] ,LDS[gRedOne][2]);
				//System.out.println("greenOne中:代号为"+LDS[gRedOne][0]+"的棋子的走步集合获取完毕,得到的数组长度为:"+tempCollection.length);
				for(int j = 0; j < tempCollection.length; j++)
				{
					redOne[numberRedOne][0] = gRedOne;
					redOne[numberRedOne][1] = tempCollection[j][0];
					redOne[numberRedOne][2] = tempCollection[j][1];
					redOne[numberRedOne][3] = getNumber(gRedOne, tempCollection[j][0] ,tempCollection[j][1]);
					//System.out.println("本次棋子代号为:"+redOne[numberRedOne][0]+"获取的坐标数据为:"+"y:"+redOne[numberRedOne][1]+"x:"+redOne[numberRedOne][2]+"得到的分值为:"+redOne[numberRedOne][3]);
					numberRedOne++;
				}
			}
			//System.out.println("redOne的长度是"+redOne.length);
			//对redOne进行排序
			redOne = sortArray(redOne, 12);
			redOne = selectArray(redOne ,12);
			//System.out.println("redOne构造完成");
			for(int n = 0; n < redOne.length; n++)
			{
				//System.out.println("********************************************redOne中,棋子为:"+redOne[n][0]+",y:"+redOne[n][1]+",x:"+redOne[n][2]);
				if(n != 0)
				{
					updateChess();
					modifyChess(greenOneM, greenOneN, greenOneY, greenOneX);
				}
				//棋盘变化反映到chess中去,为getPath()方法服务
				int redOneCode = redOne[n][0];
				int redOneM = LDS[redOneCode][1];
				int redOneN = LDS[redOneCode][2];
				int redOneY = redOne[n][1];
				int redOneX = redOne[n][2];
				modifyChess(redOneM, redOneN, redOneY, redOneX);
				int numberGreenTwo = 0;
				for(int gGreenTwo = 0; gGreenTwo < 16; gGreenTwo++)
				{
					if(LDS[gGreenTwo][1] == -1)
						continue;
					//System.out.println("redOne中:开始获取代号为"+LDS[gGreenTwo][0]+"的棋子的走步集合y:"+LDS[gGreenTwo][1]+",x:"+LDS[gGreenTwo][2]);
					tempCollection = getPath(gGreenTwo, LDS[gGreenTwo][1] ,LDS[gGreenTwo][2]);
					//System.out.println("redOne中:代号为"+LDS[gGreenTwo][0]+"的棋子的走步集合获取完毕,得到的数组长度为:"+tempCollection.length);
					for(int j = 0; j < tempCollection.length; j++)
					{
						greenTwo[numberGreenTwo][0] = gGreenTwo;
						greenTwo[numberGreenTwo][1] = tempCollection[j][0];
						greenTwo[numberGreenTwo][2] = tempCollection[j][1];
						greenTwo[numberGreenTwo][3] = getNumber(gGreenTwo, tempCollection[j][0] ,tempCollection[j][1]);
						//System.out.println("本次棋子代号为:"+greenTwo[numberGreenTwo][0]+"获取的坐标为y:"+greenTwo[numberGreenTwo][1]+",x:"+greenTwo[numberGreenTwo][2]);
						numberGreenTwo++;
					}
					//System.out.println("redOne中:代号为"+LDS[gGreenTwo][0]+"的棋子的走步集合已经添加完毕");
				}
				//对进行排序
				//System.out.println("greenTwo的长度是"+greenTwo.length);
				greenTwo = sortArray(greenTwo, 21);
				greenTwo = selectArray(greenTwo, 21);
				//System.out.println("greenTwo构造完成");
				for(int p = 0; p < greenTwo.length; p++)
				{
					//System.out.println("*************greenTwo中,棋子为:"+greenTwo[p][0]+",y:"+greenTwo[p][1]+",x:"+greenTwo[p][2]);
					if(p != 0)
					{
						updateChess();
						modifyChess(greenOneM, greenOneN, greenOneY, greenOneX);
						modifyChess(redOneM, redOneN, redOneY, redOneX);
					}
					//棋盘变化反映到chess中去,为getPath()方法服务
					int greenTwoCode = greenTwo[p][0];
					int greenTwoM = LDS[greenTwoCode][1];
					int greenTwoN = LDS[greenTwoCode][2];
					int greenTwoY = greenTwo[p][1];
					int greenTwoX = greenTwo[p][2];
					//System.out.println("greenTwo中获取坐标变化完毕代号为:"+LDS[greenTwoCode][0]+"m:"+greenTwoM+",n:"+greenTwoN+",y:"+greenTwoY+",x:"+greenTwoX);
					modifyChess(greenTwoM, greenTwoN, greenTwoY, greenTwoX);
					
					int numberRedTwo = 0;
					//System.out.println("为获取一个redTwo而开始进入循环");
					for(int gRedTwo = 16; gRedTwo < 32; gRedTwo++)
					{
						if(LDS[gRedTwo][1] == -1)
							continue;
						//System.out.println("greenTwo中:开始获取代号为"+LDS[gRedTwo][0]+"的棋子的走步集合y:"+LDS[gRedTwo][1]+",x:"+LDS[gRedTwo][2]);
						tempCollection = getPath(gRedTwo, LDS[gRedTwo][1] ,LDS[gRedTwo][2]);
						//System.out.println("greenTwo中:代号为"+LDS[gRedTwo][0]+"的棋子的走步集合获取完毕,得到的数组长度为:"+tempCollection.length);
						for(int j = 0; j < tempCollection.length; j++)
						{
							//System.out.println("将代号"+LDS[gRedTwo][0]+"棋子生成的元素添加进结束数组:y"+tempCollection[j][0]+",x"+tempCollection[j][1]);
							redTwo[numberRedTwo][0] = gRedTwo;
							redTwo[numberRedTwo][1] = tempCollection[j][0];
							redTwo[numberRedTwo][2] = tempCollection[j][1];
							//System.out.println(1);
							redTwo[numberRedTwo][3] = getNumber(gRedTwo, tempCollection[j][0] ,tempCollection[j][1]);
							//System.out.println("本次棋子代号为:"+redTwo[numberRedTwo][0]+"获取的坐标为y:"+redTwo[numberRedTwo][1]+",x:"+redTwo[numberRedTwo][2]);
							numberRedTwo++;
							//System.out.println("此时redTwo中已经有了"+numberRedTwo+"个元素"+redTwo.length);
						}
					}
					//System.out.println("对redTwo进入排序和选择");
					redTwo = sortArray(redTwo, 22);
					//这儿可以不再做选择,直接取数组中的最后一个元素
					redTwo = selectArray(redTwo, 22);
					//System.out.println("获取redTwo完毕");
					int tempResultNumber = greenOne[m][3] - redOne[n][3] + greenTwo[p][3] - redTwo[0][3];
					if(tempResultNumber > result[3])
					{
						result[0] = greenOne[m][0];
						result[1] = greenOne[m][1];
						result[2] = greenOne[m][2];
						result[3] = tempResultNumber;
					}
					redTwo = new int[107][4];
					//更新chess
					updateChess();
				}
				greenTwo = new int[107][4];
				//更新chess
				updateChess();
			}
			redOne = new int[107][4];
			//更新chess
			updateChess();
			//将标识是否有被删了值的变量置为false
		}
		int[] tempResult = new int[4];
		int tempCode = result[0];
		tempResult[0] = LDS[tempCode][1];
		tempResult[1] = LDS[tempCode][2];
		tempResult[2] = result[1];
		tempResult[3] = result[2];
		return tempResult;
	}
	//排序选择部分
	private int[][] sortArray(int[][] array, int flag)
	{
		//一个数组中的数据有四种,一是空;二是得分为-1;三是得分为棋子分值;四是得分为棋子的优先级
		//会被吃子的步得分为-1,会吃子的步得分为吃到的棋子的分值,其他无动作的得分为其优先级
		//初步排序应用堆排序算法,初步排序完成后,数组中的元素按索引由大到小分别为:得分为棋子分值的(吃子的步);得分为棋子优先级的(无动作的步);得分为空的(数组中未填满107时余下的空值);得分为-1的(会被吃子的步)
		if(flag == 22)
		{//如果是redTwo的话,只需将得分最大的一项移到最高的位置
			for(int j = array.length - 2; j >= 0; j--)
			{
				if(array[j][3] > array[array.length - 1][3])
					array[array.length - 1] = array[j];
			}
		}
		else
		{
			//将数组中的空值去掉
			int n = 0;
			for(int j = array.length - 1; j >= 0; j--)
			{
				//除非是空值,否则不可能得分为0!
				if(array[j][3] != 0)
					n++;
					
			}
			int[][] tempArray = new int[n][4];
			int m = 0;
			for(int j = 0; j < array.length; j++)
			{
				if(array[j][3] != 0)
				{
					tempArray[m] = array[j];
					m++;
				}
			}
			array = tempArray;
		}
		if(flag != 22)
		{//如果是redTwo,则不用排序,只需将空值去掉就可以了
			sort(array, 0, array.length - 1);
		}
		return array;
	}
	private	int	partition(int[][] array, int low, int high)
	{
		int[]	tempArray = array[low];
		int		key = array[low][3];
		while(low < high)
		{
			while(low < high && array[high][3] >= key)
				high--;
			array[low] = array[high];
			while(low < high && array[low][3] <= key)
				low++;
			array[high] = array[low];
		}
		array[low] = tempArray;
		return low;
	}
	private void sort(int[][] array, int low, int high)
	{
		if(low < high)
		{
			int midInt = partition(array, low, high);
			sort(array, low, midInt - 1);
			sort(array, midInt + 1, high);
		}
	}
	private	int[][]	selectArray(int[][] array ,int flag)
	{
		int[][] tempArray = null;
		//设定要选出的个数selectNumber,其中每一级都有不同的规定
		int selectNumber = 3;
		if(flag == 11)
		{//因为没有对greenOne进行排序操作,所以必须全部筛选
			selectNumber = 10;
		}
		else if(flag == 12)
		{//筛选redOne
			selectNumber = 5;
		}
		else if(flag == 21)
		{//筛选greenTwo
			selectNumber = 3;
		}
		else//flag == 22
		{//筛选redTwo
			selectNumber = 1;
		}
		//从索引最大的一端开始,选出符合条件的值
		if(selectNumber < array.length)
		{
			tempArray = new int[selectNumber][4];
			for(int j = 0; j < selectNumber; j++)
			{
				tempArray[j] = array[array.length - 1 - j];
			}
		} 
		else
		{
			tempArray = array;
		}
		return tempArray;
	}
	//局面评估函数部分
	private boolean isEating(int code ,int y ,int x)
	{
		//System.out.println("开始进入isEating()方法");
		if(code < 16)
		{
			for(int i = 16; i < 31; i++)
			{
				if(LDS[i][1] != -1)
				{
					if(chessCanvas.check(LDS[i][1], LDS[i][2], y, x, true))
					{
						return true;
					}
				}
			}
		}
		else
		{
			for(int i = 0; i < 16 ; i++)
			{
				if(LDS[i][1] != -1)
				{
					if(chessCanvas.check(LDS[i][1], LDS[i][2], y, x, true))
					{
						return true;
					}
				}
			}
		}
		//System.out.println("isEating()方法执行完毕");
		return false;
	}
	private boolean isEating(int code)
	{
		return isEating(code, LDS[code][1], LDS[code][2]);
	}
	//估值函数部分 
	private int	getNumber(int code, int y, int x)
	{//code为棋子代号,(m,n)为起点,(Y,X)为落脚点,返回走步得分值
		//System.out.println("进入getNumber方法,本次传过来的参数为code:"+code+"y:"+y+"x:"+x);
		int	tempNumber = 0;
		//检测棋子当前是否正处于被吃的状态
		int	allNumber = 0;
		if(isEating(code))
			allNumber = IDS[code][2];
		if(chess[y][x] != 32)
		{//吃棋
			//System.out.println("本步产生吃棋");
			int tempId = chess[y][x];
			tempNumber = IDS[tempId][2] + allNumber;
		}
		else if (isEating(code, y, x))
		{//会被吃
			//System.out.println("本步落脚后,有可能被吃");
			tempNumber = 0 - IDS[code][2] + allNumber;
		}
		else
		{//无动作,按动棋优先级排序,这里赋的值小于10
			//System.out.println("本步走后无动作:"+IDS[code][1]);
			tempNumber = IDS[code][1] + allNumber;
			//System.out.println("赋值得分完毕");
		}
		//System.out.println("getNumber()方法完成退出");
		return tempNumber;
	}
	//走法产生器
	private int[][] getPath(int	code,int	y,int	x)
	{
		int[][]	tempCollection = null;
		//将走步集合
		if(code == 0 || code == 16)
		{
			//System.out.println("开始获取将走步集合,传过来的参数是code:"+code+"y:"+y+"x:"+x);
			int[][]	a = null;
			int		n = 0;
			if(code == 16)
			{
				if(x == 3)
				{
					if(y == 7)
					{
						a = new int[2][2];
						a[0][0] = 7;
						a[0][1] = 4;

⌨️ 快捷键说明

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