// evaluate_threats() assigns bonuses according to the type of attacking piece // and the type of attacked one. public static Score evaluate_threats(Position pos, EvalInfo ei, Color Us, bool Trace) { Color Them = (Us == ColorS.WHITE ? ColorS.BLACK : ColorS.WHITE); Bitboard b, weakEnemies; Score score = ScoreS.SCORE_ZERO; // Enemies not defended by a pawn and under our attack weakEnemies = pos.pieces_color(Them) & ~ei.attackedBy[Them][PieceTypeS.PAWN] & ei.attackedBy[Us][PieceTypeS.ALL_PIECES]; // Add a bonus according if the attacking pieces are minor or major if (weakEnemies != 0) { b = weakEnemies & (ei.attackedBy[Us][PieceTypeS.PAWN] | ei.attackedBy[Us][PieceTypeS.KNIGHT] | ei.attackedBy[Us][PieceTypeS.BISHOP]); if (b != 0) { score += Threat[0][Types.type_of_piece(pos.piece_on(BitBoard.lsb(b)))]; } b = weakEnemies & (ei.attackedBy[Us][PieceTypeS.ROOK] | ei.attackedBy[Us][PieceTypeS.QUEEN]); if (b != 0) { score += Threat[1][Types.type_of_piece(pos.piece_on(BitBoard.lsb(b)))]; } b = weakEnemies & ~ei.attackedBy[Them][PieceTypeS.ALL_PIECES]; if (b != 0) { score += BitBoard.more_than_one(b) ? Hanging[Us != pos.side_to_move()?1:0] * Bitcount.popcount_Max15(b) : Hanging[Us == pos.side_to_move()?1:0]; } } if (Trace) { Tracing.terms[Us][TermsS.THREAT] = score; } return(score); }
/// generate<EVASIONS> generates all pseudo-legal check evasions when the side /// to move is in check. Returns a pointer to the end of the move list. public static int generate_evasions(Position pos, ExtMove[] mlist, int mPos) { Debug.Assert(pos.checkers() != 0); Color us = pos.side_to_move(); Square ksq = pos.king_square(us); Bitboard sliderAttacks = 0; Bitboard sliders = pos.checkers() & ~pos.pieces_piecetype(PieceTypeS.KNIGHT, PieceTypeS.PAWN); // Find all the squares attacked by slider checkers. We will remove them from // the king evasions in order to skip known illegal moves, which avoids any // useless legality checks later on. while (sliders != 0) { Square checksq = BitBoard.pop_lsb(ref sliders); sliderAttacks |= BitBoard.LineBB[checksq][ksq] ^ BitBoard.SquareBB[checksq]; } // Generate evasions for king, capture and non capture moves Bitboard b = pos.attacks_from_square_piecetype(ksq, PieceTypeS.KING) & ~pos.pieces_color(us) & ~sliderAttacks; while (b != 0) { mlist[mPos++].move = Types.make_move(ksq, BitBoard.pop_lsb(ref b)); } if (BitBoard.more_than_one(pos.checkers())) { return(mPos); // Double check, only a king move can save the day } // Generate blocking evasions or captures of the checking piece Square checksq2 = BitBoard.lsb(pos.checkers()); Bitboard target = BitBoard.between_bb(checksq2, ksq) | BitBoard.SquareBB[checksq2]; return(us == ColorS.WHITE ? generate_all(pos, mlist, mPos, target, ColorS.WHITE, GenTypeS.EVASIONS) : generate_all(pos, mlist, mPos, target, ColorS.BLACK, GenTypeS.EVASIONS)); }