Пример #1
0
    internal static void setup_pieces_pawn(TBEntry_pawn ptr, byte[] data, ulong[] tb_size, int f)
    {
        int i;
        int j;
        int order;
        int order2;

        j      = 1 + (ptr.pawns[1] > 0);
        order  = data[0] & 0x0f;
        order2 = ptr.pawns[1] != 0 ? (data[1] & 0x0f) : 0x0f;
        for (i = 0; i < ptr.num; i++)
        {
            ptr.file[f].pieces[0, i] = (byte)(data[i + j] & 0x0f);
        }
        GlobalMembersTbcore.set_norm_pawn(ptr, ptr.file[f].norm[0], ptr.file[f].pieces[0]);
        tb_size[0] = GlobalMembersTbcore.calc_factors_pawn(ptr.file[f].factor[0], ptr.num, order, order2, ptr.file[f].norm[0], f);

        order  = data[0] >> 4;
        order2 = ptr.pawns[1] != 0 ? (data[1] >> 4) : 0x0f;
        for (i = 0; i < ptr.num; i++)
        {
            ptr.file[f].pieces[1, i] = (byte)(data[i + j] >> 4);
        }
        GlobalMembersTbcore.set_norm_pawn(ptr, ptr.file[f].norm[1], ptr.file[f].pieces[1]);
        tb_size[1] = GlobalMembersTbcore.calc_factors_pawn(ptr.file[f].factor[1], ptr.num, order, order2, ptr.file[f].norm[1], f);
    }
Пример #2
0
    internal static void calc_symlen(PairsData d, int s, ref string tmp)
    {
        int s1;
        int s2;

        byte[] w = d.sympat + 3 * s;
        s2 = (w[2] << 4) | (w[1] >> 4);
        if (s2 == 0x0fff)
        {
            d.symlen[s] = 0;
        }
        else
        {
            s1 = ((w[1] & 0xf) << 8) | w[0];
            if (!tmp[s1])
            {
                GlobalMembersTbcore.calc_symlen(d, s1, ref tmp);
            }
            if (!tmp[s2])
            {
                GlobalMembersTbcore.calc_symlen(d, s2, ref tmp);
            }
            d.symlen[s] = (byte)(d.symlen[s1] + d.symlen[s2] + 1);
        }
        tmp[s] = 1;
    }
Пример #3
0
    internal static ulong calc_factors_piece(int[] factor, int num, int order, byte[] norm, byte enc_type)
    {
        int   i;
        int   k;
        int   n;
        ulong f;

        //C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method:
        //  static int pivfac[] = { 31332, 28056, 462 };

        n = 64 - norm[0];

        f = 1;
        for (i = norm[0], k = 0; i < num || k == order; k++)
        {
            if (k == order)
            {
                factor[0] = (int)(f);
                f        *= calc_factors_piece_pivfac[enc_type];
            }
            else
            {
                factor[i] = (int)(f);
                f        *= GlobalMembersTbcore.subfactor(norm[i], n);
                n        -= norm[i];
                i        += norm[i];
            }
        }

        return(f);
    }
Пример #4
0
    //static ulong calc_key_from_pcs(ref int pcs, int mirror);
    internal static void free_wdl_entry(TBEntry entry)
    {
        GlobalMembersTbcore.unmap_file(ref entry.data, entry.mapping);
        if (entry.has_pawns == 0)
        {
            TBEntry_piece ptr = (TBEntry_piece)entry;
//C++ TO C# CONVERTER TODO TASK: The memory management function 'free' has no equivalent in C#:
            free(ptr.precomp[0]);
            if (ptr.precomp[1] != null)
            {
//C++ TO C# CONVERTER TODO TASK: The memory management function 'free' has no equivalent in C#:
                free(ptr.precomp[1]);
            }
        }
        else
        {
            TBEntry_pawn ptr = (TBEntry_pawn)entry;
            int          f;
            for (f = 0; f < 4; f++)
            {
//C++ TO C# CONVERTER TODO TASK: The memory management function 'free' has no equivalent in C#:
                free(ptr.file[f].precomp[0]);
                if (ptr.file[f].precomp[1] != null)
                {
//C++ TO C# CONVERTER TODO TASK: The memory management function 'free' has no equivalent in C#:
                    free(ptr.file[f].precomp[1]);
                }
            }
        }
    }
Пример #5
0
    internal static void setup_pieces_piece_dtz(DTZEntry_piece ptr, byte[] data, ulong[] tb_size)
    {
        int i;
        int order;

        for (i = 0; i < ptr.num; i++)
        {
            ptr.pieces[i] = (byte)(data[i + 1] & 0x0f);
        }
        order = data[0] & 0x0f;
        GlobalMembersTbcore.set_norm_piece((TBEntry_piece)ptr, ptr.norm, ptr.pieces);
        tb_size[0] = GlobalMembersTbcore.calc_factors_piece(ptr.factor, ptr.num, order, ptr.norm, ptr.enc_type);
    }
Пример #6
0
    internal static string map_file(string name, string suffix, ref ulong mapping)
    {
        FD fd = GlobalMembersTbcore.open_tb(name, suffix);

        if (fd == DefineConstants.FD_ERR)
        {
            return(null);
        }
        #if !_WIN32
        stat statbuf = new stat();
        fstat(fd, statbuf);
        mapping = statbuf.st_size;
//C++ TO C# CONVERTER TODO TASK: C# does not have an equivalent for pointers to value types:
//ORIGINAL LINE: sbyte *data = (sbyte *)mmap(null, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
        sbyte data = (string)mmap(null, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
        if (data == (string)(-1))
        {
            Console.Write("Could not mmap() {0}.\n", name);
            Environment.Exit(1);
        }
        #else
        uint size_low;
        uint size_high;
        size_low = GetFileSize(fd, size_high);
        //  *size = ((uint64)size_high) << 32 | ((uint64)size_low);
        System.IntPtr map = CreateFileMapping(fd, null, PAGE_READONLY, size_high, size_low, null);
        if (map == null)
        {
            Console.Write("CreateFileMapping() failed.\n");
            Environment.Exit(1);
        }
        mapping = (ulong)map;
//C++ TO C# CONVERTER TODO TASK: C# does not have an equivalent for pointers to value types:
//ORIGINAL LINE: sbyte *data = (sbyte *)MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
        sbyte data = (string)MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
        if (data == null)
        {
            Console.Write("MapViewOfFile() failed, name = {0}{1}, error = {2:D}.\n", name, suffix, GetLastError());
            Environment.Exit(1);
        }
        #endif
        GlobalMembersTbcore.close_tb(fd);
        return(data);
    }
Пример #7
0
    internal static void setup_pieces_piece(TBEntry_piece ptr, byte[] data, ulong[] tb_size)
    {
        int i;
        int order;

        for (i = 0; i < ptr.num; i++)
        {
            ptr.pieces[0, i] = (byte)(data[i + 1] & 0x0f);
        }
        order = data[0] & 0x0f;
        GlobalMembersTbcore.set_norm_piece(ptr, ptr.norm[0], ptr.pieces[0]);
        tb_size[0] = GlobalMembersTbcore.calc_factors_piece(ptr.factor[0], ptr.num, order, ptr.norm[0], ptr.enc_type);

        for (i = 0; i < ptr.num; i++)
        {
            ptr.pieces[1, i] = (byte)(data[i + 1] >> 4);
        }
        order = data[0] >> 4;
        GlobalMembersTbcore.set_norm_piece(ptr, ptr.norm[1], ptr.pieces[1]);
        tb_size[1] = GlobalMembersTbcore.calc_factors_piece(ptr.factor[1], ptr.num, order, ptr.norm[1], ptr.enc_type);
    }
Пример #8
0
    internal static ulong calc_factors_pawn(int[] factor, int num, int order, int order2, byte[] norm, int file)
    {
        int   i;
        int   k;
        int   n;
        ulong f;

        i = norm[0];
        if (order2 < 0x0f)
        {
            i += norm[i];
        }
        n = 64 - i;

        f = 1;
        for (k = 0; i < num || k == order || k == order2; k++)
        {
            if (k == order)
            {
                factor[0] = (int)(f);
                f        *= pfactor[norm[0] - 1, file];
            }
            else if (k == order2)
            {
                factor[norm[0]] = (int)(f);
                f *= GlobalMembersTbcore.subfactor(norm[norm[0]], 48 - norm[0]);
            }
            else
            {
                factor[i] = (int)(f);
                f        *= GlobalMembersTbcore.subfactor(norm[i], n);
                n        -= norm[i];
                i        += norm[i];
            }
        }

        return(f);
    }
Пример #9
0
    internal static PairsData setup_pairs(byte[] data, ulong tb_size, ulong[] size, byte[][] next, ref byte flags, int wdl)
    {
        PairsData d;
        int       i;

        flags = data[0];
        if (data[0] & 0x80)
        {
//C++ TO C# CONVERTER TODO TASK: The memory management function 'malloc' has no equivalent in C#:
            d         = (PairsData)malloc(sizeof(PairsData));
            d.idxbits = 0;
            if (wdl != 0)
            {
                d.min_len = data[1];
            }
            else
            {
                d.min_len = 0;
            }
            next    = data + 2;
            size[0] = size[1] = size[2] = 0;
            return(d);
        }

        int blocksize       = data[1];
        int idxbits         = data[2];
        int real_num_blocks = GlobalMembersTbcore.ReadUint32(data[4]);
        int num_blocks      = real_num_blocks + (byte)(data[3]);
        int max_len         = data[8];
        int min_len         = data[9];
        int h        = max_len - min_len + 1;
        int num_syms = GlobalMembersTbcore.ReadUshort(data[10 + 2 * h]);

//C++ TO C# CONVERTER TODO TASK: The memory management function 'malloc' has no equivalent in C#:
        d           = (PairsData)malloc(sizeof(PairsData) + (h - 1) * sizeof(ulong) + num_syms);
        d.blocksize = blocksize;
        d.idxbits   = idxbits;
        d.offset    = (ushort)(data[10]);
        d.symlen    = ((byte)d) + sizeof(PairsData) + (h - 1) * sizeof(ulong);
        d.sympat    = data[12 + 2 * h];
        d.min_len   = min_len;
        next        = &data[12 + 2 * h + 3 * num_syms + (num_syms & 1)];

        ulong num_indices = (tb_size + (1UL << idxbits) - 1) >> idxbits;

        size[0] = 6UL * num_indices;
        size[1] = 2UL * num_blocks;
        size[2] = (1UL << blocksize) * real_num_blocks;

        // char tmp[num_syms];
        string tmp = new string(new char[4096]);

        for (i = 0; i < num_syms; i++)
        {
            tmp = StringFunctions.ChangeCharacter(tmp, i, 0);
        }
        for (i = 0; i < num_syms; i++)
        {
            if (!tmp[i])
            {
                GlobalMembersTbcore.calc_symlen(d, i, ref tmp);
            }
        }

        d.@base[h - 1] = 0;
        for (i = h - 2; i >= 0; i--)
        {
            d.@base[i] = (d.@base[i + 1] + GlobalMembersTbcore.ReadUshort((byte)(d.offset + i)) - GlobalMembersTbcore.ReadUshort((byte)(d.offset + i + 1))) / 2;
        }
        for (i = 0; i < h; i++)
        {
            d.@base[i] <<= 64 - (min_len + i);
        }

        d.offset -= d.min_len;

        return(d);
    }
Пример #10
0
    internal static void init_tb(ref string str)
    {
        FD      fd = new FD();
        TBEntry entry;
        int     i;
        int     j;

        int[] pcs = new int[16];
        ulong key;
        ulong key2;
        int   color;
//C++ TO C# CONVERTER TODO TASK: Pointer arithmetic is detected on this variable, so pointers on this variable are left unchanged:
        sbyte *s;

        fd = GlobalMembersTbcore.open_tb(str, DefineConstants.WDLSUFFIX);
        if (fd == DefineConstants.FD_ERR)
        {
            return;
        }
        GlobalMembersTbcore.close_tb(fd);

        for (i = 0; i < 16; i++)
        {
            pcs[i] = 0;
        }
        color = 0;
        for (s = str; *s; s++)
        {
            switch (*s)
            {
            case 'P':
                pcs[DefineConstants.TB_PAWN | color]++;
                break;

            case 'N':
                pcs[DefineConstants.TB_KNIGHT | color]++;
                break;

            case 'B':
                pcs[DefineConstants.TB_BISHOP | color]++;
                break;

            case 'R':
                pcs[DefineConstants.TB_ROOK | color]++;
                break;

            case 'Q':
                pcs[DefineConstants.TB_QUEEN | color]++;
                break;

            case 'K':
                pcs[DefineConstants.TB_KING | color]++;
                break;

            case 'v':
                color = 0x08;
                break;
            }
        }
        for (i = 0; i < 8; i++)
        {
            if (pcs[i] != pcs[i + 8])
            {
                break;
            }
        }
        key  = GlobalMembersTbprobe.calc_key_from_pcs(pcs, 0);
        key2 = GlobalMembersTbprobe.calc_key_from_pcs(pcs, 1);
        if (pcs[DefineConstants.TB_PAWN] + pcs[DefineConstants.TB_PAWN | 8] == 0)
        {
            if (TBnum_piece == DefineConstants.TBMAX_PIECE)
            {
                Console.Write("TBMAX_PIECE limit too low!\n");
                Environment.Exit(1);
            }
            entry = (TBEntry)TB_piece[TBnum_piece++];
        }
        else
        {
            if (TBnum_pawn == DefineConstants.TBMAX_PAWN)
            {
                Console.Write("TBMAX_PAWN limit too low!\n");
                Environment.Exit(1);
            }
            entry = (TBEntry)TB_pawn[TBnum_pawn++];
        }
        entry.key   = key;
        entry.ready = 0;
        entry.num   = 0;
        for (i = 0; i < 16; i++)
        {
            entry.num += (byte)pcs[i];
        }
        entry.symmetric = (key == key2);
        entry.has_pawns = (pcs[DefineConstants.TB_PAWN] + pcs[DefineConstants.TB_PAWN | 8] > 0);
        if (entry.num > GlobalMembersTbprobe.MaxCardinality)
        {
            GlobalMembersTbprobe.MaxCardinality = entry.num;
        }

        if (entry.has_pawns != 0)
        {
            TBEntry_pawn ptr = (TBEntry_pawn)entry;
            ptr.pawns[0] = (byte)pcs[DefineConstants.TB_PAWN];
            ptr.pawns[1] = (byte)pcs[DefineConstants.TB_PAWN | 8];
            if (pcs[DefineConstants.TB_PAWN | 8] > 0 && (pcs[DefineConstants.TB_PAWN] == 0 || pcs[DefineConstants.TB_PAWN | 8] < pcs[DefineConstants.TB_PAWN]))
            {
                ptr.pawns[0] = (byte)pcs[DefineConstants.TB_PAWN | 8];
                ptr.pawns[1] = (byte)pcs[DefineConstants.TB_PAWN];
            }
        }
        else
        {
            TBEntry_piece ptr = (TBEntry_piece)entry;
            for (i = 0, j = 0; i < 16; i++)
            {
                if (pcs[i] == 1)
                {
                    j++;
                }
            }
            if (j >= 3)
            {
                ptr.enc_type = 0;
            }
            else if (j == 2)
            {
                ptr.enc_type = 2;
            }
            else     // only for suicide
            {
                j = 16;
                for (i = 0; i < 16; i++)
                {
                    if (pcs[i] < j && pcs[i] > 1)
                    {
                        j = pcs[i];
                    }
                    ptr.enc_type = (byte)(1 + j);
                }
            }
        }
        GlobalMembersTbcore.add_to_hash(entry, key);
        if (key2 != key)
        {
            GlobalMembersTbcore.add_to_hash(entry, key2);
        }
    }
Пример #11
0
    internal static int init_table_dtz(TBEntry entry)
    {
        byte[] data = (byte)entry.data;
//C++ TO C# CONVERTER TODO TASK: C# does not have an equivalent for pointers to value types:
//ORIGINAL LINE: byte *next;
        byte next;
        int  f;
        int  s;

        ulong[] tb_size = new ulong[4];
        ulong[] size    = new ulong[4 * 3];

        if (!data)
        {
            return(0);
        }

        if (data[0] != DTZ_MAGIC[0] || data[1] != DTZ_MAGIC[1] || data[2] != DTZ_MAGIC[2] || data[3] != DTZ_MAGIC[3])
        {
            Console.Write("Corrupted table.\n");
            return(0);
        }

        int files = (data[4] & 0x02) != 0 ? 4 : 1;

        data += 5;

        if (entry.has_pawns == 0)
        {
            DTZEntry_piece ptr = (DTZEntry_piece)entry;
            GlobalMembersTbcore.setup_pieces_piece_dtz(ptr, data, tb_size[0]);
            data += ptr.num + 1;
            data += ((ushort)data) & 0x01;

            ptr.precomp = GlobalMembersTbcore.setup_pairs(data, tb_size[0], size[0], next, ref (ptr.flags), 0);
            data        = next;

            ptr.map = data;
            if ((ptr.flags & 2) != 0)
            {
                int i;
                for (i = 0; i < 4; i++)
                {
                    ptr.map_idx[i] = (ushort)(data + 1 - ptr.map);
                    data          += 1 + data[0];
                }
                data += ((ushort)data) & 0x01;
            }

            ptr.precomp.indextable = (string)data;
            data += size[0];

            ptr.precomp.sizetable = (ushort)data;
            data += size[1];

            data             = (byte)((((ushort)data) + 0x3f) & ~0x3f);
            ptr.precomp.data = data;
            data            += size[2];
        }
        else
        {
            DTZEntry_pawn ptr = (DTZEntry_pawn)entry;
            s = 1 + (ptr.pawns[1] > 0);
            for (f = 0; f < 4; f++)
            {
                GlobalMembersTbcore.setup_pieces_pawn_dtz(ptr, data, tb_size[f], f);
                data += ptr.num + s;
            }
            data += ((ushort)data) & 0x01;

            for (f = 0; f < files; f++)
            {
                ptr.file[f].precomp = GlobalMembersTbcore.setup_pairs(data, tb_size[f], size[3 * f], next, ref (ptr.flags[f]), 0);
                data = next;
            }

            ptr.map = data;
            for (f = 0; f < files; f++)
            {
                if ((ptr.flags[f] & 2) != 0)
                {
                    int i;
                    for (i = 0; i < 4; i++)
                    {
                        ptr.map_idx[f, i] = (ushort)(data + 1 - ptr.map);
                        data += 1 + data[0];
                    }
                }
            }
            data += ((ushort)data) & 0x01;

            for (f = 0; f < files; f++)
            {
                ptr.file[f].precomp.indextable = (string)data;
                data += size[3 * f];
            }

            for (f = 0; f < files; f++)
            {
                ptr.file[f].precomp.sizetable = (ushort)data;
                data += size[3 * f + 1];
            }

            for (f = 0; f < files; f++)
            {
                data = (byte)((((ushort)data) + 0x3f) & ~0x3f);
                ptr.file[f].precomp.data = data;
                data += size[3 * f + 2];
            }
        }

        return(1);
    }
Пример #12
0
    internal static int init_table_wdl(TBEntry entry, ref string str)
    {
//C++ TO C# CONVERTER TODO TASK: C# does not have an equivalent for pointers to value types:
//ORIGINAL LINE: byte *next;
        byte next;
        int  f;
        int  s;

        ulong[] tb_size = new ulong[8];
        ulong[] size    = new ulong[8 * 3];
        byte    flags;

        // first mmap the table into memory

        entry.data = GlobalMembersTbcore.map_file(str, DefineConstants.WDLSUFFIX, ref entry.mapping);
        if (entry.data == 0)
        {
            Console.Write("Could not find {0}" DefineConstants.WDLSUFFIX, str);
            return(0);
        }

        byte[] data = (byte)entry.data;
        if (data[0] != WDL_MAGIC[0] || data[1] != WDL_MAGIC[1] || data[2] != WDL_MAGIC[2] || data[3] != WDL_MAGIC[3])
        {
            Console.Write("Corrupted table.\n");
            GlobalMembersTbcore.unmap_file(ref entry.data, entry.mapping);
            entry.data = 0;
            return(0);
        }

        int split = data[4] & 0x01;
        int files = (data[4] & 0x02) != 0 ? 4 : 1;

        data += 5;

        if (entry.has_pawns == 0)
        {
            TBEntry_piece ptr = (TBEntry_piece)entry;
            GlobalMembersTbcore.setup_pieces_piece(ptr, data, tb_size[0]);
            data += ptr.num + 1;
            data += ((ushort)data) & 0x01;

            ptr.precomp[0] = GlobalMembersTbcore.setup_pairs(data, tb_size[0], size[0], next, ref flags, 1);
            data           = next;
            if (split != 0)
            {
                ptr.precomp[1] = GlobalMembersTbcore.setup_pairs(data, tb_size[1], size[3], next, ref flags, 1);
                data           = next;
            }
            else
            {
                ptr.precomp[1] = null;
            }

            ptr.precomp[0].indextable = (string)data;
            data += size[0];
            if (split != 0)
            {
                ptr.precomp[1].indextable = (string)data;
                data += size[3];
            }

            ptr.precomp[0].sizetable = (ushort)data;
            data += size[1];
            if (split != 0)
            {
                ptr.precomp[1].sizetable = (ushort)data;
                data += size[4];
            }

            data = (byte)((((ushort)data) + 0x3f) & ~0x3f);
            ptr.precomp[0].data = data;
            data += size[2];
            if (split != 0)
            {
                data = (byte)((((ushort)data) + 0x3f) & ~0x3f);
                ptr.precomp[1].data = data;
            }
        }
        else
        {
            TBEntry_pawn ptr = (TBEntry_pawn)entry;
            s = 1 + (ptr.pawns[1] > 0);
            for (f = 0; f < 4; f++)
            {
                GlobalMembersTbcore.setup_pieces_pawn((TBEntry_pawn)ptr, data, tb_size[2 * f], f);
                data += ptr.num + s;
            }
            data += ((ushort)data) & 0x01;

            for (f = 0; f < files; f++)
            {
                ptr.file[f].precomp[0] = GlobalMembersTbcore.setup_pairs(data, tb_size[2 * f], size[6 * f], next, ref flags, 1);
                data = next;
                if (split != 0)
                {
                    ptr.file[f].precomp[1] = GlobalMembersTbcore.setup_pairs(data, tb_size[2 * f + 1], size[6 * f + 3], next, ref flags, 1);
                    data = next;
                }
                else
                {
                    ptr.file[f].precomp[1] = null;
                }
            }

            for (f = 0; f < files; f++)
            {
                ptr.file[f].precomp[0].indextable = (string)data;
                data += size[6 * f];
                if (split != 0)
                {
                    ptr.file[f].precomp[1].indextable = (string)data;
                    data += size[6 * f + 3];
                }
            }

            for (f = 0; f < files; f++)
            {
                ptr.file[f].precomp[0].sizetable = (ushort)data;
                data += size[6 * f + 1];
                if (split != 0)
                {
                    ptr.file[f].precomp[1].sizetable = (ushort)data;
                    data += size[6 * f + 4];
                }
            }

            for (f = 0; f < files; f++)
            {
                data = (byte)((((ushort)data) + 0x3f) & ~0x3f);
                ptr.file[f].precomp[0].data = data;
                data += size[6 * f + 2];
                if (split != 0)
                {
                    data = (byte)((((ushort)data) + 0x3f) & ~0x3f);
                    ptr.file[f].precomp[1].data = data;
                    data += size[6 * f + 5];
                }
            }
        }

        return(1);
    }
Пример #13
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);
    }
Пример #14
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);
    }