alphabeta.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /* This file contains the alphabeta search for CHESS.
  2. Copyright (C) 1986 Free Software Foundation, Inc.
  3. This file is part of CHESS.
  4. CHESS is distributed in the hope that it will be useful,
  5. but WITHOUT ANY WARRANTY. No author or distributor
  6. accepts responsibility to anyone for the consequences of using it
  7. or for whether it serves any particular purpose or works at all,
  8. unless he says so in writing. Refer to the CHESS General Public
  9. License for full details.
  10. Everyone is granted permission to copy, modify and redistribute
  11. CHESS, but only under the conditions described in the
  12. CHESS General Public License. A copy of this license is
  13. supposed to have been given to you along with CHESS so you
  14. can know your rights and responsibilities. It should be in a
  15. file named COPYING. Among other things, the copyright notice
  16. and this notice must be preserved on all copies. */
  17. #include <stdio.h>
  18. #include <sys/types.h>
  19. #include <sys/time.h>
  20. #include "gnuchess.h"
  21. #define in_check(bd) FALSE
  22. #ifdef TREEPOS
  23. #define fast_eval ((bd[TOMOVE].moved == WHITE) ? bd[WMAT].moved - bd[BMAT].moved + bd[WPOS].moved - bd[BPOS].moved : bd[BMAT].moved - bd[WMAT].moved + bd[BPOS].moved - bd[WPOS].moved)
  24. #else
  25. #define fast_eval ((bd[TOMOVE].moved == WHITE) ? bd[WMAT].moved - bd[BMAT].moved : bd[BMAT].moved - bd[WMAT].moved)
  26. #endif TREEPOS
  27. int iv = 0;
  28. extern int stacktot,bestfrom,bestto,maxdepth,compare(),sorttype,histtot,bestmove;
  29. extern int snodestot,fnodestot,termnodes,treenodes;
  30. extern struct mvlist stack[MAXSTACK];
  31. extern struct mvlist game[MAXGAME];
  32. extern struct timeval timcpu;
  33. struct pvstr pv[20];
  34. /*
  35. * quies conducts a quiescence search on the given board for
  36. * depth more ply with the supplied alpha and beta cutoff values.
  37. * (cf. Thompson, Advances in Computer Chess 3, page 52.)
  38. */
  39. #ifdef QUIES
  40. int quies(bd,alpha,beta,depth)
  41. struct bdtype bd[120];
  42. int alpha,beta,depth;
  43. {
  44. int i,width,value;
  45. struct mvlist moves[MAXMOVES];
  46. termnodes++;
  47. value = fast_eval;
  48. if (depth >= MAXQUIES)
  49. return(value);
  50. if (value >= alpha)
  51. {
  52. if (value >= beta)
  53. return(beta);
  54. alpha = value;
  55. }
  56. width = generate(bd,moves);
  57. for (i = 0; i < width; i++)
  58. if (moves[i].flags & CAPFLAG)
  59. {
  60. #ifdef SEARCHTREE
  61. printf("\tMake: ");
  62. if (moves[i].flags & NULLMV)
  63. printf("null\n");
  64. else {
  65. lin_to_alg(moves[i].from,stdout);
  66. lin_to_alg(moves[i].to,stdout);
  67. putchar('\n');
  68. }
  69. #endif SEARCHTREE
  70. makemove(moves[i],bd);
  71. value = -quies(bd,-beta,-alpha,depth+1);
  72. #ifdef SEARCHTREE
  73. printf("\tUnmake: ");
  74. if (moves[i].flags & NULLMV)
  75. printf("null\n");
  76. else {
  77. lin_to_alg(moves[i].from,stdout);
  78. lin_to_alg(moves[i].to,stdout);
  79. putchar('\n');
  80. }
  81. #endif SEARCHTREE
  82. unmakemove(moves[i],bd);
  83. if (value > alpha) /* An improvement */
  84. {
  85. if (value >= beta)
  86. return(beta);
  87. alpha = value;
  88. }
  89. }
  90. return(alpha);
  91. }
  92. #endif QUIES
  93. /*
  94. * search conducts an alphabeta search on the given board for
  95. * depth more ply with the supplied alpha and beta cutoff values.
  96. * (cf. Thompson, Advances in Computer Chess 3, page 52.)
  97. */
  98. int search(bd,alpha,beta,depth)
  99. struct bdtype bd[120];
  100. int alpha,beta,depth;
  101. {
  102. int i,width,value;
  103. struct mvlist moves[MAXMOVES];
  104. treenodes++;
  105. #ifdef QUIES
  106. depth--;
  107. if (depth == (maxdepth-1))
  108. #else
  109. if (depth <= 0)
  110. {
  111. termnodes++;
  112. treenodes--;
  113. return(fast_eval);
  114. }
  115. if (depth == maxdepth)
  116. #endif QUIES
  117. width = pps(bd,moves);
  118. else
  119. width = generate(bd,moves);
  120. for (i = 0; i < width; i++)
  121. {
  122. makemove(moves[i],bd);
  123. #ifdef SEARCHTREE
  124. printf("\tMake: ");
  125. lin_to_alg(moves[i].from,stdout);
  126. lin_to_alg(moves[i].to,stdout);
  127. putchar('\n');
  128. #endif SEARCHTREE
  129. #ifdef QUIES
  130. if (depth > 0)
  131. value = -search(bd,-beta,-alpha,depth);
  132. else
  133. value = -quies(bd,-beta,-alpha,maxdepth);
  134. #else
  135. value = -search(bd,-beta,-alpha,depth-1);
  136. #endif QUIES
  137. #ifdef SEARCHTREE
  138. printf("\tUnmake: ");
  139. lin_to_alg(moves[i].from,stdout);
  140. lin_to_alg(moves[i].to,stdout);
  141. putchar('\n');
  142. #endif SEARCHTREE
  143. unmakemove(moves[i],bd);
  144. if (value > alpha) /* An improvement */
  145. {
  146. #ifdef QUIES
  147. if (depth == (maxdepth-1))
  148. #else
  149. if (depth == maxdepth)
  150. #endif QUIES
  151. {
  152. #ifdef SEARCHTREE
  153. printf("Newbest: ");
  154. lin_to_alg(moves[i].from,stdout);
  155. lin_to_alg(moves[i].to,stdout);
  156. putchar('\n');
  157. #endif SEARCHTREE
  158. bestfrom = moves[i].from;
  159. bestto = moves[i].to;
  160. moves[i].score = value;
  161. }
  162. if (value >= beta) /* A cutoff */
  163. return(beta);
  164. alpha = value;
  165. }
  166. }
  167. return(alpha);
  168. }
  169. /*
  170. * increm is an attempt at creating iterative deepening, which
  171. * is not generally useful with the overall design of this
  172. * program due to a total lack of positional knowledge at
  173. * terminal positions (by design).
  174. */
  175. increm(bd,depth)
  176. struct bdtype bd[120];
  177. {
  178. int value,from,to,width,alpha,beta,index;
  179. float timused;
  180. struct mvlist moves[MAXMOVES];
  181. value = 0;
  182. width = pps(bd,moves);
  183. for (maxdepth = 1; maxdepth <= depth; maxdepth++)
  184. {
  185. printf("Ply %d: ",maxdepth); fflush(stdout);
  186. alpha = value - 100;
  187. beta = value + 100;
  188. fnodestot = snodestot = 0;
  189. timeon();
  190. /*
  191. value = alphabeta(bd,moves,width,MININT,MAXINT,maxdepth);
  192. if (value >= beta)
  193. value = alphabeta(bd,moves,width,value,MAXINT,maxdepth);
  194. else if (value <= alpha)
  195. value = alphabeta(bd,moves,width,MININT,value,maxdepth);
  196. */
  197. timeoff();
  198. moves[bestmove].score += value;
  199. from = moves[bestmove].from;
  200. to = moves[bestmove].to;
  201. lin_to_alg(from,stdout);
  202. lin_to_alg(to,stdout);
  203. timused = (float)timcpu.tv_sec+((float)timcpu.tv_usec/1000000.);
  204. printf(". Slow = %d, Fast = %d, Score = %d, Time = %.2f, Rate = %.2f\n",
  205. snodestot,fnodestot,value,timused,fnodestot/timused);
  206. sorttype = SCORESORT;
  207. qsort(moves,width,sizeof(struct mvlist),compare);
  208. }
  209. index = searchlist(from,to,moves,width);
  210. makemove(moves[index],bd);
  211. }
  212. /*
  213. * Aspiration implments aspiration search. This is a modifiction
  214. * of ordinary alpha-beta search such that the window is made
  215. * smaller, resulting in faster searches. When the returned value
  216. * is outside the search, a "failed search" is said to result
  217. * thus resulting in the need to search with a wider window.
  218. * (cf. "Parallel alpha-beta search on Arachne", Fishburn, J. &
  219. * Finkel, R., Tech. Report 394, Computer Science Department,
  220. * University of Wisconsin, Madison, Wis., July 1980 ;
  221. * Parallel Search of Strongly Ordered Game Trees, Marsland, T.A. &
  222. * Campbell, M., Department of Computing Science, University of
  223. * Alberta, Edmonton, Canada T6G 2H1)
  224. */
  225. aspiration(bd,alpha,beta,depth)
  226. struct bdtype bd[120];
  227. int alpha,beta,depth;
  228. {
  229. int a,b,v;
  230. a = -100; /* Create a window */
  231. b = 100; /* Two pawn's wide */
  232. a = iv + a; /* Around current expected score */
  233. b = iv + b;
  234. v = search(bd,a,b,depth);
  235. if (v >= b)
  236. v = search(bd,b,MAXINT,depth);
  237. else if (v <= a)
  238. v = search(bd,MININT,a,depth);
  239. iv = v; /* Reset iv so next search will use it */
  240. return(v);
  241. }