Example #1
0
        internal static void init_kpk()
        {
            var db = new KPKPosition[IndexMax];
            int idx, repeat = 1;

            // Initialize db with known win / draw positions
            for (idx = 0; idx < IndexMax; idx++)
            {
                db[idx].classify_leaf(idx);
            }

            // Iterate until all positions are classified (30 cycles needed)
            while (repeat != 0)
            {
                for (repeat = idx = 0; idx < IndexMax; idx++)
                {
                    if (db[idx].res == ResultC.UNKNOWN && (db[idx].classify(db) != ResultC.UNKNOWN))
                    {
                        repeat = 1;
                    }
                }
            }

            // Map 32 position results into one KPKBitbase[] entry
            for (idx = 0; idx < IndexMax; idx++)
            {
                if (db[idx].res == ResultC.WIN)
                {
                    KPKBitbase[idx / 32] |= (uint)(1 << (idx & 31));
                }
            }
        }
Example #2
0
        public void Run(object arguments)
        {
            string[] args = (string[])arguments;

            Plug.Write(Utils.engine_info());
            Plug.Write(Constants.endl);

            CheckInfoBroker.init();
            EvalInfoBroker.init();
            SwapListBroker.init();
            MovesSearchedBroker.init();
            PositionBroker.init();
            StateInfoArrayBroker.init();

            MListBroker.init();
            LoopStackBroker.init();
            MovePickerBroker.init();
            StateInfoBroker.init();

            Utils.init();
#if WINDOWS_RT
#else
            Book.init();
#endif
            Position.init();
            KPKPosition.init();
            Endgame.init();
            Search.init();
            Evaluate.init();

            Threads.init();

            // .Net warmup sequence
            Plug.IsWarmup = true;
            Position       pos   = new Position(Uci.StartFEN, false, Threads.main_thread());
            Stack <string> stack = Utils.CreateStack("go depth 7");
            Uci.go(pos, stack);
            Threads.wait_for_search_finished();
            Plug.IsWarmup = false;

            StringBuilder sb = new StringBuilder();
            for (int i = 1; i < args.Length; i++)
            {
                sb.Append(args[i]).Append(" ");
            }

            Uci.uci_loop(sb.ToString());

            Threads.exit();
        }
Example #3
0
        /// KP vs K. This endgame is evaluated with the help of a bitbase.
        internal static Value Endgame_KPK(Color strongerSide, Position pos)
        {
            Color weakerSide = strongerSide ^ 1;

            Debug.Assert(pos.non_pawn_material(strongerSide) == ValueC.VALUE_ZERO);
            Debug.Assert(pos.non_pawn_material(weakerSide) == ValueC.VALUE_ZERO);
            Debug.Assert(pos.piece_count(strongerSide, PieceTypeC.PAWN) == 1);
            Debug.Assert(pos.piece_count(weakerSide, PieceTypeC.PAWN) == 0);

            Square wksq, bksq, wpsq;
            Color stm;

            if (strongerSide == ColorC.WHITE)
            {
                wksq = pos.king_square(ColorC.WHITE);
                bksq = pos.king_square(ColorC.BLACK);
                wpsq = pos.pieceList[ColorC.WHITE][PieceTypeC.PAWN][0];
                stm = pos.sideToMove;
            }
            else
            {
                wksq = Utils.flip_S(pos.king_square(ColorC.BLACK));
                bksq = Utils.flip_S(pos.king_square(ColorC.WHITE));
                wpsq = Utils.flip_S(pos.pieceList[ColorC.BLACK][PieceTypeC.PAWN][0]);
                stm = Utils.flip_C(pos.sideToMove);
            }

            if (Utils.file_of(wpsq) >= FileC.FILE_E)
            {
                wksq = Utils.mirror(wksq);
                bksq = Utils.mirror(bksq);
                wpsq = Utils.mirror(wpsq);
            }

            if (KPKPosition.probe_kpk_bitbase(wksq, wpsq, bksq, stm) == 0)
                return ValueC.VALUE_DRAW;

            Value result = ValueC.VALUE_KNOWN_WIN
                          + Constants.PawnValueEndgame
                          + Utils.rank_of(wpsq);

            return strongerSide == pos.sideToMove ? result : -result;
        }
Example #4
0
        /// K and a pawn vs K and a pawn. 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, she 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).
        internal static ScaleFactor Endgame_KPKP(Color strongerSide, Position pos)
        {
            Color weakerSide = strongerSide ^ 1;

            Debug.Assert(pos.non_pawn_material(strongerSide) == ValueC.VALUE_ZERO);
            Debug.Assert(pos.non_pawn_material(weakerSide) == ValueC.VALUE_ZERO);
            Debug.Assert(pos.piece_count(ColorC.WHITE, PieceTypeC.PAWN) == 1);
            Debug.Assert(pos.piece_count(ColorC.BLACK, PieceTypeC.PAWN) == 1);

            Square wksq = pos.king_square(strongerSide);
            Square bksq = pos.king_square(weakerSide);
            Square wpsq = pos.pieceList[strongerSide][PieceTypeC.PAWN][0];
            Color stm = pos.sideToMove;

            if (strongerSide == ColorC.BLACK)
            {
                wksq = Utils.flip_S(wksq);
                bksq = Utils.flip_S(bksq);
                wpsq = Utils.flip_S(wpsq);
                stm = Utils.flip_C(stm);
            }

            if (Utils.file_of(wpsq) >= FileC.FILE_E)
            {
                wksq = Utils.mirror(wksq);
                bksq = Utils.mirror(bksq);
                wpsq = Utils.mirror(wpsq);
            }

            // 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 (Utils.rank_of(wpsq) >= RankC.RANK_5
                && Utils.file_of(wpsq) != FileC.FILE_A)
                return ScaleFactorC.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 (KPKPosition.probe_kpk_bitbase(wksq, wpsq, bksq, stm) != 0) ? ScaleFactorC.SCALE_FACTOR_NONE : ScaleFactorC.SCALE_FACTOR_DRAW;
        }
Example #5
0
        internal static void init()
        {
            Result[]    db = new Result[IndexMax];
            KPKPosition pos = new KPKPosition();
            int         idx, bit, repeat = 1;

            // Initialize table with known win / draw positions
            for (idx = 0; idx < IndexMax; idx++)
            {
                db[idx] = pos.classify_leaf(idx);
            }

            // Iterate until all positions are classified (30 cycles needed)
            while (repeat != 0)
            {
                for (repeat = idx = 0; idx < IndexMax; idx++)
                {
                    if (db[idx] == ResultC.UNKNOWN && (db[idx] = pos.classify_index(idx, db)) != ResultC.UNKNOWN)
                    {
                        repeat = 1;
                    }
                }
            }

            // Map 32 position results into one KPKBitbase[] entry
            UInt32 one = 1;

            for (idx = 0; idx < IndexMax / 32; idx++)
            {
                for (bit = 0; bit < 32; bit++)
                {
                    if (db[32 * idx + bit] == ResultC.WIN)
                    {
                        KPKBitbase[idx] |= (one << bit);
                    }
                }
            }
        }
Example #6
0
        internal static void init()
        {
            Result[] db = new Result[IndexMax];
            KPKPosition pos = new KPKPosition();
            int idx, bit, repeat = 1;

            // Initialize table with known win / draw positions
            for (idx = 0; idx < IndexMax; idx++)
                db[idx] = pos.classify_leaf(idx);

            // Iterate until all positions are classified (30 cycles needed)
            while (repeat != 0)
                for (repeat = idx = 0; idx < IndexMax; idx++)
                    if (db[idx] == ResultC.UNKNOWN && (db[idx] = pos.classify_index(idx, db)) != ResultC.UNKNOWN)
                        repeat = 1;

            // Map 32 position results into one KPKBitbase[] entry
            UInt32 one = 1;
            for (idx = 0; idx < IndexMax / 32; idx++)
                for (bit = 0; bit < 32; bit++)
                    if (db[32 * idx + bit] == ResultC.WIN)
                        KPKBitbase[idx] |= (one << bit);
        }
Example #7
0
        private int classify(int Us, KPKPosition[] db)
        {
            // White to Move: If one move leads to a position classified as RESULT_WIN,
            // the result of the current position is RESULT_WIN. If all moves lead to
            // positions classified as RESULT_DRAW, the current position is classified
            // RESULT_DRAW otherwise the current position is classified as RESULT_UNKNOWN.
            //
            // Black to Move: If one move leads to a position classified as RESULT_DRAW,
            // the result of the current position is RESULT_DRAW. If all moves lead to
            // positions classified as RESULT_WIN, the position is classified RESULT_WIN.
            // Otherwise, the current position is classified as RESULT_UNKNOWN.

            var r = ResultC.INVALID;
            var b = this.k_attacks(Us);

            while (b != 0)
            {
                r |= Us == ColorC.WHITE
                         ? db[index(ColorC.BLACK, bksq, Utils.pop_lsb(ref b), psq)].res
                         : db[index(ColorC.WHITE, Utils.pop_lsb(ref b), wksq, psq)].res;

                if (Us == ColorC.WHITE && ((r & ResultC.WIN) != 0))
                {
                    return res = ResultC.WIN;
                }

                if (Us == ColorC.BLACK && ((r & ResultC.DRAW) != 0))
                {
                    return res = ResultC.DRAW;
                }
            }

            if (Us == ColorC.WHITE && Utils.rank_of(this.psq) < RankC.RANK_7)
            {
                var s = this.psq + SquareC.DELTA_N;
                r |= db[index(ColorC.BLACK, bksq, wksq, s)].res; // Single push

                if (Utils.rank_of(s) == RankC.RANK_3 && s != this.wksq && s != this.bksq)
                {
                    r |= db[index(ColorC.BLACK, bksq, wksq, s + SquareC.DELTA_N)].res; // Double push
                }

                if ((r & ResultC.WIN) != 0)
                {
                    return res = ResultC.WIN;
                }
            }

            return res = (r & ResultC.UNKNOWN) != 0 ? ResultC.UNKNOWN : Us == ColorC.WHITE ? ResultC.DRAW : ResultC.WIN;
        }
Example #8
0
 Result classify(KPKPosition[] db)
 {
     return classify(stm, db);
 }