private static int GetSmallestAttackSeeMove(long[] pieces, int colorToMove, int toIndex, long allPieces, long slidingMask) { // TODO stop when bad-capture // put 'super-piece' in see position // pawn non-promotion attacks var attackMove = StaticMoves.PawnAttacks[1 - colorToMove][toIndex] & pieces[Pawn] & allPieces; if (attackMove != 0) { return(BitOperations.TrailingZeroCount(attackMove)); } // knight attacks attackMove = pieces[Knight] & StaticMoves.KnightMoves[toIndex] & allPieces; if (attackMove != 0) { return(BitOperations.TrailingZeroCount(attackMove)); } // bishop attacks if ((pieces[Bishop] & slidingMask) != 0) { attackMove = pieces[Bishop] & MagicUtil.GetBishopMoves(toIndex, allPieces) & allPieces; if (attackMove != 0) { return(BitOperations.TrailingZeroCount(attackMove)); } } // rook attacks if ((pieces[Rook] & slidingMask) != 0) { attackMove = pieces[Rook] & MagicUtil.GetRookMoves(toIndex, allPieces) & allPieces; if (attackMove != 0) { return(BitOperations.TrailingZeroCount(attackMove)); } } // queen attacks if ((pieces[Queen] & slidingMask) != 0) { attackMove = pieces[Queen] & MagicUtil.GetQueenMoves(toIndex, allPieces) & allPieces; if (attackMove != 0) { return(BitOperations.TrailingZeroCount(attackMove)); } } // king attacks attackMove = pieces[King] & StaticMoves.KingMoves[toIndex]; if (attackMove != 0) { return(BitOperations.TrailingZeroCount(attackMove)); } return(-1); }
public static int CalculateMobilityScoresAndSetAttacks(ChessBoard cb) { cb.ClearEvalAttacks(); for (var color = White; color <= Black; color++) { var kingArea = KingArea[cb.KingIndex[1 - color]]; var piece = cb.Pieces[color][Pawn] & ~cb.PinnedPieces; while (piece != 0) { cb.UpdatePawnAttacks(StaticMoves.PawnAttacks[color][BitOperations.TrailingZeroCount(piece)], color); piece &= piece - 1; } cb.UpdatePawnAttacks(color, kingArea); piece = cb.Pieces[color][Pawn] & cb.PinnedPieces; while (piece != 0) { cb.UpdateAttacks(StaticMoves.PawnAttacks[color][BitOperations.TrailingZeroCount(piece)] & PinnedMovement[BitOperations.TrailingZeroCount(piece)][cb.KingIndex[color]], Pawn, color, kingArea); piece &= piece - 1; } } var score = 0; long moves; for (var color = White; color <= Black; color++) { var tempScore = 0; var kingArea = KingArea[cb.KingIndex[1 - color]]; var safeMoves = ~cb.Pieces[color][All] & ~cb.Attacks[1 - color][Pawn]; // knights var piece = cb.Pieces[color][Knight] & ~cb.PinnedPieces; while (piece != 0) { moves = StaticMoves.KnightMoves[BitOperations.TrailingZeroCount(piece)]; cb.UpdateAttacks(moves, Knight, color, kingArea); tempScore += EvalConstants.MobilityKnight[BitOperations.PopCount((ulong)(moves & safeMoves))]; piece &= piece - 1; } // bishops piece = cb.Pieces[color][Bishop]; while (piece != 0) { moves = MagicUtil.GetBishopMoves(BitOperations.TrailingZeroCount(piece), cb.AllPieces ^ cb.Pieces[color][Queen]); cb.UpdateAttacks(moves, Bishop, color, kingArea); tempScore += EvalConstants.MobilityBishop[BitOperations.PopCount((ulong)(moves & safeMoves))]; piece &= piece - 1; } // rooks piece = cb.Pieces[color][Rook]; while (piece != 0) { moves = MagicUtil.GetRookMoves(BitOperations.TrailingZeroCount(piece), cb.AllPieces ^ cb.Pieces[color][Rook] ^ cb.Pieces[color][Queen]); cb.UpdateAttacks(moves, Rook, color, kingArea); tempScore += EvalConstants.MobilityRook[BitOperations.PopCount((ulong)(moves & safeMoves))]; piece &= piece - 1; } // queens piece = cb.Pieces[color][Queen]; while (piece != 0) { moves = MagicUtil.GetQueenMoves(BitOperations.TrailingZeroCount(piece), cb.AllPieces); cb.UpdateAttacks(moves, Queen, color, kingArea); tempScore += EvalConstants.MobilityQueen[BitOperations.PopCount((ulong)(moves & safeMoves))]; piece &= piece - 1; } score += tempScore * ColorFactor[color]; } // TODO king-attacks with or without enemy attacks? // WHITE king moves = StaticMoves.KingMoves[cb.KingIndex[White]] & ~StaticMoves.KingMoves[cb.KingIndex[Black]]; cb.Attacks[White][King] = moves; cb.DoubleAttacks[White] |= cb.Attacks[White][All] & moves; cb.Attacks[White][All] |= moves; score += EvalConstants.MobilityKing[ BitOperations.PopCount((ulong)(moves & ~cb.Pieces[White][All] & ~cb.Attacks[Black][All]))]; // BLACK king moves = StaticMoves.KingMoves[cb.KingIndex[Black]] & ~StaticMoves.KingMoves[cb.KingIndex[White]]; cb.Attacks[Black][King] = moves; cb.DoubleAttacks[Black] |= cb.Attacks[Black][All] & moves; cb.Attacks[Black][All] |= moves; score -= EvalConstants.MobilityKing[ BitOperations.PopCount((ulong)(moves & ~cb.Pieces[Black][All] & ~cb.Attacks[White][All]))]; return(score); }