📄 telent.java
字号:
//本次搜索深度为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 + -