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

📄 evaluate.java

📁 J2ME编写的完整国际象棋程序
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		boolean inEndgame = Math.min(vlWhite, vlBlack) <= 6 && Math.abs(vlWhite - vlBlack) >= 2;
		// 2. Calculate Attacking Values for Each Squares (Both Sides)
		byte[] whiteAttack = new byte[128], blackAttack = new byte[128];
		for (int sq = 0; sq < 128; sq ++) {
			whiteAttack[sq] = blackAttack[SQUARE_FLIP(sq)] = (byte)
					(RANK_IMPORTANCE[sq] * Math.max(vlWhite + vlBlack - 24, 8) / 32 + CENTER_IMPORTANCE[sq]);
		}
		for (int i = 0; i < 8; i ++) {
			int importance = 12 * Math.max(vlWhite + vlBlack - 24, 8) / 32;
			int sq = sqWhiteKing + Position.KING_DELTA[i];
			if (IN_BOARD(sq)) {
				blackAttack[sq] += importance;
			}
			sq = sqBlackKing + Position.KING_DELTA[i];
			if (IN_BOARD(sq)) {
				whiteAttack[sq] += importance;
			}
		}
		// 3. Calculate Control Table for Each Squares
		byte[] whiteRookControl = new byte[128], whiteBishopControl = new byte[128];
		byte[] blackRookControl = new byte[128], blackBishopControl = new byte[128];
		for (int sq = 0; sq < 128; sq ++) {
			if (IN_BOARD(sq)) {
				whiteRookControl[sq] = (byte) calcRookControl(pos, sq, whiteAttack);
				blackRookControl[sq] = (byte) calcRookControl(pos, sq, blackAttack);
				whiteBishopControl[sq] = (byte) calcBishopControl(pos, sq, whiteAttack);
				blackBishopControl[sq] = (byte) calcBishopControl(pos, sq, blackAttack);
			}
		}
		// 4. Calculate Piece Value Table for Each Squares and Each Piece-Types
		for (int sq = 0; sq < 128; sq ++) {
			if (!IN_BOARD(sq)) {
				continue;
			}
			int edgePenalty = EDGE_PENALTY[sq];
			if (inEndgame) {
				if (vlWhite < vlBlack) {
					// 4.1. In Endgames, the Losing King should be Close to Center and Distant to Bottom
					pos.vlWhitePiecePos[PIECE_KING][sq] = (short) losingKingValue(sq);
					// 4.2. In Endgames, the Winning King should be Close to the Losing King and Distant to Border
					pos.vlBlackPiecePos[PIECE_KING][sq] = (short) winningKingValue(sq, sqWhiteKing);
				} else {
					// 4.1. ...
					pos.vlBlackPiecePos[PIECE_KING][sq] = (short) losingKingValue(sq);
					// 4.2. ...
					pos.vlWhitePiecePos[PIECE_KING][sq] = (short) winningKingValue(sq, sqBlackKing);
				}
				// 4.3. In Endgames, Other Pieces are independent to their Positions
				for (int i = PIECE_QUEEN; i <= PIECE_KNIGHT; i ++) {
					pos.vlWhitePiecePos[i][sq] = pos.vlBlackPiecePos[i][sq] =
							(short) (PIECE_VALUE[i] * 100);
				}
			} else {
				// 4.4. King should be Close to Center in Midgames or Endgames
				if (vlWhite + vlBlack <= 32) {
					pos.vlWhitePiecePos[PIECE_KING][sq] =
							pos.vlBlackPiecePos[PIECE_KING][sq] = (short) -edgePenalty;
				} else {
					pos.vlWhitePiecePos[PIECE_KING][sq] =
							pos.vlBlackPiecePos[PIECE_KING][sq] = 0;
				}
				// 4.5. Queen, Rook, Bishop should Favor their Control Values
				pos.vlWhitePiecePos[PIECE_QUEEN][sq] = (short)
						(PIECE_VALUE[PIECE_QUEEN] * 100 + (whiteRookControl[sq] + whiteBishopControl[sq]) / 8);
				pos.vlBlackPiecePos[PIECE_QUEEN][sq] = (short)
						(PIECE_VALUE[PIECE_QUEEN] * 100 + (blackRookControl[sq] + blackBishopControl[sq]) / 8);
				pos.vlWhitePiecePos[PIECE_ROOK][sq] = (short)
						(PIECE_VALUE[PIECE_ROOK] * 100 + whiteRookControl[sq] / 2);
				pos.vlBlackPiecePos[PIECE_ROOK][sq] = (short)
						(PIECE_VALUE[PIECE_ROOK] * 100 + blackRookControl[sq] / 2);
				pos.vlWhitePiecePos[PIECE_BISHOP][sq] = (short)
						(PIECE_VALUE[PIECE_BISHOP] * 100 + whiteBishopControl[sq] / 2);
				pos.vlBlackPiecePos[PIECE_BISHOP][sq] = (short)
						(PIECE_VALUE[PIECE_BISHOP] * 100 + blackBishopControl[sq] / 2);
				// 4.6. Knight should Favor its Attack Value
				int whiteKnightAttack = 0, blackKnightAttack = 0;
				for (int i = 0; i < 8; i ++) {
					int sqDst = sq + Position.KNIGHT_DELTA[i];
					if (IN_BOARD(sqDst)) {
						whiteKnightAttack += whiteAttack[sqDst];
						blackKnightAttack += blackAttack[sqDst];
					}
				}
				pos.vlWhitePiecePos[PIECE_KNIGHT][sq] = (short)
						(PIECE_VALUE[PIECE_KNIGHT] * 100 + whiteKnightAttack / 4 - edgePenalty * 3 / 2);
				pos.vlBlackPiecePos[PIECE_KNIGHT][sq] = (short)
						(PIECE_VALUE[PIECE_KNIGHT] * 100 + blackKnightAttack / 4 - edgePenalty * 3 / 2);
			}
			// 4.7. Pawn should Favor its Position Value
			pos.vlWhitePiecePos[PIECE_PAWN][sq] = pos.vlBlackPiecePos[PIECE_PAWN][SQUARE_FLIP(sq)] =
					(short) (PIECE_VALUE[PIECE_PAWN] * 100 + PAWN_VALUE[sq] / 2 - 6);
		}
		/* 5. Calculate Piece Value Table for Pawn Structure
		 * 
		 * Self:
		 *   x P x - P = brForward,    x = brLeftCover/brRightCover
		 * ^ x P x - P = brSelf,       x = brSide
		 * | x P x - P = brSelf(Last), x = brChain
		 * 
		 * Opponent:
		 *   . . .
		 * ^ . x . - x = brOppPass, or BehindOppPass if a Pawn in Front
		 * | o o o - o = ~brSelf/brSide(Last)
		 */
		for (int sd = 0; sd < 2; sd ++) {
			int brSelf = 0, brSide = 0, brBehindOppPass = 0;
			int brOppPass = FULL_BIT_RANK;
			for (int i = 1; i <= 6; i ++) {
				int y = (sd == 0 ? 7 - i : i);
				int brOpp = (sd == 0 ? pos.brBlackPawn[y] : pos.brWhitePawn[y]);
				brOppPass &= ~(brSelf | brSide);
				brBehindOppPass |= (brOppPass & brOpp);
				int brChain = brSide;
				brSelf = (sd == 0 ? pos.brWhitePawn[y] : pos.brBlackPawn[y]);
				brSide = ((brSelf >> 1) | (brSelf << 1)) & FULL_BIT_RANK;
				int brForward = (sd == 0 ? pos.brWhitePawn[y + 1] : pos.brBlackPawn[y + 1]);
				int brLeftCover = (brForward >> 1) & FULL_BIT_RANK;
				int brRightCover = (brForward << 1) & FULL_BIT_RANK;
				for (int x = Position.FILE_LEFT; x <= Position.FILE_RIGHT; x ++) {
					int sq = Position.COORD_XY(x, y);
					int brSquare = 1 << x;
					// 5.1. Bonus for Parallel and Protected Pawns
					int value = ((brSide & brSquare) != 0 ? 3 : 0) + ((brChain & brSquare) != 0 ? 2 : 0);
					// 5.2. Bonus for the Pawn which can Protect Other Pawns
					value += ((brLeftCover & brSquare) != 0 ? 2 : 0) + ((brRightCover & brSquare) != 0 ? 2 : 0);
					// 5.3. Bonus for Self (Penalty for Moving)
					value += ((brSelf & brSquare) != 0 ? 1 : 0);
					if (sd == 0) {
						pos.vlWhitePiecePos[PIECE_PAWN][sq] += value;
					} else {
						pos.vlBlackPiecePos[PIECE_PAWN][sq] += value;
					}
					if (vlWhite + vlBlack <= 32) {
						// 5.4. Bonus for Passed Pawn
						if ((brOppPass & brSquare) != 0) {
							if (sd == 0) {
								pos.vlBlackPiecePos[PIECE_PAWN][sq] += PASS_PAWN[i];
							} else {
								pos.vlWhitePiecePos[PIECE_PAWN][sq] += PASS_PAWN[i];
							}
						}
						// 5.5. Bonus for Rook (Both Sides) Behind Pawn
						if ((brBehindOppPass & brSquare) != 0) {
							pos.vlWhitePiecePos[PIECE_ROOK][sq] += 8;
							pos.vlBlackPiecePos[PIECE_ROOK][sq] += 8;
							if (i == 6) {
								int sqBottom = sq + Position.FORWARD_DELTA(sd);
								pos.vlWhitePiecePos[PIECE_ROOK][sqBottom] += 8;
								pos.vlBlackPiecePos[PIECE_ROOK][sqBottom] += 8;
							}
						}
					}
				}
			}
		}
		// 6. Calculate Penalty for Blocking Center Pawns with a Bishop
		for (int sq = 0x67; sq <= 0x68; sq ++) {
			if (pos.squares[sq] == 8 + PIECE_PAWN) {
				pos.vlWhitePiecePos[PIECE_BISHOP][sq - 16] -= 10;
			}
		}
		for (int sq = 0x17; sq <= 0x18; sq ++) {
			if (pos.squares[sq] == 16 + PIECE_PAWN) {
				pos.vlBlackPiecePos[PIECE_BISHOP][sq + 16] -= 10;
			}
		}
		// 7. Update "vlWhite" and "vlBlack" in "pos"
		pos.vlWhite = pos.vlBlack = 0;
		for (int sq = 0; sq < 128; sq ++) {
			int pc = pos.squares[sq];
			if (pc > 0) {
				if (pc < 16) {
					pos.vlWhite += pos.vlWhitePiecePos[pc - 8][sq];
				} else {
					pos.vlBlack += pos.vlBlackPiecePos[pc - 16][sq];
				}
			}
		}
	}

	public static int evaluate(Position pos, int vlAlpha, int vlBeta) {
		// 1. Material (with Position) Value
		int vl = pos.material();
		if (vl + LAZY_MARGIN <= vlAlpha) {
			return vl + LAZY_MARGIN;
		} else if (vl - LAZY_MARGIN >= vlBeta) {
			return vl - LAZY_MARGIN;
		}
		// 2. Pawn Structure Value
		for (int sd = 0; sd < 2; sd ++) {
			int brSingle = 0, brDouble = 0;
			int[] brs = (sd == 0 ? pos.brWhitePawn : pos.brBlackPawn);
			for (int i = 1; i <= 6; i ++) {
				brDouble |= brSingle & brs[i];
				brSingle |= brs[i];
			}
			int brIsolated = brSingle & ~((brSingle << 1) | (brSingle >> 1));
			int penalty = Util.POP_COUNT_16(brDouble) * DOUBLE_PENALTY +
					Util.POP_COUNT_16(brIsolated) * ISOLATED_PENALTY +
					Util.POP_COUNT_16(brIsolated & brDouble) * ISOLATED_PENALTY * 2;
			vl += (pos.sdPlayer == sd ? -penalty : penalty);
		}
		return vl;
	}
}

⌨️ 快捷键说明

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