Ejemplo n.º 1
0
    public KPKPosition(uint idx)
    {
        wksq   = Square((idx >> 0) & 0x3F);
        bksq   = Square((idx >> 6) & 0x3F);
        us     = Color((idx >> 12) & 0x01);
        psq    = GlobalMembersTypes.make_square(File((idx >> 13) & 0x3), Rank.RANK_7 - Rank((idx >> 15) & 0x7));
        result = Result.UNKNOWN;

        // Check if two pieces are on the same square or if a king can be captured
        if (GlobalMembersBitboard.distance(wksq, bksq) <= 1 || wksq == psq || bksq == psq || (us == Color.WHITE && (StepAttacksBB[(int)PieceType.PAWN][(int)psq] & (int)bksq)))
        {
            result = Result.INVALID;
        }

        else if (us == Color.WHITE)
        {
            // Immediate win if a pawn can be promoted without getting captured
            if (GlobalMembersTypes.rank_of(psq) == Rank.RANK_7 && wksq != psq + Square.DELTA_N && (GlobalMembersBitboard.distance(bksq, psq + Square.DELTA_N) > 1 || (StepAttacksBB[(int)PieceType.KING][(int)wksq] & (psq + Square.DELTA_N))))
            {
                result = Result.WIN;
            }
        }
        // Immediate draw if it is a stalemate or a king captures undefended pawn
        else if (!(StepAttacksBB[(int)PieceType.KING][(int)bksq] & ~(StepAttacksBB[(int)PieceType.KING][(int)wksq] | StepAttacksBB[(int)PieceType.PAWN][(int)psq])) || (StepAttacksBB[(int)PieceType.KING][(int)bksq] & (int)psq & ~StepAttacksBB[(int)PieceType.KING][(int)wksq]))
        {
            result = Result.DRAW;
        }
    }
Ejemplo n.º 2
0
    public void init()
    {
        for (Square s = Square.SQ_A1; s <= Square.SQ_H8; ++s)
        {
            SquareBB[(int)s] = 1UL << s;
            BSFTable[GlobalMembersBitboard.bsf_index(SquareBB[(int)s])] = s;
        }

        for (uint long b = 1; b < 256; ++b)
        {
            MS1BTable[b] = GlobalMembersBitboard.more_than_one(b) ? MS1BTable[b - 1] : GlobalMembersBitboard.lsb(b);
        }

        for (File f = File.FILE_A; f <= File.FILE_H; ++f)
        {
            FileBB[(int)f] = f > ((int)File.FILE_A) != 0 ? FileBB[(int)f - 1] << 1 : FileABB;
        }

        for (Rank r = Rank.RANK_1; r <= Rank.RANK_8; ++r)
        {
            RankBB[(int)r] = r > ((int)Rank.RANK_1) != 0 ? RankBB[(int)r - 1] << 8 : Rank1BB;
        }

        for (File f = File.FILE_A; f <= File.FILE_H; ++f)
        {
            AdjacentFilesBB[(int)f] = (f > ((int)File.FILE_A) != 0 ? FileBB[(int)f - 1] : 0) | (f < ((int)File.FILE_H) != 0 ? FileBB[(int)f + 1] : 0);
        }

        for (Rank r = Rank.RANK_1; r < Rank.RANK_8; ++r)
        {
            InFrontBB[(int)Color.WHITE][(int)r] = ~(InFrontBB[(int)Color.BLACK][(int)r + 1] = InFrontBB[(int)Color.BLACK][(int)r] | RankBB[(int)r]);
        }

        for (Color c = Color.WHITE; c <= Color.BLACK; ++c)
        {
            for (Square s = Square.SQ_A1; s <= Square.SQ_H8; ++s)
            {
                ForwardBB[(int)c][(int)s]      = InFrontBB[(int)c][(int)GlobalMembersTypes.rank_of(s)] & FileBB[(int)GlobalMembersTypes.file_of(s)];
                PawnAttackSpan[(int)c][(int)s] = InFrontBB[(int)c][(int)GlobalMembersTypes.rank_of(s)] & AdjacentFilesBB[(int)GlobalMembersTypes.file_of(s)];
                PassedPawnMask[(int)c][(int)s] = ForwardBB[(int)c][(int)s] | PawnAttackSpan[(int)c][(int)s];
            }
        }

        for (Square s1 = Square.SQ_A1; s1 <= Square.SQ_H8; ++s1)
        {
            for (Square s2 = Square.SQ_A1; s2 <= Square.SQ_H8; ++s2)
            {
                if (s1 != s2)
                {
                    SquareDistance[(int)s1, (int)s2] = Math.Max(GlobalMembersBitboard.distance <File>(s1, s2), GlobalMembersBitboard.distance <Rank>(s1, s2));
                    DistanceRingBB[(int)s1][SquareDistance[(int)s1, (int)s2] - 1] |= s2;
                }
            }
        }

        int[,] steps = { {, 0, 0, 0, 0, 0, 0, 0, 0 }, { 7, 9, 0, 0, 0, 0, 0, 0, 0 }, { 17, 15, 10, 6, -6, -10, -15, -17, 0 }, {, 0, 0, 0, 0, 0, 0, 0, 0 }, {, 0, 0, 0, 0, 0, 0, 0, 0 }, {, 0, 0, 0, 0, 0, 0, 0, 0 }, { 9, 7, -7, -9, 8, 1, -1, -8, 0 } };
Ejemplo n.º 3
0
    /*
     * Stockfish, a UCI chess playing engine derived from Glaurung 2.1
     * Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
     * Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
     *
     * Stockfish is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 3 of the License, or
     * (at your option) any later version.
     *
     * Stockfish is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     */



    public static void t_main(int argc, string[] argv)
    {
        Console.Write(GlobalMembersMisc.engine_info());
        Console.Write("\n");

        GlobalMembersBitboard.init(GlobalMembersUcioption.Options);
        GlobalMembersBitboard.init();
        Position.init();
        Bitbases.init();
        GlobalMembersBitboard.init();
        GlobalMembersBitboard.init();
        GlobalMembersBitboard.init();
        GlobalMembersThread.Threads.init();
        Tablebases.init(GlobalMembersUcioption.Options["SyzygyPath"]);
        GlobalMembersTt.TT.resize(GlobalMembersUcioption.Options["Hash"]);

        GlobalMembersUci.loop(argc, argv);

        GlobalMembersThread.Threads.exit();
    }
Ejemplo n.º 4
0
    internal static int probe_dtz_table(Position pos, int wdl, ref int success)
    {
        TBEntry ptr;
        ulong   idx;
        int     i;
        int     res;

        int[] p = new int[DefineConstants.TBPIECES];

        // Obtain the position's material signature key.
        ulong key = pos.material_key();

        if (GlobalMembersTbcore.DTZ_table[0].key1 != key && GlobalMembersTbcore.DTZ_table[0].key2 != key)
        {
            for (i = 1; i < DefineConstants.DTZ_ENTRIES; i++)
            {
                if (GlobalMembersTbcore.DTZ_table[i].key1 == key)
                {
                    break;
                }
            }
            if (i < DefineConstants.DTZ_ENTRIES)
            {
                DTZTableEntry table_entry = GlobalMembersTbcore.DTZ_table[i];
                for (; i > 0; i--)
                {
                    GlobalMembersTbcore.DTZ_table[i] = GlobalMembersTbcore.DTZ_table[i - 1];
                }
                GlobalMembersTbcore.DTZ_table[0] = table_entry;
            }
            else
            {
                TBHashEntry[] ptr2 = GlobalMembersTbcore.TB_hash[key >> (64 - DefineConstants.TBHASHBITS)];
                for (i = 0; i < DefineConstants.HSHMAX; i++)
                {
                    if (ptr2[i].key == key)
                    {
                        break;
                    }
                }
                if (i == DefineConstants.HSHMAX)
                {
                    success = 0;
                    return(0);
                }
                ptr = ptr2[i].ptr;
                string str    = new string(new char[16]);
                int    mirror = (ptr.key != key);
                GlobalMembersTbprobe.prt_str(pos, str, mirror);
                if (GlobalMembersTbcore.DTZ_table[DefineConstants.DTZ_ENTRIES - 1].entry != null)
                {
                    GlobalMembersTbcore.free_dtz_entry(GlobalMembersTbcore.DTZ_table[DefineConstants.DTZ_ENTRIES - 1].entry);
                }
                for (i = DefineConstants.DTZ_ENTRIES - 1; i > 0; i--)
                {
                    GlobalMembersTbcore.DTZ_table[i] = GlobalMembersTbcore.DTZ_table[i - 1];
                }
                GlobalMembersTbcore.load_dtz_table(ref str, GlobalMembersTbprobe.calc_key(pos, mirror), GlobalMembersTbprobe.calc_key(pos, mirror == 0));
            }
        }

        ptr = GlobalMembersTbcore.DTZ_table[0].entry;
        if (ptr == null)
        {
            success = 0;
            return(0);
        }

        int bside;
        int mirror;
        int cmirror;

        if (ptr.symmetric == 0)
        {
            if (key != ptr.key)
            {
                cmirror = 8;
                mirror  = 0x38;
                bside   = (pos.side_to_move() == Color.WHITE);
            }
            else
            {
                cmirror = mirror = 0;
                bside   = !(pos.side_to_move() == Color.WHITE);
            }
        }
        else
        {
            cmirror = (int)pos.side_to_move() == ((int)Color.WHITE) != 0 ? 0 : 8;
            mirror  = (int)pos.side_to_move() == ((int)Color.WHITE) != 0 ? 0 : 0x38;
            bside   = 0;
        }

        if (ptr.has_pawns == 0)
        {
            DTZEntry_piece entry = (DTZEntry_piece)ptr;
            if ((entry.flags & 1) != bside && entry.symmetric == 0)
            {
                success = -1;
                return(0);
            }
            byte[] pc = entry.pieces;
            for (i = 0; i < entry.num;)
            {
                uint GlobalMembersBitboard.long bb = pos.pieces((Color)((pc[i] ^ cmirror) >> 3), (PieceType)(pc[i] & 0x07));
                do
                {
                    p[i++] = (int)GlobalMembersBitboard.pop_lsb(ref bb);
                } while (bb);
            }
            idx = GlobalMembersTbcore.encode_piece((TBEntry_piece)entry, entry.norm, p, entry.factor);
            res = GlobalMembersTbcore.decompress_pairs(entry.precomp, idx);

            if ((entry.flags & 2) != 0)
            {
                res = entry.map[entry.map_idx[GlobalMembersTbcore.wdl_to_map[wdl + 2]] + res];
            }

            if (!(entry.flags & GlobalMembersTbcore.pa_flags[wdl + 2]) || (wdl & 1))
            {
                res *= 2;
            }
        }
        else
        {
            DTZEntry_pawn entry = (DTZEntry_pawn)ptr;
            int           k     = entry.file[0].pieces[0] ^ cmirror;
            uint GlobalMembersBitboard.long bb = pos.pieces((Color)(k >> 3), (PieceType)(k & 0x07));
            i = 0;
            do
            {
                p[i++] = (int)GlobalMembersBitboard.pop_lsb(ref bb) ^ mirror;
            } while (bb);
            int f = GlobalMembersTbcore.pawn_file((TBEntry_pawn)entry, p);
            if ((entry.flags[f] & 1) != bside)
            {
                success = -1;
                return(0);
            }
            byte[] pc = entry.file[f].pieces;
            for (; i < entry.num;)
            {
                bb = pos.pieces((Color)((pc[i] ^ cmirror) >> 3), (PieceType)(pc[i] & 0x07));
                do
                {
                    p[i++] = (int)GlobalMembersBitboard.pop_lsb(ref bb) ^ mirror;
                } while (bb);
            }
            idx = GlobalMembersTbcore.encode_pawn((TBEntry_pawn)entry, entry.file[f].norm, p, entry.file[f].factor);
            res = GlobalMembersTbcore.decompress_pairs(entry.file[f].precomp, idx);

            if ((entry.flags[f] & 2) != 0)
            {
                res = entry.map[entry.map_idx[f, GlobalMembersTbcore.wdl_to_map[wdl + 2]] + res];
            }

            if (!(entry.flags[f] & GlobalMembersTbcore.pa_flags[wdl + 2]) || (wdl & 1))
            {
                res *= 2;
            }
        }

        return(res);
    }
Ejemplo n.º 5
0
    // probe_wdl_table and probe_dtz_table require similar adaptations.
    internal static int probe_wdl_table(Position pos, ref int success)
    {
        TBEntry ptr;

        TBHashEntry[] ptr2;
        ulong         idx;
        ulong         key;
        int           i;
        byte          res;

        int[] p = new int[DefineConstants.TBPIECES];

        // Obtain the position's material signature key.
        key = pos.material_key();

        // Test for KvK.
        if (key == (Zobrist.psq[(int)Color.WHITE][(int)PieceType.KING][0] ^ Zobrist.psq[(int)Color.BLACK][(int)PieceType.KING][0]))
        {
            return(0);
        }

        ptr2 = GlobalMembersTbcore.TB_hash[key >> (64 - DefineConstants.TBHASHBITS)];
        for (i = 0; i < DefineConstants.HSHMAX; i++)
        {
            if (ptr2[i].key == key)
            {
                break;
            }
        }
        if (i == DefineConstants.HSHMAX)
        {
            success = 0;
            return(0);
        }

        ptr = ptr2[i].ptr;
        if (ptr.ready == 0)
        {
            LOCK(GlobalMembersTbcore.TB_mutex);
            if (ptr.ready == 0)
            {
                string str = new string(new char[16]);
                GlobalMembersTbprobe.prt_str(pos, str, ptr.key != key);
                if (GlobalMembersTbcore.init_table_wdl(ptr, ref str) == 0)
                {
                    ptr2[i].key = 0UL;
                    success     = 0;
                    UNLOCK(GlobalMembersTbcore.TB_mutex);
                    return(0);
                }
                // Memory barrier to ensure ptr->ready = 1 is not reordered.
        #if _MSC_VER
                _ReadWriteBarrier();
        #else
                __asm__ __volatile__ = new __asm__("" global::: "memory");
        #endif
                ptr.ready = 1;
            }
            UNLOCK(GlobalMembersTbcore.TB_mutex);
        }

        int bside;
        int mirror;
        int cmirror;
        if (ptr.symmetric == 0)
        {
            if (key != ptr.key)
            {
                cmirror = 8;
                mirror  = 0x38;
                bside   = (pos.side_to_move() == Color.WHITE);
            }
            else
            {
                cmirror = mirror = 0;
                bside   = !(pos.side_to_move() == Color.WHITE);
            }
        }
        else
        {
            cmirror = (int)pos.side_to_move() == ((int)Color.WHITE) != 0 ? 0 : 8;
            mirror  = (int)pos.side_to_move() == ((int)Color.WHITE) != 0 ? 0 : 0x38;
            bside   = 0;
        }

        // p[i] is to contain the square 0-63 (A1-H8) for a piece of type
        // pc[i] ^ cmirror, where 1 = white pawn, ..., 14 = black king.
        // Pieces of the same type are guaranteed to be consecutive.
        if (ptr.has_pawns == 0)
        {
            TBEntry_piece entry = (TBEntry_piece)ptr;
            byte[]        pc    = entry.pieces[bside];
            for (i = 0; i < entry.num;)
            {
                uint GlobalMembersBitboard.long bb = pos.pieces((Color)((pc[i] ^ cmirror) >> 3), (PieceType)(pc[i] & 0x07));
                do
                {
                    p[i++] = (int)GlobalMembersBitboard.pop_lsb(ref bb);
                } while (bb);
            }
            idx = GlobalMembersTbcore.encode_piece(entry, entry.norm[bside], p, entry.factor[bside]);
            res = GlobalMembersTbcore.decompress_pairs(entry.precomp[bside], idx);
        }
        else
        {
            TBEntry_pawn entry = (TBEntry_pawn)ptr;
            int          k     = entry.file[0].pieces[0, 0] ^ cmirror;
            uint GlobalMembersBitboard.long bb = pos.pieces((Color)(k >> 3), (PieceType)(k & 0x07));
            i = 0;
            do
            {
                p[i++] = (int)GlobalMembersBitboard.pop_lsb(ref bb) ^ mirror;
            } while (bb);
            int    f  = GlobalMembersTbcore.pawn_file(entry, p);
            byte[] pc = entry.file[f].pieces[bside];
            for (; i < entry.num;)
            {
                bb = pos.pieces((Color)((pc[i] ^ cmirror) >> 3), (PieceType)(pc[i] & 0x07));
                do
                {
                    p[i++] = (int)GlobalMembersBitboard.pop_lsb(ref bb) ^ mirror;
                } while (bb);
            }
            idx = GlobalMembersTbcore.encode_pawn(entry, entry.file[f].norm[bside], p, entry.file[f].factor[bside]);
            res = GlobalMembersTbcore.decompress_pairs(entry.file[f].precomp[bside], idx);
        }

        return(((int)res) - 2);
    }