home *** CD-ROM | disk | FTP | other *** search
/ Más de 2,500 Juegos / CD1.iso / ZIPDAT / 0153 / 0153.ZIP / SRC / TTABLE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-17  |  20.3 KB  |  832 lines

  1. /* ttable.c -- Transposition table code to be included in search.c */
  2. /* #include "gnuchess.h"  already included, see search.c */
  3. /* #include "ttable.h"  dito */
  4. /* NOTE: The static evaluation cache "EETable" belongs to eval.c and cannot*/
  5. /*       be moved to ttable.c */
  6. /* Privae types and data */
  7.  
  8. struct hashentry
  9.      {
  10.        unsigned long hashbd;
  11.        UCHAR flags, depth;      /* CHAR saves some space */
  12.        tshort score;
  13.        utshort mv;
  14. #ifdef HASHTEST
  15.        UCHAR bd[32];
  16. #endif /* HASHTEST */
  17. #ifdef NEWAGE
  18.    utshort age;        /* age of last use */
  19. #endif
  20.      };
  21. struct hashentry *ttable[2];
  22.  
  23. unsigned long ttblsize;
  24. SHORT rehash;  /* -1 is used as a flag --tpm */
  25. #ifdef NEWAGE
  26.         utshort TTage;        /* Current ttable age */
  27.         UTSHORT TTageClock,    /* Count till next age tick */
  28.                 TTageRate;      /* new entry counts per age tick */
  29.         UTSHORT TTdepthage[MAXDEPTH+1];    /* Depth bonus for aging*/
  30.         UTSHORT newage = NEWAGE;    /* Initialization tuning parameter */
  31. #else
  32. unsigned int ttbllimit;
  33. unsigned int TTadd = 1;
  34. #endif
  35.  
  36. #ifdef HASHSTATS
  37. unsigned long ttdepthin[MAXDEPTH+1], ttdepthout[MAXDEPTH+1];
  38. unsigned long ttrehash[MAXrehash+1];
  39. unsigned long ttprobe[MAXDEPTH+1];
  40. unsigned long HashCnt, HashAdd, FHashCnt, FHashAdd, HashCol, THashCol;
  41. #endif
  42.  
  43. /* hashtable flags */
  44. #define truescore 0x0001
  45. #define lowerbound 0x0002
  46. #define upperbound 0x0004
  47. #define kingcastle 0x0008
  48. #define queencastle 0x0010
  49. #define evalflag 0x0020
  50.  
  51. void
  52. Initialize_ttable ()
  53. {
  54.   int doit = true;
  55.   if (rehash < 0) rehash = MAXrehash;
  56. while(doit && ttblsize > MINTTABLE){
  57.   ttable[0] = (struct hashentry *)malloc(sizeof(struct hashentry)*(ttblsize+rehash));
  58.   ttable[1] = (struct hashentry *)malloc(sizeof(struct hashentry)*(ttblsize+rehash));
  59.   if(ttable[0] == NULL || ttable[1] == NULL){
  60.   if(ttable[0] != NULL)free(ttable[0]);
  61.   ttblsize = ttblsize>>1;
  62.   } else doit = false;
  63. }
  64.   if(ttable[0] == NULL || ttable[1] == NULL){ ShowMessage(CP[70]);Exit(1);}
  65.   else {
  66.    int j;
  67. #ifdef notdef
  68.   printf("transposition table is %ld\n",ttblsize);
  69. #endif
  70. #ifdef NEWAGE
  71.         TTageRate = ttblsize / 1024;
  72.         TTdepthage[0] = TTdepthage[1] = newage;
  73.         for (j=2; j<=MAXDEPTH; j++)
  74.             TTdepthage[j] = TTdepthage[j-1]/2;
  75. /*    ZeroTTable(0); -- called in NewGame() */
  76. #else
  77.    ttbllimit = ttblsize<<1 - ttblsize>>2;
  78. #endif
  79.   }
  80. }
  81.  
  82. #define CB(i) (UCHAR) ((color[2 * (i)] ? 0x80 : 0)\
  83.    | (board[2 * (i)] << 4)\
  84.    | (color[2 * (i) + 1] ? 0x8 : 0)\
  85.    | (board[2 * (i) + 1]))
  86.  
  87. inline
  88. int
  89. ProbeTTable (SHORT side,
  90.         SHORT depth,
  91.         SHORT ply,
  92.         SHORT *alpha,
  93.         SHORT *beta,
  94.         SHORT *score)
  95.  
  96. /*
  97.  * Look for the current board position in the transposition table.
  98.  */
  99.  
  100. {
  101.     register struct hashentry *ptbl;
  102.     register SHORT i = 0;
  103.  
  104. #ifdef DEBUG
  105.     if(flag.nott)return false;
  106. #endif
  107. #ifdef HASHSTATS
  108.     ttprobe[depth]++;
  109. #endif
  110. #ifdef NEWAGE
  111.      /* Find entry within rehash window or return failure */
  112.      for (i=rehash, ptbl = &ttable[side][hashkey % ttblsize];
  113.           ptbl->hashbd != hashbd; ptbl++)
  114.        if (--i == 0) return false;
  115.      /* Update age of rediscovered node */
  116.           ptbl->age = TTage - TTdepthage[ptbl->depth];
  117. #else
  118.     ptbl = &ttable[side][hashkey % ttblsize];
  119.     while (true)
  120.       {
  121.      if (ptbl->depth == 0) return false;
  122.      if (ptbl->hashbd == hashbd) break;
  123.      if (++i > rehash) return false;
  124.      ptbl++;
  125.       }
  126. #endif
  127.  
  128.     PV = SwagHt = ptbl->mv;
  129.     if ((ptbl->depth >= (SHORT) depth) || abs(ptbl->score)>9000)
  130.       {
  131. #ifdef HASHTEST
  132.      for (i = 0; i < 32; i++)
  133.        {
  134.       if (ptbl->bd[i] != CB (i))
  135.         {
  136. #ifdef HASHSTATS
  137.             HashCol++;
  138.             ShowMessage (CP[51]); /*ttable collision detected*/
  139. #endif
  140.             break;
  141.         }
  142.        }
  143. #endif /* HASHTEST */
  144.  
  145. #ifdef HASHSTATS
  146.      ttdepthout[ptbl->depth]++;
  147.      HashCnt++;
  148. #endif
  149.  
  150.      if (ptbl->flags & truescore)
  151.        {
  152.       *score = ptbl->score;
  153.       /* adjust *score so moves to mate is from root */
  154.       if (*score > 9000) *score -= ply;
  155.       else if (*score < -9000) *score += ply;
  156.       *beta = -20000;
  157.        }
  158.      else if (ptbl->flags & lowerbound)
  159.        {
  160.       if (ptbl->score > *alpha)
  161. #ifdef notdef
  162.         *alpha = ptbl->score - 1;
  163. #endif
  164.       *alpha = ptbl->score;
  165.        }
  166. #ifdef DEBUG
  167.      if (debuglevel & 32)
  168.        {
  169.       algbr (PV >> 8, PV & 0xff, 0);
  170.       printf ("-get-> h=%lx d=%d s=%d p=%d a=%d b=%d %s\n", hashbd, depth, *score, ply, *alpha, *beta, mvstr);
  171.        }
  172. #endif
  173.      return (true);
  174.       }
  175.     return (false);
  176. }
  177.  
  178. inline
  179. int
  180. PutInTTable 
  181.       (SHORT side,
  182.         SHORT score,
  183.         SHORT depth,
  184.         SHORT ply,
  185.         SHORT alpha,
  186.         SHORT beta,
  187.         UTSHORT mv)
  188.  
  189. /*
  190.  * Store the current board position in the transposition table.
  191.  */
  192.  
  193.   {
  194.    register struct hashentry *ptbl;
  195.    register SHORT i = 0;
  196. #ifndef NEWAGE
  197.  
  198.    ptbl = &ttable[side][hashkey % ttblsize];
  199.    while (true)
  200.      {
  201.       if (ptbl->depth == 0) break;
  202.       if ((ptbl->hashbd) == hashbd) {
  203.           if (ptbl->depth > (UCHAR)depth) return false; else break;
  204.       }
  205.       if (++i > rehash)
  206.         {
  207. #ifdef HASHSTATS
  208.          THashCol++;
  209. #endif
  210.          ptbl -= rehash; /* Hey! it's already randomized. use the original location. */
  211.                      /* There is some discussion about thrashing.... */
  212.          break;
  213.         }
  214.       ptbl++;
  215.      }
  216.    TTadd++;
  217.    if (ptbl->depth > (UCHAR)depth) return false;
  218.  
  219. #else /* NEWAGE */
  220.    utshort old;
  221.         struct hashentry *oldest;
  222.  
  223.         /* Look for match or oldest entry to reuse */
  224.    /* Note that arithmetic on ages is intentionally modulo 65536 */
  225.         i = rehash;
  226.    oldest = ptbl = &ttable[side][hashkey % ttblsize];
  227.         old = TTage - ptbl->age;
  228.    while (ptbl->hashbd != hashbd) {
  229.        if (--i == 0) break;
  230.        ptbl++;
  231.        if ((TTage - ptbl->age) > old) {
  232.       old = TTage - ptbl->age;
  233.       oldest = ptbl;
  234.        }
  235.    }
  236.         if (i == 0) {
  237.             ptbl = oldest; /* reuse oldest entry */
  238. #ifdef HASHSTATS
  239.        THashCol++;
  240. #endif
  241.             if (--TTageClock == 0) {
  242.                 TTageClock = TTageRate;
  243.                 TTage++;        /* Everyone is now just a little older */
  244.        }
  245.    } else {
  246. /*!!!     if (ptbl->depth > (UCHAR)depth) return false;*/
  247.    }
  248. /*!!!*/      if (ptbl->depth > (UCHAR)depth) return false;
  249.         ptbl->age = TTage - TTdepthage[depth]; /* Set age of this node */
  250.  
  251. #endif /* NEWAGE */
  252. #ifdef HASHSTATS
  253.    HashAdd++;
  254. #endif
  255.    ptbl->hashbd = hashbd;
  256.    ptbl->depth = (UCHAR) depth;
  257.    ptbl->score = score;
  258.    ptbl->mv = mv;
  259. #ifdef DEBUG
  260.    if (debuglevel & 32)
  261.      {
  262.       algbr (mv >> 8, mv & 0xff, 0);
  263.       printf ("-add-> h=%lx d=%d s=%d p=%d a=%d b=%d %s\n", hashbd, depth, score, ply, alpha, beta, mvstr);
  264.      }
  265. #endif
  266.    if (score > beta)
  267.      {
  268.       ptbl->flags = lowerbound;
  269.       ptbl->score = beta + 1;
  270.      }
  271.    else
  272.           {
  273.       /* adjust score so moves to mate is from this ply */
  274.       if (score > 9000) score += ply;
  275.       else if (score < -9000) score -= ply;
  276.       ptbl->score = score;
  277.       ptbl->flags = truescore;
  278.      }
  279.  
  280. #ifdef HASHSTATS
  281.    ttdepthin[ptbl->depth]++;
  282.    ttrehash[i]++;
  283. #endif
  284. #ifdef HASHTEST
  285.    for (i = 0; i < 32; i++)
  286.      {
  287.       ptbl->bd[i] = CB (i);
  288.      }
  289. #endif /* HASHTEST */
  290.    return true;
  291.   }
  292.  
  293. void
  294. ZeroTTable (int iop) /* iop: 0= clear any, 1= clear agged */
  295.   {
  296. #ifdef NEWAGE
  297.    if(iop==0)
  298.      {
  299.       TTageClock = TTageRate;
  300.       TTage = newage+1; /* Zero entries are pre-expired. */
  301.       /* zero the age of all ttable entries */
  302.       memset(ttable[white],0,sizeof(struct hashentry)*(unsigned)(ttblsize+rehash));
  303.       memset(ttable[black],0,sizeof(struct hashentry)*(unsigned)(ttblsize+rehash));
  304.      }
  305.    else
  306.       /* Just add a major increment to TTage */
  307.       TTage += newage/5;  /* Just a guess */
  308. #else /* not NEWAGE */
  309.    if ((iop==0 && TTadd) || TTadd > ttbllimit)
  310.      {
  311.       memset(ttable[white],0,sizeof(struct hashentry)*(unsigned)(ttblsize+rehash));
  312.       memset(ttable[black],0,sizeof(struct hashentry)*(unsigned)(ttblsize+rehash));
  313.        TTadd = 0;
  314.       }
  315. #endif /* NEWAGE */
  316.  
  317. }
  318.  
  319. /************************* Hash table statistics ****************************/
  320.  
  321. #ifdef HASHSTATS
  322. long EADD,EGET;   /* Eval cache stats */
  323.  
  324. void
  325. ClearHashStats()  /* initialize the stats */
  326.   {
  327.    memset ((CHAR *) ttdepthin, 0, sizeof (ttdepthin));
  328.    memset ((CHAR *) ttdepthout, 0, sizeof (ttdepthout));
  329.    memset ((CHAR *) ttrehash, 0, sizeof (ttrehash));
  330.    memset ((CHAR *) ttprobe, 0, sizeof (ttprobe));
  331.    HashAdd = HashCnt = THashCol = HashCol = FHashCnt = FHashAdd = 0;
  332.    EADD = EGET = 0;
  333.   }
  334.  
  335. void
  336. ShowHashStats()   /* print the stats */
  337.   {
  338.    int ii;
  339.    printf("Probe: ");
  340.    for(ii=0;ii<MAXDEPTH;ii++)
  341.       if (ttprobe[ii])
  342.          printf(" %d:%ld", ii, ttprobe[ii]);
  343.    printf("\nIn/Out: ");
  344.    for(ii=0;ii<MAXDEPTH;ii++)
  345.       if (ttdepthin[ii] || ttdepthout[ii])
  346.          printf(" %d:%ld/%ld", ii, ttdepthin[ii], ttdepthout[ii]);
  347.    printf("\nRehash: ");
  348.    for(ii=0;ii<=MAXrehash;ii++)
  349.       printf(" %ld", ttrehash[ii]);
  350.    printf("\n");
  351.    printf (CP[71],
  352.       HashAdd, HashCnt, THashCol, HashCol,FHashCnt, FHashAdd);
  353. #ifdef CACHE
  354.    printf ("cache in/out: %ld/%ld\n", EADD, EGET);
  355. #endif
  356.   }
  357. #endif
  358.  
  359. /************************* Hash File Stuf ****************************/
  360. #ifdef HASHFILE
  361. #define frehash 6
  362.  
  363.      struct fileentry
  364.      {
  365.        UCHAR bd[32];
  366.        UCHAR f, t, flags, depth, sh, sl;
  367.      };
  368.  
  369. FILE *hashfile = NULL;
  370. unsigned long HFileSize;      /* Nunber of fileentry records in hash file */
  371.  
  372. void 
  373. CreateHashFile(long sz)
  374. /* NOTE: If sz is Odd the black and white positions will be
  375.    scrambled (Is this good or bad?) */
  376.   {
  377.    if ((hashfile = fopen (HASHFILE, RWA_ACC)))  /* old file */
  378.      {   /* chech size, warn if shrinking? */
  379.       fseek (hashfile, 0L, SEEK_END);
  380.       HFileSize = ftell (hashfile) / sizeof (struct fileentry);
  381.       if (sz < HFileSize) sz = HFileSize;
  382.       fseek (hashfile, 0L, SEEK_SET);
  383.      }
  384.    else if (sz)
  385.      {   /* create new file only if we have a size */
  386.       hashfile = fopen (HASHFILE, WA_ACC);
  387.      }
  388.    if (hashfile != NULL)
  389.      {
  390.       long j;
  391.       struct fileentry n[64]; /* Write a bunch at a time */
  392.       
  393.       memset ((CHAR *) n, 0, sizeof (n));
  394. /*    n.f = n.t = 0; */
  395. /*    n.flags = 0; */
  396. /*    n.depth = 0; */
  397. /*    n.sh = n.sl = 0; */
  398.       for (j = 0; j < sz; j += 64)
  399.          fwrite (&n, sizeof (struct fileentry), sz-j<64 ? sz-j: 64, hashfile);
  400.       fclose (hashfile);
  401.       hashfile = NULL;
  402.      }
  403.    else
  404.      {
  405.       sprintf (msg,CP[79], HASHFILE);
  406.       ShowMessage(msg);
  407.      }
  408.   }
  409.   
  410. void 
  411. OpenHashFile() /* try to open hash file */
  412.   {
  413.    hashfile = fopen (HASHFILE, RWA_ACC);
  414.    if (hashfile)
  415.      {
  416.       fseek (hashfile, 0L, SEEK_END);
  417.       HFileSize = ftell (hashfile) / sizeof (struct fileentry);
  418.      }
  419.   }
  420.  
  421. void
  422. CloseHashFile()
  423.   {
  424.    /* remember to write accumulated statistics if we keep such */
  425.    if (hashfile)
  426.       fclose (hashfile);
  427.    hashfile = NULL;
  428.   }
  429.   
  430. void 
  431. TestHashFile()
  432.   {
  433.    int iopendit = false;
  434.    if (!hashfile)
  435.      {
  436.       OpenHashFile();
  437.       iopendit = (hashfile != NULL);
  438.      }
  439.    if (hashfile)
  440.      {
  441.       int i; 
  442.       long j;
  443.       long nr[MAXDEPTH+1];
  444.       struct fileentry n;
  445.       
  446.       printf (CP[18]);
  447.       for (i = 0; i < MAXDEPTH; i++)
  448.          nr[i] = 0;
  449.       fseek (hashfile, 0L, SEEK_SET);
  450.       for (j = 0; j < HFileSize; j++)
  451.         {
  452.          fread (&n, sizeof (struct fileentry), 1, hashfile);
  453.          if (n.depth > MAXDEPTH){printf("ERROR\n");exit(1);}
  454.          if (n.depth)
  455.            {
  456.             nr[n.depth]++;
  457.             nr[0]++;
  458.            }
  459.         }
  460.       printf (CP[36], nr[0], HFileSize);
  461.       for (i = 1; i <= MAXDEPTH; i++)
  462.          if (nr[i])
  463.             printf (" %d:%ld", i,nr[i]);
  464.       printf ("\n");
  465.       if (iopendit)
  466.          CloseHashFile();
  467.      }
  468.   }
  469.  
  470. int 
  471. Fbdcmp(UCHAR *a,UCHAR *b)
  472.   {
  473.    register int i;
  474.    for(i = 0;i<32;i++)
  475.       if(a[i] != b[i])
  476.          return false;
  477.    return true;
  478.   }
  479.  
  480. int
  481. ProbeFTable (SHORT side,
  482.       SHORT depth,
  483.       SHORT ply,
  484.       SHORT *alpha,
  485.       SHORT *beta,
  486.       SHORT *score)
  487.  
  488. /*
  489. * Look for the current board position in the persistent transposition table.
  490. */
  491.  
  492.   {
  493.    register SHORT i;
  494.    register unsigned long hashix;
  495.    struct fileentry new, t;
  496. #ifdef DEBUG
  497.    if(flag.noft)return false;
  498. #endif
  499.    
  500.    hashix = ((side == white) ? (hashkey & 0xFFFFFFFE) : (hashkey | 1)) % HFileSize;
  501.    
  502.    for (i = 0; i < 32; i++)
  503.       new.bd[i] = CB (i);
  504.    new.flags = 0;
  505.    if (Mvboard[kingP[side]] == 0)
  506.      {
  507.       if (Mvboard[qrook[side]] == 0)
  508.          new.flags |= queencastle;
  509.       if (Mvboard[krook[side]] == 0)
  510.       new.flags |= kingcastle;
  511.      }
  512.    for (i = 0; i < frehash; i++)
  513.      {
  514.       fseek (hashfile,
  515.          sizeof (struct fileentry) * ((hashix + 2 * i) % (HFileSize)),
  516.          SEEK_SET);
  517.       fread (&t, sizeof (struct fileentry), 1, hashfile);
  518.       if (!t.depth) break;
  519.       if(!Fbdcmp(t.bd, new.bd)) continue;
  520.       if (((SHORT) t.depth >= depth) 
  521.          && (new.flags == (UTSHORT)(t.flags & (kingcastle | queencastle))))
  522.         {
  523. #ifdef HASHSTATS
  524.          FHashCnt++;
  525. #endif
  526.          PV = (t.f << 8) | t.t;
  527.          *score = (t.sh << 8) | t.sl;
  528.          /* adjust *score so moves to mate is from root */
  529.          if (*score > 9000)
  530.             *score -= ply;
  531.          else if (*score < -9000)
  532.             *score += ply;
  533.          if (t.flags & truescore)
  534.            {
  535.             *beta = -20000;
  536.            }
  537.          else if (t.flags & lowerbound)
  538.            {
  539.             if (*score > *alpha)
  540.                *alpha = *score - 1;
  541.            }
  542.          else if (t.flags & upperbound)
  543.            {
  544.             if (*score < *beta)
  545.                *beta = *score + 1;
  546.            }
  547.          return (true);
  548.         }
  549.      }
  550.    return (false);
  551.   }
  552.  
  553. void
  554. PutInFTable (SHORT side,
  555.       SHORT score,
  556.       SHORT depth,
  557.       SHORT ply,
  558.       SHORT alpha,
  559.       SHORT beta,
  560.       UTSHORT f,
  561.       UTSHORT t)
  562.  
  563. /*
  564. * Store the current board position in the persistent transposition table.
  565. */
  566.  
  567.   {
  568.    register UTSHORT i;
  569.    register unsigned long hashix;
  570.    struct fileentry new, tmp;
  571.    
  572.    hashix = ((side == white) ? (hashkey & 0xFFFFFFFE) : (hashkey | 1)) % HFileSize;
  573.    for (i = 0; i < 32; i++) new.bd[i] = CB (i);
  574.    new.f = (UCHAR) f;
  575.    new.t = (UCHAR) t;
  576.    if (score < alpha)
  577.       new.flags = upperbound;
  578.    else
  579.       new.flags = ((score > beta) ? lowerbound : truescore);
  580.    if (Mvboard[kingP[side]] == 0)
  581.      {
  582.       if (Mvboard[qrook[side]] == 0)
  583.          new.flags |= queencastle;
  584.       if (Mvboard[krook[side]] == 0)
  585.          new.flags |= kingcastle;
  586.      }
  587.    new.depth = (UCHAR) depth;
  588.    /* adjust *score so moves to mate is from root */
  589.    if (score > 9000)
  590.       score += ply;
  591.    else if (score < -9000)
  592.       score -= ply;
  593.  
  594.    new.sh = (UCHAR) (score >> 8);
  595.    new.sl = (UCHAR) (score & 0xFF);
  596.    
  597.    for (i = 0; i < frehash; i++)
  598.      {
  599.       fseek (hashfile,
  600.          sizeof (struct fileentry) * ((hashix + 2 * i) % (HFileSize)),
  601.          SEEK_SET);
  602.       if(fread (&tmp, sizeof (struct fileentry), 1, hashfile) == 0){perror("hashfile");exit(1);}
  603.       if (tmp.depth && !Fbdcmp(tmp.bd,new.bd))continue;
  604.       if ((SHORT) tmp.depth < new.depth)
  605.         {
  606.          fseek (hashfile,
  607.             sizeof (struct fileentry) * ((hashix + 2 * i) % (HFileSize)),
  608.             SEEK_SET);
  609.          fwrite (&new, sizeof (struct fileentry), 1, hashfile);
  610. #ifdef HASHSTATS
  611.          FHashAdd++;
  612. #endif
  613.         }
  614.       break;
  615.      }
  616.   }
  617.  
  618. #endif /* HASHFILE */
  619. /********************** Repitition cache ***********************/
  620. SHORT rpthash[2][256];
  621.  
  622. void
  623. ZeroRPT (void)
  624. {
  625.    memset ((CHAR *) rpthash, 0, sizeof (rpthash));
  626. }
  627. /********************** Hash code stuff ***********************/
  628. /*
  629.  * In a networked enviroment gnuchess might be compiled on different hosts
  630.  * with different random number generators, that is not acceptable if they
  631.  * are going to share the same transposition table.
  632.  */
  633. unsigned long int next = 1;
  634.  
  635. #if defined NEWURAND
  636. /*
  637. This code copied from:
  638.  
  639. G. Wiesenekker. ZZZZZZ a chess program.
  640. Copyright (C) 1993  G. Wiesenekker
  641. E-mail: wiesenecker@sara.nl
  642.  
  643. A 32 bit random number generator. An implementation in C of the algorithm given by
  644. Knuth, the art of computer programming, vol. 2, pp. 26-27. We use e=32, so 
  645. we have to evaluate y(n) = y(n - 24) + y(n - 55) mod 2^32, which is implicitly
  646. done by unsigned arithmetic.
  647. */
  648.  
  649. unsigned int urand(void)
  650. {
  651.    /*
  652.    random numbers from Mathematica 2.0.
  653.    SeedRandom = 1;
  654.    Table[Random[Integer, {0, 2^32 - 1}]
  655.    */
  656.    static unsigned long x[55] =
  657.    {
  658.       1410651636UL,
  659.       3012776752UL,
  660.       3497475623UL,
  661.       2892145026UL,
  662.       1571949714UL,
  663.       3253082284UL,
  664.       3489895018UL,
  665.       387949491UL, 
  666.       2597396737UL,
  667.       1981903553UL,
  668.       3160251843UL,
  669.       129444464UL, 
  670.       1851443344UL,
  671.       4156445905UL,
  672.       224604922UL,
  673.       1455067070UL, 
  674.       3953493484UL,
  675.       1460937157UL,
  676.       2528362617UL,
  677.       317430674UL, 
  678.       3229354360UL,
  679.       117491133UL,
  680.       832845075UL,
  681.       1961600170UL, 
  682.       1321557429UL,
  683.       747750121UL,
  684.       545747446UL,
  685.       810476036UL,
  686.       503334515UL, 
  687.       4088144633UL,
  688.       2824216555UL,
  689.       3738252341UL,
  690.       3493754131UL, 
  691.       3672533954UL,
  692.       29494241UL,
  693.       1180928407UL,
  694.       4213624418UL,
  695.       33062851UL, 
  696.       3221315737UL,
  697.       1145213552UL,
  698.       2957984897UL,
  699.       4078668503UL, 
  700.       2262661702UL,
  701.       65478801UL,
  702.       2527208841UL,
  703.       1960622036UL,
  704.       315685891UL, 
  705.       1196037864UL,
  706.       804614524UL,
  707.       1421733266UL,
  708.       2017105031UL, 
  709.       3882325900UL,
  710.       810735053UL,
  711.       384606609UL,
  712.       2393861397UL
  713.    };
  714.    static int init = TRUE;
  715.    static unsigned long y[55];
  716.    static int j, k;
  717.    unsigned long ul;
  718.    
  719.    if (init)
  720.    {
  721.       int i;
  722.       
  723.       init = FALSE;
  724.       for (i = 0; i < 55; i++)
  725.          y[i] = x[i];
  726.       j = 24 - 1;
  727.       k = 55 - 1;
  728.    }
  729.    
  730.    ul = (y[k] += y[j]);
  731.    if (--j < 0) j = 55 - 1;
  732.    if (--k < 0) k = 55 - 1;
  733.    return((unsigned int)ul);
  734. }
  735.  
  736. #else
  737. unsigned int
  738. urand (void)
  739. {
  740.   next *= 1103515245;
  741.   next += 12345;
  742.   return ((unsigned int) (next >> 16) & 0xFFFF);
  743. }
  744. #endif
  745.  
  746. void
  747. gsrand (unsigned int seed)
  748. {
  749.   next = seed;
  750. }
  751.  
  752. unsigned long hashkey, hashbd;
  753. struct hashval hashcode[2][7][64];
  754. #ifdef LONG64
  755. #define XRANDTSIZE 8000
  756. #else
  757. #define XRANDTSIZE 4000
  758. #endif
  759.  
  760. #if !defined NOXRAND
  761. unsigned int
  762. xrand (int a, unsigned int b[])
  763. {
  764.   unsigned int i, r, r2, loop;
  765.   unsigned int j, c;
  766.   if (!a)
  767.     {
  768.       for (i = 0; i < XRANDTSIZE; i++)
  769.    b[i] = 0;
  770.       return 0;
  771.     }
  772.   loop = true;
  773.   while (loop)
  774.     {
  775.       r = r2 = urand ();
  776.       c = 0;
  777.       while(r2)
  778.    {
  779.      c += r2 & 1;
  780.      r2 >>= 1;
  781.    }
  782.       if (c < 8)
  783.    continue;
  784.       loop = false;
  785.       for (i = 0; i < a; i++)
  786.    if (r == b[i])
  787.      {
  788.        loop = true;
  789.        break;
  790.      }
  791.       if (!loop)
  792.    {
  793.      b[a] = r;
  794.      return r;
  795.    }
  796.     }
  797.   return 0;
  798. }
  799. #else
  800. #define xrand(a,b) urand()
  801. #endif
  802.  
  803. void
  804. InitHashCode(unsigned int seed)
  805.   {
  806.    SHORT l, c, p;
  807.    unsigned int t[XRANDTSIZE];
  808.    int cnt = 0;
  809.  
  810.    xrand(cnt++,t);
  811.    gsrand (seed); /* idealy we would preserve the old seed but... */
  812.    for (c = white; c <= black; c++)
  813.      for (p = pawn; p <= king; p++)
  814.       for (l = 0; l < 64; l++)
  815.         {
  816.          hashcode[c][p][l].key = (((unsigned long) xrand (cnt++,t)));
  817.          hashcode[c][p][l].key += (((unsigned long) xrand (cnt++,t)) << 16);
  818.          hashcode[c][p][l].bd = (((unsigned long) xrand (cnt++,t)));
  819.          hashcode[c][p][l].bd += (((unsigned long) xrand (cnt++,t)) << 16);
  820. #ifdef LONG64
  821.          hashcode[c][p][l].key += (((unsigned long) xrand (cnt++,t)) << 32);
  822.          hashcode[c][p][l].key += (((unsigned long) xrand (cnt++,t)) << 48);
  823.          hashcode[c][p][l].bd += (((unsigned long) xrand (cnt++,t)) << 32);
  824.          hashcode[c][p][l].bd += (((unsigned long) xrand (cnt++,t)) << 48);
  825. #endif
  826.         }
  827.   }
  828.  
  829.  
  830.  
  831.  
  832.