📄 evaluation.java
字号:
/**
*
* This class evaluates the situation of the board
*
*/
class Evaluation
{
int size;
static final int sTwo = 0;
static final int sThree = 1;
static final int sFour = 2;
static final int two = 3;
static final int three= 4;
static final int four = 5;
static final int five = 6;
//array records the count of the above kind
int[] blackTypeCount = new int[8];
int[] whiteTypeCount = new int[8];
//the two dimension array records the position weight
public static int[][] posValue;
/**
*
* @param mapSize the size of the board
*/
Evaluation(int mapSize)
{
size = mapSize;
posValue = new int[mapSize][mapSize];
//initialize the position weight
int edge = size - 1;
for(int i = 0; i < size; i++)
for(int j = 0; j < size; j++)
{
int a = (i > edge - i)?(edge - i):i;
int b = (j > edge - j)?(edge - j):j;
posValue[i][j] = (a > b)?b:a;
}
return;
}
/**
*This method evaluate the board and return a score, if it's a white turn, it'll return
*-score, else return score. score will be large if the situation is better for the black
*and vice versa
*
* @param board the board information
* @param isWhiteTurn whether the next turn is white
* @return the score of the board
*/
int evaluate(ChessMan[][] board, boolean isWhiteTurn)
{
for(int i = 0; i < 8; i++)
{
blackTypeCount[i] = 0;
whiteTypeCount[i] = 0;
}
this.analysisBoard(board);
int score = 0;
//多个冲四相当与一个活四
if (whiteTypeCount[sFour] > 1)
whiteTypeCount[four]++;
if (blackTypeCount[sFour] > 1)
blackTypeCount[four]++;
//computes the white value and the black value
int WValue = 0, BValue = 0;
if (isWhiteTurn)
{
if (blackTypeCount[five] > 0)
{
BValue = 9999;
}
else if (whiteTypeCount[five] > 0)
{
WValue = 9999;
}
//white wins
else if (whiteTypeCount[four] > 0 || whiteTypeCount[sFour] > 0)
{
WValue = 9990;
}
//black wins
else if (blackTypeCount[four] > 0)
{
BValue = 9970;
}
//black wins
else if (blackTypeCount[sFour] > 0 && blackTypeCount[three] > 0)
{
BValue = 9960;
}
//white wins
else if (whiteTypeCount[three] > 0 && blackTypeCount[sFour] == 0)
{
WValue = 9950;
}
//black wins
else if (blackTypeCount[three] > 1 &&
whiteTypeCount[three] == 0 &&
whiteTypeCount[sThree] == 0)
{
BValue = 9940;
}
else {
//calculates the respective value of black and white
if (whiteTypeCount[three] > 1)
WValue += 2000;
else
{
if (whiteTypeCount[three] > 0)
WValue += 200;
}
if (blackTypeCount[three] > 1)
BValue += 1000;
else
{
if (blackTypeCount[three] > 0)
BValue += 100;
}
if (whiteTypeCount[sThree] > 0)
WValue += whiteTypeCount[sThree]*10;
if (blackTypeCount[sThree] > 0)
BValue += blackTypeCount[sThree]*10;
if (whiteTypeCount[two] > 0)
WValue += whiteTypeCount[two]*4;
if (blackTypeCount[two] > 0)
BValue += blackTypeCount[two]*4;
if (whiteTypeCount[sTwo] > 0)
WValue += whiteTypeCount[sTwo];
if (blackTypeCount[sTwo] > 0)
BValue += blackTypeCount[sTwo];
}
}
else
{
//the following is similar to the above
if (whiteTypeCount[five] > 0)
{
WValue = 9999;
}
else if(blackTypeCount[five] > 0)
{
BValue = 9999;
}
else if (blackTypeCount[four] > 0 || blackTypeCount[sFour] > 0)
{
BValue = 9990;
}
else if (whiteTypeCount[four] > 0)
{
WValue = 9970;
}
else if (whiteTypeCount[sFour] > 0 && whiteTypeCount[three] > 0)
{
WValue = 9960;
}
else if (blackTypeCount[three] > 0 && whiteTypeCount[sFour] == 0)
{
BValue = 9950;
}
else if (whiteTypeCount[three] > 1 &&
blackTypeCount[three] == 0 &&
blackTypeCount[sThree] == 0)
{
WValue = 9940;
}
else {
if (blackTypeCount[three] > 1)
BValue += 2000;
else{
if (blackTypeCount[three] > 0)
BValue += 200;
}
if (whiteTypeCount[three] > 1)
WValue += 1000;
else{
if (whiteTypeCount[three] > 0)
WValue += 100;
}
if (whiteTypeCount[sThree] > 0)
WValue += whiteTypeCount[sThree]*10;
if (blackTypeCount[sThree] > 0)
BValue += blackTypeCount[sThree]*10;
if (whiteTypeCount[two] > 0)
WValue += whiteTypeCount[two]*4;
if (blackTypeCount[two] > 0)
BValue += blackTypeCount[two]*4;
if (whiteTypeCount[sTwo] > 0)
WValue += whiteTypeCount[sTwo];
if (blackTypeCount[sTwo] > 0)
BValue += blackTypeCount[sTwo];
}
}
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
{
ChessMan tmp = board[i][j];
if (tmp != ChessMan.Empty)
{
if (tmp == ChessMan.Black)
BValue += posValue[i][j];
else
WValue += posValue[i][j];
}
}
score = BValue - WValue;
return score;
}
/**
* this method analysis the board and find out the FIVEs, FOURs and THREEs and etc
*
* @param board the board to be analysised
*/
void analysisBoard(ChessMan[][] board)
{
ChessMan[] line = new ChessMan[size];
//the horizontal direction
for(int i = 0; i < size; i++)
analysisLine(board[i], size);
/* System.out.println("水平");
for(int i = 0; i < 8; i++)
System.out.print(blackTypeCount[i] + " ");
System.out.println();
for(int i = 0; i < 8; i++)
System.out.print(whiteTypeCount[i] + " ");
System.out.println();*/
//the vertical direction
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size; j++)
line[j] = board[j][i];
analysisLine(line, size);
}
/* System.out.println();
for(int i = 0; i < 8; i++)
System.out.print(blackTypeCount[i] + " ");
System.out.println("竖直");
for(int i = 0; i < 8; i++)
System.out.print(whiteTypeCount[i] + " ");
System.out.println();*/
//the north east direction
for(int k = 0; k <= 2 * size - 2; k++)
{
int n = 0;
for(int i = 0; i <= k; i++)
{
int j = k - i;
if(j >= size || i >= size)
continue;
line[n++] = board[i][j];
}
analysisLine(line, size);
}
/* System.out.println("右上");
for(int i = 0; i < 8; i++)
System.out.print(blackTypeCount[i] + " ");
System.out.println();
for(int i = 0; i < 8; i++)
System.out.print(whiteTypeCount[i] + " ");
System.out.println();
*/
//the north west direction
for(int k = 0; k < size; k++)
{
int n = 0;
for(int i = 0; i < size - k; i++)
{
line[n++] = board[i][i + k];
}
analysisLine(line, n);
}
for(int k = 1; k < size; k++)
{
int n = 0;
for(int i = k; i < size; i++)
{
line[n++] = board[i][i - k];
}
analysisLine(line, n);
}
/* System.out.println("右下");
for(int i = 0; i < 8; i++)
System.out.print(blackTypeCount[i] + " ");
System.out.println();
for(int i = 0; i < 8; i++)
System.out.print(whiteTypeCount[i] + " ");
*/
}
/**
* this method analysis one line, and finds out how many FIVEs FOURs THREEs of each side
*
* @param line array stores the line
* @param end the length of the array
*/
void analysisLine(ChessMan[] line, int end)
{
int i = 0;
int j = 0;
int k = 0;
int bitLine = 0;
ChessMan oldChess = ChessMan.Empty;
ChessMan lastChess = ChessMan.Empty;
//divide this line into several segments of different chess color
//and analysis them respectively
while(i < end)
{
ChessMan curChess = line[i];
boolean isOldEmpty = (oldChess == ChessMan.Empty);
boolean isCurEmpty = (curChess == ChessMan.Empty);
boolean isCurEqOld = (oldChess == curChess);
//finds out the latest change in chess
if(!isOldEmpty && curChess != lastChess && lastChess == oldChess)
{
k = i;
//System.out.println("k:" + k);
}
if(!isCurEmpty)
bitLine |= 1<<i;
if(isOldEmpty)
{
if(!isCurEmpty)
oldChess = curChess;
}
else if(!isCurEqOld && !isCurEmpty)
{
analysisChess(bitLine, j, i, oldChess);
oldChess = curChess;
j = k;
}
lastChess = curChess;
i++;
}
//analysis the last segment
analysisChess(bitLine, j, size, oldChess);
}
/**
* this method uses bit comparison to find how many FIVEs FOURs THREEs TWOs in a single
* segment
*
* @param bitLine one integer value records the bit information of the segment
* @param start the start bit number
* @param end the end bit number
* @param c the chess color the this segment
*/
void analysisChess(int bitLine, int start, int end, ChessMan c)
{
//System.out.println("start:" + start + " end:" + end + " Line:" + bitLine);
int length = end - start;
if(length < 5)
return;
int line = bitLine >> start;
int[] typeCount;
//System.out.println("line:" + line);
if(c == ChessMan.Black)
typeCount = blackTypeCount;
else
typeCount = whiteTypeCount;
int tmpLine = line;
for(int i = 0; i <= length - 5; i++)
{
int tmp = tmpLine & 0x1f;
//System.out.println("tmp:" + tmp);
switch(tmp)
{
//五连11111b
case 0x1f: typeCount[five]++; return;
//冲四11011b
case 0x1b: typeCount[sFour]++; break;
//眠三10011b, 10101b, 11001b
case 0x13: case 0x15: case 0x19: typeCount[sThree]++; break;
//眠二10001
case 0x11: typeCount[sTwo]++; break;
default: break;
}
tmpLine >>= 1;
}
tmpLine = line;
for(int i = 0; i <= length - 6; i++)
{
int tmp = tmpLine & 0x3f;
//System.out.println("tmp:" + tmp);
switch(tmp)
{
//活四011110b
case 0x1e: typeCount[four]++; break;
//活三011010b, 010110b
case 0x1a: case 0x16: typeCount[three]++; break;
//活二010010b, 001100b
case 0x12: case 0xc: typeCount[two]++; break;
default: break;
}
tmpLine >>= 1;
}
tmpLine = line;
for(int i = 0; i <= length - 7; i++)
{
//mask:0111110
int tmp = tmpLine & 0x3e;
//System.out.println("tmp:" + tmp);
//活三:X01110Y
if(tmp == 0x1c)
{
//活三:X 或 Y 等于 0
if(((tmpLine & 0x1) == 0) || ((tmpLine & 0x40) == 0))
typeCount[three]++;
}
//活二:X01010Y
if(tmp == 0x14)
{
//活二:X 或 Y 等于 0
if(((tmpLine & 0x1) == 0) || ((tmpLine & 0x40) == 0))
typeCount[two]++;
}
//mask:0011100
tmp = tmpLine & 0x1c;
//冲四:XY101ZW
if(tmp == 0x14)
{
//冲四:XY 等于 11 且 Z 等于 0 或 ZW 等于 11 且 Y 等于 0
if(((tmpLine & 0x62) == 0x60) || ((tmpLine & 0x23) == 0x3))
typeCount[sFour]++;
}
tmpLine >>= 1;
}
tmpLine = line;
for(int i = 0; i <= length - 8; i++)
{
//mask:00111100
int tmp = tmpLine & 0x3c;
//活二:XY0110ZW
if(tmp == 0x18)
{
//活二:XY 等于 0 且 ZW 不等于 0 或 ZW 等于 0 且 XY 不等于 0
int XY = tmpLine & 0xc0;
int ZW = tmpLine & 0x3;
if(((XY == 0) && (ZW != 0)) || ((ZW == 0) && (XY != 0)))
typeCount[two]++;
}
tmpLine >>= 1;
}
//取尾部五位
int suffix = line & 0x1f;
//System.out.println("suffix:" + suffix);
switch(suffix)
{
//冲四01111, 11101
case 0xf: case 0x1d: typeCount[sFour]++; break;
//眠三01011,眠三01101,眠三00111
case 0xb: case 0xd: case 0x7: typeCount[sThree]++; break;
//眠二00011,00101,01001
case 0x3: case 0x5: case 01001: typeCount[sTwo]++; break;
default: break;
}
int prefix = (line >> (length - 5)) & 0x1f;
//System.out.println("prefix:" + prefix);
switch(prefix)
{
//冲四11110, 10111
case 0x1e: case 0x17: typeCount[sFour]++; break;
//眠三11010,眠三10110,眠三11100
case 0x1a: case 0x16: case 0x1c: typeCount[sThree]++; break;
//眠二11000,10100,10010
case 0x18: case 0x14: case 0x12: typeCount[sTwo]++; break;
default: break;
}
if(length >= 6)
{
//取尾部六位111111
suffix = line & 0x3f;
//System.out.println("suffix:" + suffix);
switch(suffix)
{
//活三001110
case 0xe: typeCount[three]++; break;
//活二001010, 000110
case 0xa: case 0x6: typeCount[two]++; break;
default: break;
}
prefix = (line >> (length - 6)) & 0x3f;
switch(prefix)
{
//活三011100
case 0x1c: typeCount[three]++; break;
//活二010100, 011000
case 0x14: case 0x18: typeCount[two]++; break;
default: break;
}
}
/* for(int i = 0; i < 8; i++)
System.out.print(typeCount[i] + " ");
System.out.println();*/
}
/* public static void main(String[] args)
{
Evaluation e = new Evaluation(15);
ChessMan[][] board = new ChessMan[15][15];
e.analysisChess(52, 0, 15, ChessMan.Black);
System.exit(0);
}*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -