home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / game / uchess-2.89.lha / UChess / src / search.c < prev    next >
C/C++ Source or Header  |  1994-08-05  |  55KB  |  1,971 lines

  1. // about splitting the search into a new thread, perhaps
  2. // the best place to check the msg queue is in UpdateClocks,
  3. // called from ElapsedTime, you would set a flag in here
  4. // before you call each ElapsedTime, telling the system
  5. // to check the msg queue in there for any new moves
  6.  
  7. //char strx[40];
  8. #define CLEARHISTBETWEENMOVES // old way to handle hist table
  9. /*
  10.  * search.c - C source for GNU CHESS
  11.  *
  12.  * Copyright (c) 1988,1989,1990 John Stanback Copyright (c) 1992 Free Software
  13.  * Foundation
  14.  *
  15.  * This file is part of GNU CHESS.
  16.  *
  17.  * GNU Chess is free software; you can redistribute it and/or modify it under
  18.  * the terms of the GNU General Public License as published by the Free
  19.  * Software Foundation; either version 2, or (at your option) any later
  20.  * version.
  21.  *
  22.  * GNU Chess is distributed in the hope that it will be useful, but WITHOUT ANY
  23.  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  24.  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  25.  * details.
  26.  *
  27.  * You should have received a copy of the GNU General Public License along with
  28.  * GNU Chess; see the file COPYING.  If not, write to the Free Software
  29.  * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  30.  */
  31. #include "gnuchess.h"
  32.  
  33. #define PTRHEIGHT 55
  34. extern UWORD chip myPointer[];
  35. #include <proto/intuition.h>
  36. extern struct Window __aligned *wG;
  37. extern int __aligned SupervisorMode;
  38.  
  39.  
  40. #define ZEROALLBETWEENPLY 1
  41.  
  42. #ifdef QUIETBACKGROUND
  43. short __aligned background = 0;
  44.  
  45. #endif /* QUIETBACKGROUND */
  46. static short int __aligned DepthBeyond;
  47. short __aligned Threat[MAXDEPTH];
  48. unsigned short int __aligned PrVar[MAXDEPTH];
  49. extern short int ISZERO;
  50. extern long EADD,EGET;
  51. extern char mvstr[8][8];
  52. extern short int recycle;
  53. extern int __aligned GetEntryDone;
  54. extern int trying_again;
  55. short int __aligned myflagdeepnull=0xff;
  56. int got_20000=0;
  57. short __aligned ThreatSave[MAXDEPTH]; /* tom@izf.tno.nl */
  58. extern short __aligned QueenCheck[MAXDEPTH]; /* tom@izf.tno.nl */
  59. #if defined NULLMOVE || defined DEEPNULL
  60. short int __aligned no_null;
  61. short int __aligned null;         /* Null-move already made or not */
  62. short int __aligned PVari;        /* Is this the PV */
  63. #endif
  64. #ifdef DEBUG40
  65. extern int whichway;
  66. #endif
  67. #ifdef DEBUG
  68. unsigned short __aligned DBLINE[MAXDEPTH];
  69. struct leaf __aligned *dbptr;
  70.  
  71. #endif
  72. short __aligned start_stage;
  73. short __aligned thrashing_tt; /* must we recycle slots at random. TomV */
  74. short int __aligned zwndw;
  75.  
  76. #include "ataks3.h"
  77.  
  78. #define __USE_SYSBASE
  79. #include <proto/exec.h>
  80.  
  81. extern long OrigResponse;
  82. extern int global_tmp_score;
  83. extern int previous_score;
  84. short __aligned myflagpvs=true;
  85. int __aligned backsrchaborted=0;
  86. int __aligned Sdepth2=0;
  87. extern int MoveNowOK;
  88. extern int procpri;
  89. extern struct Process *myproc;
  90. extern struct MsgPort *InThreadPort;
  91. extern struct myMsgStruct Global_Message;
  92.  
  93. int __aligned RealThink=0;
  94.  
  95. #ifdef SPEED_PRECALC
  96. unsigned short __aligned PreCalcedHint;
  97. unsigned short __aligned PreCalcedMove;
  98. int DoPreCalc (unsigned INTSIZE *, INTSIZE);
  99. #endif
  100. int __aligned Castled[2]={0,0};
  101. int __aligned myEnPassant[2]={0,0};
  102.  
  103. #include "ttable.c"
  104.  
  105.  
  106. short int __inline repetition (void);
  107.  
  108.  
  109. #include "debug41.h"
  110. /* ............    MOVE GENERATION & SEARCH ROUTINES    .............. */
  111.  
  112. //#define STRAIGHT4PL70 1 // for repetiton code
  113. #ifndef STRAIGHT4PL70
  114. // improved Kong Sian Repetition
  115.  
  116. short int __inline
  117. repetition ()
  118.  
  119. /*  Check for draw by threefold repetition.  */
  120.  
  121. {
  122.   register short i, cnt;
  123.  
  124.   cnt = 0;
  125.   /* try to avoid work */
  126.   if (GameCnt > Game50 + 3)
  127.     for (i = GameCnt; i >= Game50; i--)
  128.       if (hashbd == GameList[i].hashbd && hashkey == GameList[i].hashkey)
  129.         cnt++;
  130.  
  131.   return cnt;
  132. }
  133.  
  134. #else // straight 4pl70 repetition
  135. short int __inline
  136. repetition ()
  137.  
  138. /*  Check for draw by threefold repetition.  */
  139.  
  140. {
  141.   register SHORT i, c, cnt;
  142.   register SHORT m;
  143.   SHORT b[64];
  144.  
  145.   cnt = c = 0;
  146.   /* try to avoid work */
  147.   if (GameCnt > Game50 + 3)
  148.     {
  149.       ClearMem(b,sizeof(b));
  150.       for (i = GameCnt; i >= Game50; i--)
  151.     {
  152.       m = GameList[i].gmove;
  153.       /* does piece exist on diff board? */
  154.       if (b[m & 0x3f])
  155.         {
  156.           /* does diffs cancel out, piece back? */
  157.           if ((b[m >> 8] += b[m & 0x3f]) == 0)
  158.         --c;
  159.           b[m & 0x3f] = 0;
  160.         }
  161.       else
  162.         {
  163.           /* create diff */
  164.           ++c;
  165.           /* does diff cancel out another diff? */
  166.           if (!(b[m >> 8] -= (b[m & 0x3f] = board[m & 0x3f] +
  167.                   (color[m & 0x3f] << 8))))
  168.         --c;
  169.         }
  170.       /* if diff count is 0 we have a repetition */
  171.       if (c == 0)
  172.         if ((i ^ GameCnt) & 1)
  173.           cnt++;
  174.     }
  175.     }
  176.   return cnt;
  177. }
  178.  
  179. #endif // striaght 4pl70 repetition
  180.  
  181. int plyscore, globalscore;
  182. int
  183. pick (short int p1, short int p2)
  184.  
  185. /*
  186.  * Find the best move in the tree between indexes p1 and p2. Swap the best
  187.  * move into the p1 element.
  188.  *
  189.  */
  190. {
  191.   register struct leaf *p, *q, *r, *k;
  192.   register s0;
  193.   struct leaf temp;
  194.  
  195.   k = p = &Tree[p1];
  196.   q = &Tree[p2];
  197.   s0 = p->score;
  198.   for (r = p + 1; r <= q; r++)
  199.     if (r->score != 9999 && (r->score) > s0) // this is the PL70 way!
  200. //    if ((r->score) > s0) 
  201.       {
  202.     s0 = (r->score);
  203.     p = r;
  204.       }
  205.   if (p != k)
  206.     {
  207.       temp = *p;
  208.       *p = *k;
  209.       *k = temp;
  210.       return true;
  211.     }
  212.   return false;
  213. }
  214.  
  215. #ifdef DEBUG
  216. unsigned short trace[MAXDEPTH];
  217. char traceline[256];
  218. unsigned short tracelog[MAXDEPTH];
  219. int tracen = 0;
  220. int traceflag = 0;
  221. int traceply = 0;
  222. #endif
  223. int __aligned bookflag = false;
  224. int __aligned Jscore = 0;
  225.  
  226. static int __aligned TCcount, TCleft;
  227. void
  228. SelectMove (short int side, short int iop)
  229. /*
  230.  * Select a move by calling function search() at progressively deeper ply
  231.  * until time is up or a mate or draw is reached. An alpha-beta window of
  232.  * -Awindow to +Bwindow points is set around the score returned from the
  233.  * previous iteration. If Sdepth != 0 then the program has correctly
  234.  * predicted the opponents move and the search will start at a depth of
  235.  * Sdepth+1 rather than a depth of 1.
  236.  */
  237. {
  238.   static short int i, tempb, tempc, tempsf, tempst, xside, rpt;
  239.   static short int alpha, beta, score;
  240.   static struct GameRec *g;
  241.   int earlyflag;
  242.  
  243. #ifndef CLEARHISTBETWEENMOVES // old way to handle hist table
  244.   int cnt;
  245.   ULONG *tmphistptr;
  246. #endif
  247.  
  248.   char mystr[32];
  249.   short InChkDummy;
  250.   short start_score;
  251. #ifdef DEBUG
  252.  
  253. if(debuglevel & (512|1024)){
  254.     char b[32];
  255.     short c1,c2,r1,r2;
  256. tracen=0;
  257. traceflag = false;
  258. traceply = 0;
  259. tracelog[0]=0;
  260. while(true){
  261.     /*printf("debug?");
  262.     gets(b);*/
  263.     if(b[0] == 'p')traceply = atoi(&b[1]);
  264.     else
  265.     if(b[0] == '\0')break;
  266.     else{
  267.         c1 = b[0] - 'a';
  268.               r1 = b[1] - '1';
  269.               c2 = b[2] - 'a';
  270.               r2 = b[3] - '1';
  271.               trace[++tracen] = (locn (r1, c1) << 8) | locn (r2, c2);
  272.     }
  273.     if(tracen == 0 && traceply >0)traceflag = true;
  274.     }
  275.     
  276. }
  277. #endif
  278.  
  279. //  InitializeStats(); // MY FIX FOR UNDO PROBLEMS!!! TMP!!!
  280.  
  281. if (!SupervisorMode)
  282.  SetPointer(wG,myPointer,PTRHEIGHT,0x10L,0L,0L);
  283. got_20000 = 0;
  284. if (iop != 2)
  285.  {
  286.   RealThink = 1;
  287.   if (!GetEntryDone)
  288.    {
  289.     Global_Message.myData = 1L;
  290.     Forbid();
  291.     PutMsg(InThreadPort,(struct Message *)&Global_Message);
  292.     Permit();
  293.     GetEntryDone = 1;
  294.    }
  295.  }
  296. else
  297.  RealThink = 0;
  298. start_again:
  299.   flag.timeout = false;
  300.   flag.back = flag.musttimeout = false;
  301.   INCscore = 0; // new from 4pl70, do I want this?
  302.   xside = side ^ 1;
  303.   recycle = (GameCnt % rehash) - rehash;
  304.   /* if background mode set to infinite */
  305.   if (iop == 2)
  306.     {
  307.       Sdepth2 = 0;
  308.       (void)SetTaskPri((struct Task *)myproc,0);
  309.       OrigResponse = ResponseTime = 9999999;
  310. #ifdef QUIETBACKGROUND
  311.       background = true;
  312. #endif /* QUIETBACKGROUND */
  313.     }
  314.   else
  315.     {
  316.       player = side;
  317.       if (TCflag)
  318.     {
  319.       TCcount = 0;
  320. #ifdef QUIETBACKGROUND
  321.       background = false;
  322. #endif /* QUIETBACKGROUND */
  323.       if (TimeControl.moves[side] < 1)
  324.         TimeControl.moves[side] = 1;
  325.       /* special case time per move specified */
  326.       if (flag.onemove)
  327.         {
  328.           OrigResponse = ResponseTime = TimeControl.clock[side] - 100;
  329.           TCleft = 0;
  330.         }
  331.       else
  332.         {
  333.           /* calculate avg time per move remaining */
  334.           TimeControl.clock[side] += TCadd;
  335.  
  336.           ResponseTime = (TimeControl.clock[side]) / (((TimeControl.moves[side]) * 2) + 1);
  337.           TCleft = (int)ResponseTime / 3;
  338.           ResponseTime +=