public Engine(string[] args) { inOut.WriteLine(Misc.engine_info(), MutexAction.ATOMIC); Uci.init(Options); BitBoard.init(); Position.init(); Bitbases.init_kpk(); Search.init(); Pawns.init(); Eval.init(); Threads.init(); TT.resize((ulong)Options["Hash"].getInt()); Uci.loop(args); Threads.exit(); }
public Result classify(KPKPosition[] db, Color Us) { // White to Move: If one move leads to a position classified as WIN, the result // of the current position is WIN. If all moves lead to positions classified // as DRAW, the current position is classified as DRAW, otherwise the current // position is classified as UNKNOWN. // // Black to Move: If one move leads to a position classified as DRAW, the result // of the current position is DRAW. If all moves lead to positions classified // as WIN, the position is classified as WIN, otherwise the current position is // classified as UNKNOWN. Color Them = (Us == ColorS.WHITE ? ColorS.BLACK : ColorS.WHITE); Result r = Result.INVALID; Bitboard b = BitBoard.StepAttacksBB[PieceTypeS.KING][Us == ColorS.WHITE ? wksq : bksq]; while (b != 0) { r |= (Us == ColorS.WHITE) ? db[Bitbases.index(Them, bksq, BitBoard.pop_lsb(ref b), psq)].result : db[Bitbases.index(Them, BitBoard.pop_lsb(ref b), wksq, psq)].result; } if (Us == ColorS.WHITE && Types.rank_of(psq) < RankS.RANK_7) { Square s = (psq + SquareS.DELTA_N); r |= db[Bitbases.index(ColorS.BLACK, bksq, wksq, s)].result; // Single push if (Types.rank_of(psq) == RankS.RANK_2 && s != wksq && s != bksq) { r |= db[Bitbases.index(ColorS.BLACK, bksq, wksq, s + SquareS.DELTA_N)].result; // Double push } } if (Us == ColorS.WHITE) { return(result = (r & Result.WIN) != 0 ? Result.WIN : (r & Result.UNKNOWN) != 0 ? Result.UNKNOWN : Result.DRAW); } else { return(result = (r & Result.DRAW) != 0 ? Result.DRAW : (r & Result.UNKNOWN) != 0 ? Result.UNKNOWN : Result.WIN); } }
/// KP vs K. This endgame is evaluated with the help of a bitbase. public Value KPK(Position pos) { Debug.Assert(verify_material(pos, strongSide, ValueS.VALUE_ZERO, 1)); Debug.Assert(verify_material(pos, weakSide, ValueS.VALUE_ZERO, 0)); // Assume strongSide is white and the pawn is on files A-D Square wksq = normalize(pos, strongSide, pos.king_square(strongSide)); Square bksq = normalize(pos, strongSide, pos.king_square(weakSide)); Square psq = normalize(pos, strongSide, pos.list(strongSide, PieceTypeS.PAWN)[0]); Color us = strongSide == pos.side_to_move() ? ColorS.WHITE : ColorS.BLACK; if (!Bitbases.probe_kpk(wksq, psq, bksq, us)) { return(ValueS.VALUE_DRAW); } Value result = ValueS.VALUE_KNOWN_WIN + ValueS.PawnValueEg + Types.rank_of(psq); return(strongSide == pos.side_to_move() ? result : -result); }
/// KP vs KP. This is done by removing the weakest side's pawn and probing the /// KP vs K bitbase: If the weakest side has a draw without the pawn, it probably /// has at least a draw with the pawn as well. The exception is when the stronger /// side's pawn is far advanced and not on a rook file; in this case it is often /// possible to win (e.g. 8/4k3/3p4/3P4/6K1/8/8/8 w - - 0 1). public ScaleFactor KPKP(Position pos) { Debug.Assert(verify_material(pos, strongSide, ValueS.VALUE_ZERO, 1)); Debug.Assert(verify_material(pos, weakSide, ValueS.VALUE_ZERO, 1)); // Assume strongSide is white and the pawn is on files A-D Square wksq = normalize(pos, strongSide, pos.king_square(strongSide)); Square bksq = normalize(pos, strongSide, pos.king_square(weakSide)); Square psq = normalize(pos, strongSide, pos.list(strongSide, PieceTypeS.PAWN)[0]); Color us = strongSide == pos.side_to_move() ? ColorS.WHITE : ColorS.BLACK; // If the pawn has advanced to the fifth rank or further, and is not a // rook pawn, it's too dangerous to assume that it's at least a draw. if (Types.rank_of(psq) >= RankS.RANK_5 && Types.file_of(psq) != FileS.FILE_A) { return(ScaleFactorS.SCALE_FACTOR_NONE); } // Probe the KPK bitbase with the weakest side's pawn removed. If it's a draw, // it's probably at least a draw even with the pawn. return(Bitbases.probe_kpk(wksq, psq, bksq, us) ? ScaleFactorS.SCALE_FACTOR_NONE : ScaleFactorS.SCALE_FACTOR_DRAW); }