📄 evaluate.java
字号:
/*
Evaluate.java - Source Code for Mobile Chess, Part VII
Mobile Chess - a Chess Program for Java ME
Designed by Morning Yellow, Version: 1.01, Last Modified: Feb. 2008
Copyright (C) 2004-2008 www.elephantbase.net
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package chess;
// This part is ported from Owl Chess Sample in Borland C++ 5.0
public class Evaluate {
public static final int PIECE_KING = Position.PIECE_KING;
public static final int PIECE_QUEEN = Position.PIECE_QUEEN;
public static final int PIECE_ROOK = Position.PIECE_ROOK;
public static final int PIECE_BISHOP = Position.PIECE_BISHOP;
public static final int PIECE_KNIGHT = Position.PIECE_KNIGHT;
public static final int PIECE_PAWN = Position.PIECE_PAWN;
public static final int FULL_BIT_RANK = 0x0ff0;
public static final int LAZY_MARGIN = 100;
public static final int ISOLATED_PENALTY = 10;
public static final int DOUBLE_PENALTY = 4;
public static final int[] PIECE_VALUE = {0, 9, 5, 3, 3, 1};
public static final int[] PASS_PAWN = {0, 35, 30, 20, 10, 5, 0, 0};
public static final byte[] DISTANCE = new byte[] {
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 7, 6, 7, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 7, 6, 5, 6, 7, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 7, 6, 5, 4, 5, 6, 7, 0, 0, 0, 0, 0,
0, 0, 0, 7, 6, 5, 4, 3, 4, 5, 6, 7, 0, 0, 0, 0,
0, 0, 7, 6, 5, 4, 3, 2, 3, 4, 5, 6, 7, 0, 0, 0,
0, 7, 6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 6, 7, 0, 0,
7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 0,
0, 7, 6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 6, 7, 0, 0,
0, 0, 7, 6, 5, 4, 3, 2, 3, 4, 5, 6, 7, 0, 0, 0,
0, 0, 0, 7, 6, 5, 4, 3, 4, 5, 6, 7, 0, 0, 0, 0,
0, 0, 0, 0, 7, 6, 5, 4, 5, 6, 7, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 7, 6, 5, 6, 7, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 7, 6, 7, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
};
public static final byte[] ENDGAME_EDGE = {
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
};
public static final byte[] ENDGAME_BOTTOM = {
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
};
public static final byte[] ENDGAME_KING_PENALTY = {
0, 0, 0, 0,25,22,19,16,16,19,22,25, 0, 0, 0, 0,
0, 0, 0, 0,17,14,11, 8, 8,11,14,17, 0, 0, 0, 0,
0, 0, 0, 0,13,10, 7, 4, 4, 7,10,13, 0, 0, 0, 0,
0, 0, 0, 0, 9, 6, 3, 0, 0, 3, 6, 9, 0, 0, 0, 0,
0, 0, 0, 0, 9, 6, 3, 0, 0, 3, 6, 9, 0, 0, 0, 0,
0, 0, 0, 0,13,10, 7, 4, 4, 7,10,13, 0, 0, 0, 0,
0, 0, 0, 0,17,14,11, 8, 8,11,14,17, 0, 0, 0, 0,
0, 0, 0, 0,25,22,19,16,16,19,22,25, 0, 0, 0, 0,
};
public static final byte[] EDGE_PENALTY = {
0, 0, 0, 0, 6, 5, 4, 3, 3, 4, 5, 6, 0, 0, 0, 0,
0, 0, 0, 0, 5, 4, 3, 2, 2, 3, 4, 5, 0, 0, 0, 0,
0, 0, 0, 0, 4, 3, 2, 1, 1, 2, 3, 4, 0, 0, 0, 0,
0, 0, 0, 0, 3, 2, 1, 0, 0, 1, 2, 3, 0, 0, 0, 0,
0, 0, 0, 0, 3, 2, 1, 0, 0, 1, 2, 3, 0, 0, 0, 0,
0, 0, 0, 0, 4, 3, 2, 1, 1, 2, 3, 4, 0, 0, 0, 0,
0, 0, 0, 0, 5, 4, 3, 2, 2, 3, 4, 5, 0, 0, 0, 0,
0, 0, 0, 0, 6, 5, 4, 3, 3, 4, 5, 6, 0, 0, 0, 0,
};
public static final byte[] PAWN_VALUE = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 30, 30, 46, 70, 78, 46, 30, 30, 0, 0, 0, 0,
0, 0, 0, 0, 8, 8, 22, 43, 50, 22, 8, 8, 0, 0, 0, 0,
0, 0, 0, 0, 4, 4, 16, 34, 40, 16, 4, 4, 0, 0, 0, 0,
0, 0, 0, 0, 2, 2, 12, 27, 32, 12, 2, 2, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 8, 20, 24, 8, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 6, 15, 18, 6, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
public static final byte[] CENTER_IMPORTANCE = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 2, 5, 5, 2, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 2, 5, 8, 8, 5, 2, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 2, 5, 8, 8, 5, 2, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 2, 5, 5, 2, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
public static final byte[] RANK_IMPORTANCE = {
0, 0, 0, 0,12,12,12,12,12,12,12,12, 0, 0, 0, 0,
0, 0, 0, 0,12,12,12,12,12,12,12,12, 0, 0, 0, 0,
0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0,
0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
public static boolean IN_BOARD(int sq) {
return Position.IN_BOARD(sq);
}
public static int SQUARE_FLIP(int sq) {
return Position.SQUARE_FLIP(sq);
}
public static int losingKingValue(int sq) {
return -ENDGAME_KING_PENALTY[sq] * 2 - ENDGAME_BOTTOM[sq] * 8;
}
public static int winningKingValue(int sq, int sqOppKing) {
return -DISTANCE[sqOppKing - sq + 128] * 2 - ENDGAME_EDGE[sq] * 8;
}
public static int calcRookControl(Position pos, int sqSrc, byte[] attack) {
return calcSlideControl(pos, sqSrc, attack, true);
}
public static int calcBishopControl(Position pos, int sqSrc, byte[] attack) {
return calcSlideControl(pos, sqSrc, attack, false);
}
public static int calcSlideControl(Position pos, int sqSrc, byte[] attack, boolean isRook) {
int control = 0;
for (int i = 0; i < 4; i ++) {
int delta = (isRook ? Position.ROOK_DELTA[i] : Position.BISHOP_DELTA[i]);
int sqDst = sqSrc + delta;
boolean direct = true;
while (IN_BOARD(sqDst)) {
control += (direct ? attack[sqDst] : attack[sqDst] / 2);
if (pos.squares[sqDst] > 0) {
int pieceType = Position.PIECE_TYPE(pos.squares[sqDst]);
if (pieceType == PIECE_PAWN) {
break;
} else if (pieceType == PIECE_KING || pieceType == PIECE_KNIGHT ||
pieceType == (isRook ? PIECE_BISHOP : PIECE_ROOK)) {
direct = false;
}
}
sqDst += delta;
}
}
return control;
}
public static void preEval(Position pos) {
// 1. Calculate Simple Materials for Both Sides
int vlWhite = 0, vlBlack = 0, sqWhiteKing = 0, sqBlackKing = 0;
for (int sq = 0; sq < 128; sq ++) {
int pc = pos.squares[sq];
if (pc == 0) {
continue;
}
if (pc < 16) {
vlWhite += PIECE_VALUE[pc - 8];
if (pc == 8) {
sqWhiteKing = sq;
}
} else {
vlBlack += PIECE_VALUE[pc - 16];
if (pc == 16) {
sqBlackKing = sq;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -