internal static UInt64 GetAllTargets(UInt64 knights, bool pieceColor, Board board) { UInt64 targets = 0UL; while (knights != 0) { // accede all'array di mosse precalcolate cercando il primo bit attivo all'interno della Board targets |= KnightAttacks[(BitOps.BitScanForwardReset(ref knights))]; } return(targets & ~board.GetColorPieces(pieceColor)); }
public static void initmagicmoves() { int i; //for bitscans : //initmagicmoves_bitpos64_database[(x*0x07EDD5E59A4E28C2UL)>>58] int[] initmagicmoves_bitpos64_database = new int[64] { 63, 0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, 61, 51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, 62, 57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21, 56, 45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5 }; #if PERFECT_MAGIC_HASH for (i = 0; i < 1428; i++) { magicmovesbdb[i] = 0UL; } for (i = 0; i < 4900; i++) { magicmovesrdb[i] = 0UL; } #endif //Bishops for (i = 0; i < 64; i++) { int[] squares = new int[64]; int numsquares = 0; UInt64 temp = magicmoves_b_mask[i]; while (temp != 0UL) { int bitCount = BitOps.BitCountWegner(temp); squares[numsquares++] = bitCount; BitOps.BitScanForwardReset(ref temp); //UInt64 bit = temp & -temp; //squares[numsquares++] = initmagicmoves_bitpos64_database[(bit * 0x07EDD5E59A4E28C2UL) >> 58]; //temp ^= bit; } for (temp = 0; temp < (1UL << numsquares); temp++) { UInt64 tempocc = initmagicmoves_occ(squares, numsquares, temp); #if !PERFECT_MAGIC_HASH #if !VARIABLE_SHIFT magicmovesbdb[squares[i], Convert.ToInt32((tempocc * magicmoves_b_magics[squares[i]]) >> 55)] = initmagicmoves_Bmoves(i, tempocc); #else magicmovesbdb[squares[i], Convert.ToInt32((tempocc * magicmoves_b_magics[squares[i]]) >> magicmoves_b_shift[squares[i]])] = initmagicmoves_Bmoves(i, tempocc); #endif #else UInt64 moves = initmagicmoves_Bmoves(i, tempocc); #if !VARIABLE_SHIFT UInt64 index = ((tempocc * magicmoves_b_magics[i]) >> 55); #else UInt64 index = ((tempocc * magicmoves_b_magics[i]) >> magicmoves_b_shift[square]); #endif for (ushort j = 0; j < 1428; j++) { if (~magicmovesbdb[j] != 0UL) { magicmovesbdb[j] = moves; magicmoves_b_indices[i, Convert.ToInt32(index)] = j; break; } else if (magicmovesbdb[j] == moves) { magicmoves_b_indices[i, Convert.ToInt32(index)] = j; break; } } #endif } } //Rooks for (i = 0; i < 64; i++) { int[] squares = new int[64]; int numsquares = 0; UInt64 temp = magicmoves_r_mask[i]; while (temp != 0UL) { int bitCount = BitOps.BitCountWegner(temp); squares[numsquares++] = bitCount; BitOps.BitScanForwardReset(ref temp); //UInt64 bit = temp & -temp; //squares[numsquares++]=initmagicmoves_bitpos64_database[(bit*0x07EDD5E59A4E28C2UL)>>58]; //temp^=bit; } for (temp = 0; temp < (1UL << numsquares); temp++) { UInt64 tempocc = initmagicmoves_occ(squares, numsquares, temp); #if !PERFECT_MAGIC_HASH #if !VARIABLE_SHIFT magicmovesrdb[squares[i], Convert.ToInt32((tempocc * magicmoves_r_magics[squares[i]]) >> 52)] = initmagicmoves_Rmoves(i, tempocc); #else magicmovesrdb[squares[i], Convert.ToInt32((tempocc * magicmoves_r_magics[squares[i]]) >> magicmoves_r_shift[squares[i]])] = initmagicmoves_Rmoves(i, tempocc); #endif #else UInt64 moves = initmagicmoves_Rmoves(i, tempocc); #if !VARIABLE_SHIFT UInt64 index = (((tempocc) * magicmoves_r_magics[i]) >> 52); #else UInt64 index = (((tempocc) * magicmoves_r_magics[i]) >> magicmoves_r_shift[squares[i]]); #endif for (ushort j = 0; j < 4900; j++) { if (~magicmovesrdb[j] != 0UL) { magicmovesrdb[j] = moves; magicmoves_r_indices[i, Convert.ToInt32(index)] = j; break; } else if (magicmovesrdb[j] == moves) { magicmoves_r_indices[i, Convert.ToInt32(index)] = j; break; } } #endif } } }
public short getTotalScore() { if (isCheckmate) { return(PlayersTurn ? (short)(-Constants.MATE_SCORE) : (short)Constants.MATE_SCORE); } if (isStalemate) { return(0); } UInt64 piece; int sq; //white is the maximizer short score = (short)(whiteWorth - blackWorth); //Getting a relative attack score for all possible captures on a board like this is a bad idea for 2 reasons; //1. It forces us to calculate the opponents pseudoMoves to get an approx even score, which is inaccurate because it is not their turn. //2. It does not consider the order of captures. //Both problems solved by Algorithm.Quint, which looks further into the game tree for capture moves only. //float attackScore = 0; //foreach (Move move in LegalMoves) // attackScore += (int)move.takenType - (int)((decimal)move.pieceType/(decimal)100); //foreach (Move move in opponentsPseudoMoves) // attackScore -= (int)move.takenType - (int)((decimal)move.pieceType / (decimal)100); short positionalScore = 0; //Pawns piece = BP; while (piece != 0) { sq = BitOps.BitScanForwardReset(ref piece); positionalScore += PawnTable[sq]; } piece = WP; while (piece != 0) { sq = BitOps.BitScanForwardReset(ref piece); positionalScore -= PawnTable[Mirror[sq]]; } //Knights piece = BN; while (piece != 0) { sq = BitOps.BitScanForwardReset(ref piece); positionalScore += KnightTable[sq]; } piece = WN; while (piece != 0) { sq = BitOps.BitScanForwardReset(ref piece); positionalScore -= KnightTable[Mirror[sq]]; } //Bishops piece = BB; while (piece != 0) { sq = BitOps.BitScanForwardReset(ref piece); positionalScore += BishopTable[sq]; } piece = WB; while (piece != 0) { sq = BitOps.BitScanForwardReset(ref piece); positionalScore -= BishopTable[Mirror[sq]]; } //Rooks piece = BR; while (piece != 0) { sq = BitOps.BitScanForwardReset(ref piece); positionalScore += RookTable[sq]; } piece = WR; while (piece != 0) { sq = BitOps.BitScanForwardReset(ref piece); positionalScore -= RookTable[Mirror[sq]]; } //King sq = blackKingIndex; if (blackWorth <= ENDGAME_MAT) { positionalScore += KingE[sq]; } else { positionalScore += KingO[sq]; } sq = whiteKingIndex; if (whiteWorth <= ENDGAME_MAT) { positionalScore -= KingE[Mirror[sq]]; } else { positionalScore -= KingO[Mirror[sq]]; } //score += (short)(POSITIONAL_WEIGHT * positionalScore); //pce = wP; //for (pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) //{ // sq = pos->pList[pce][pceNum]; // ASSERT(SqOnBoard(sq)); // ASSERT(SQ64(sq) >= 0 && SQ64(sq) <= 63); // score += PawnTable[SQ64(sq)]; // if ((IsolatedMask[SQ64(sq)] & pos->pawns[WHITE]) == 0) // { // //printf("wP Iso:%s\n",PrSq(sq)); // score += PawnIsolated; // } // if ((WhitePassedMask[SQ64(sq)] & pos->pawns[BLACK]) == 0) // { // //printf("wP Passed:%s\n",PrSq(sq)); // score += PawnPassed[RanksBrd[sq]]; // } //} //pce = bP; //for (pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) //{ // sq = pos->pList[pce][pceNum]; // ASSERT(SqOnBoard(sq)); // ASSERT(MIRROR64(SQ64(sq)) >= 0 && MIRROR64(SQ64(sq)) <= 63); // score -= PawnTable[MIRROR64(SQ64(sq))]; // if ((IsolatedMask[SQ64(sq)] & pos->pawns[BLACK]) == 0) // { // //printf("bP Iso:%s\n",PrSq(sq)); // score -= PawnIsolated; // } // if ((BlackPassedMask[SQ64(sq)] & pos->pawns[WHITE]) == 0) // { // //printf("bP Passed:%s\n",PrSq(sq)); // score -= PawnPassed[7 - RanksBrd[sq]]; // } //} //pce = wN; //for (pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) //{ // sq = pos->pList[pce][pceNum]; // ASSERT(SqOnBoard(sq)); // ASSERT(SQ64(sq) >= 0 && SQ64(sq) <= 63); // score += KnightTable[SQ64(sq)]; //} //pce = bN; //for (pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) //{ // sq = pos->pList[pce][pceNum]; // ASSERT(SqOnBoard(sq)); // ASSERT(MIRROR64(SQ64(sq)) >= 0 && MIRROR64(SQ64(sq)) <= 63); // score -= KnightTable[MIRROR64(SQ64(sq))]; //} //pce = wB; //for (pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) //{ // sq = pos->pList[pce][pceNum]; // ASSERT(SqOnBoard(sq)); // ASSERT(SQ64(sq) >= 0 && SQ64(sq) <= 63); // score += BishopTable[SQ64(sq)]; //} //pce = bB; //for (pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) //{ // sq = pos->pList[pce][pceNum]; // ASSERT(SqOnBoard(sq)); // ASSERT(MIRROR64(SQ64(sq)) >= 0 && MIRROR64(SQ64(sq)) <= 63); // score -= BishopTable[MIRROR64(SQ64(sq))]; //} //pce = wR; //for (pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) //{ // sq = pos->pList[pce][pceNum]; // ASSERT(SqOnBoard(sq)); // ASSERT(SQ64(sq) >= 0 && SQ64(sq) <= 63); // score += RookTable[SQ64(sq)]; // ASSERT(FileRankValid(FilesBrd[sq])); // if (!(pos->pawns[BOTH] & FileBBMask[FilesBrd[sq]])) // { // score += RookOpenFile; // } // else if (!(pos->pawns[WHITE] & FileBBMask[FilesBrd[sq]])) // { // score += RookSemiOpenFile; // } //} //pce = bR; //for (pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) //{ // sq = pos->pList[pce][pceNum]; // ASSERT(SqOnBoard(sq)); // ASSERT(MIRROR64(SQ64(sq)) >= 0 && MIRROR64(SQ64(sq)) <= 63); // score -= RookTable[MIRROR64(SQ64(sq))]; // ASSERT(FileRankValid(FilesBrd[sq])); // if (!(pos->pawns[BOTH] & FileBBMask[FilesBrd[sq]])) // { // score -= RookOpenFile; // } // else if (!(pos->pawns[BLACK] & FileBBMask[FilesBrd[sq]])) // { // score -= RookSemiOpenFile; // } //} //pce = wQ; //for (pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) //{ // sq = pos->pList[pce][pceNum]; // ASSERT(SqOnBoard(sq)); // ASSERT(SQ64(sq) >= 0 && SQ64(sq) <= 63); // ASSERT(FileRankValid(FilesBrd[sq])); // if (!(pos->pawns[BOTH] & FileBBMask[FilesBrd[sq]])) // { // score += QueenOpenFile; // } // else if (!(pos->pawns[WHITE] & FileBBMask[FilesBrd[sq]])) // { // score += QueenSemiOpenFile; // } //} //pce = bQ; //for (pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) //{ // sq = pos->pList[pce][pceNum]; // ASSERT(SqOnBoard(sq)); // ASSERT(SQ64(sq) >= 0 && SQ64(sq) <= 63); // ASSERT(FileRankValid(FilesBrd[sq])); // if (!(pos->pawns[BOTH] & FileBBMask[FilesBrd[sq]])) // { // score -= QueenOpenFile; // } // else if (!(pos->pawns[BLACK] & FileBBMask[FilesBrd[sq]])) // { // score -= QueenSemiOpenFile; // } //} ////8/p6k/6p1/5p2/P4K2/8/5pB1/8 b - - 2 62 //pce = wK; //sq = pos->pList[pce][0]; //ASSERT(SqOnBoard(sq)); //ASSERT(SQ64(sq) >= 0 && SQ64(sq) <= 63); //if ((pos->material[BLACK] <= ENDGAME_MAT)) //{ // score += KingE[SQ64(sq)]; //} //else //{ // score += KingO[SQ64(sq)]; //} //pce = bK; //sq = pos->pList[pce][0]; //ASSERT(SqOnBoard(sq)); //ASSERT(MIRROR64(SQ64(sq)) >= 0 && MIRROR64(SQ64(sq)) <= 63); //if ((pos->material[WHITE] <= ENDGAME_MAT)) //{ // score -= KingE[MIRROR64(SQ64(sq))]; //} //else //{ // score -= KingO[MIRROR64(SQ64(sq))]; //} //if (pos->pceNum[wB] >= 2) score += BishopPair; //if (pos->pceNum[bB] >= 2) score -= BishopPair; if (isCheck) { score += PlayersTurn ? (short)-Constants.CHECK_BONUS : Constants.CHECK_BONUS; } return(score); }