home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / useful / game / think / uchess.lha / UChess / src / genmoves.c < prev    next >
C/C++ Source or Header  |  1994-02-22  |  10KB  |  448 lines

  1. /*
  2.  * genmoves.c - C source for GNU CHESS
  3.  *
  4.  * Copyright (c) 1988,1989,1990 John Stanback
  5.  * Copyright (c) 1992 Free Software Foundation
  6.  *
  7.  * This file is part of GNU CHESS.
  8.  *
  9.  * GNU Chess is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2, or (at your option)
  12.  * any later version.
  13.  *
  14.  * GNU Chess is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with GNU Chess; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23. #include "gnuchess.h"
  24.  
  25.  
  26. short __aligned *TrP;
  27.  
  28. #define Link(from,to,flag,s) \
  29. {\
  30.    node->f = from; node->t = to;\
  31.      node->reply = 0;\
  32.        node->flags = flag;\
  33.      node->score = s;\
  34.        ++node;\
  35.          (*TrP)++;\
  36.          }
  37.  
  38. #ifndef KILLTO
  39. inline void
  40. LinkMove (ARGSZ int ply, ARGSZ int f,
  41.       ARGSZ int t,
  42.       ARGSZ int flag,
  43.       ARGSZ int xside)
  44. #else
  45. inline void
  46. LinkMove (ARGSZ int ply, ARGSZ int f,
  47.       ARGSZ int t,
  48.       ARGSZ int flag)
  49. #endif
  50.  
  51. /*
  52.  * Add a move to the tree.  Assign a bonus to order the moves as follows: 1.
  53.  * Principle variation 2. Capture of last moved piece 3. Other captures
  54.  * (major pieces first) 4. Killer moves 5.
  55.  */
  56.  
  57. {
  58.   register short s = 0;
  59. #if defined HISTORY
  60.   register short z;
  61. #endif
  62.   register unsigned short mv;
  63.   register struct leaf *node;
  64.  
  65.   node = &Tree[*TrP];
  66.   mv = (f << 8) | t;
  67. #ifdef KILLT
  68. #ifdef USE_SIDEBIT
  69.   s += killt[mv | sidebit];
  70. #else
  71.   s += killt[mv];
  72. #endif
  73. #endif
  74. #ifdef HISTORY
  75.   z = mv;
  76.   if (xside == white) z |= 0x4000;
  77.   s += history[z];
  78. #endif
  79.   if (color[t] != neutral)
  80.     {
  81.       /* TOsquare is the square the last piece moved moved to */
  82.       s +=  value[board[t]] - board[f] + ((t == TOsquare) ? 500 : 0);
  83.     }
  84.   if (board[f] == pawn)
  85.     if (row (t) == 0 || row (t) == 7)
  86.       {
  87.     flag |= promote;
  88.     s += 800;
  89. #if !defined OLDXBOARD  && !defined GNU3 && !defined CHESSTOOL
  90.     Link (f, t, flag | queen, s - 20000);
  91.     s -= 200;
  92.     Link (f, t, flag | knight, s - 20000);
  93.     s -= 50;
  94.     Link (f, t, flag | rook, s - 20000);
  95.     flag |= bishop;
  96.     s -= 50;
  97. #else
  98.     flag |= queen;
  99. #endif
  100.       }
  101.     else if (row (t) == 1 || row (t) == 6)
  102.       {
  103.     flag |= pwnthrt;
  104.     s += 600;
  105.       }
  106.     else if ((row(t) == ((color[f] == white)?5:2)) && (ply > MINDEPTH) && (ply < Sdepth+3))
  107.       {
  108.     if ((mtl[white] - pmtl[white] + mtl[black] - pmtl[black]) < PTVALUE)
  109.       {
  110.         flag |= pwnthrt;
  111.         s += 400;
  112.       }
  113.       }
  114.   Link (f, t, flag, s - 20000);
  115. }
  116.  
  117. inline
  118. void
  119. GenMoves (ARGSZ int ply, ARGSZ int sq, ARGSZ int side, ARGSZ int xside)
  120.  
  121. /*
  122.  * Generate moves for a piece. The moves are taken from the precalulated
  123.  * array nextpos/nextdir. If the board is free, next move is choosen from
  124.  * nextpos else from nextdir.
  125.  */
  126.  
  127. {
  128.   register short u, piece;
  129.   register unsigned char *ppos, *pdir;
  130.  
  131.   TrP = &TrPnt[ply + 1];
  132.   piece = board[sq];
  133.   ppos = nextpos[ptype[side][piece]][sq];
  134.   pdir = nextdir[ptype[side][piece]][sq];
  135.   if (piece == pawn)
  136.     {
  137.       u = ppos[sq];        /* follow no captures thread */
  138.       if (color[u] == neutral)
  139.     {
  140. #ifndef KILLTO
  141.       LinkMove (ply, sq, u, 0, xside);
  142. #else
  143.       LinkMove (ply, sq, u, 0);
  144. #endif
  145.       u = ppos[u];
  146.       if (color[u] == neutral)
  147. #ifndef KILLTO
  148.         LinkMove (ply, sq, u, 0, xside);
  149. #else
  150.         LinkMove (ply, sq, u, 0);
  151. #endif
  152.     }
  153.       u = pdir[sq];        /* follow captures thread */
  154.       if (color[u] == xside && board[u] != king)
  155. #ifndef KILLTO
  156.     LinkMove (ply, sq, u, capture, xside);
  157. #else
  158.     LinkMove (ply, sq, u, capture);
  159. #endif
  160.       u = pdir[u];
  161.       if (color[u] == xside && board[u] != king)
  162. #ifndef KILLTO
  163.     LinkMove (ply, sq, u, capture, xside);
  164. #else
  165.     LinkMove (ply, sq, u, capture);
  166. #endif
  167.     }
  168.   else
  169.     {
  170.       u = ppos[sq];
  171.       do
  172.     {
  173.       if (color[u] == neutral)
  174.         {
  175. #ifndef KILLTO
  176.           LinkMove (ply, sq, u, 0, xside);
  177. #else
  178.           LinkMove (ply, sq, u, 0);
  179. #endif
  180.           u = ppos[u];
  181.         }
  182.       else
  183.         {
  184.           if (color[u] == xside && board[u] != king)
  185. #ifndef KILLTO
  186.         LinkMove (ply, sq, u, capture, xside);
  187. #else
  188.         LinkMove (ply, sq, u, capture);
  189. #endif
  190.           u = pdir[u];
  191.         }
  192.       } while (u != sq);
  193.     }
  194. }
  195.  
  196. void
  197. MoveList (INTSIZE int side, INTSIZE int ply)
  198.  
  199. /*
  200.  * Fill the array Tree[] with all available moves for side to play. Array
  201.  * TrPnt[ply] contains the index into Tree[] of the first move at a ply.
  202.  */
  203.  
  204. {
  205.   register short i, xside, f;
  206.  
  207.   xside = side ^ 1;
  208.   TrP = &TrPnt[ply + 1];
  209.   *TrP = TrPnt[ply];
  210.   if (!PV)
  211.     Swag0 = killr0[ply];
  212.    else Swag0 = PV;
  213.   Swag1 = killr1[ply];
  214.   Swag2 = killr2[ply];
  215.   Swag3 = killr3[ply];
  216.   if (ply > 2)
  217.     Swag4 = killr1[ply - 2]; else Swag4 = 0;
  218. #ifdef KILLT
  219. #ifdef USE_SIDEBIT
  220.   sidebit = ((side == white) ? 0 : 0x80);
  221.   killt[SwagHt | sidebit] += 5000;
  222.   killt[Swag0 | sidebit] += 2000;
  223.   killt[Swag1 | sidebit] += 60;
  224.   killt[Swag2 | sidebit] += 50;
  225.   killt[Swag3 | sidebit] += 40;
  226.   killt[Swag4 | sidebit] += 30;
  227. #else
  228.   killt[SwagHt] += 5000;
  229.   killt[Swag0] += 2000;
  230.   killt[Swag1] += 60;
  231.   killt[Swag2] += 50;
  232.   killt[Swag3] += 40;
  233.   killt[Swag4] += 30;
  234. #endif
  235. #endif
  236. #ifdef HISTORKILLT
  237. #ifdef HISTORY
  238.   i = (side == black)?0x4000:0;
  239.   history[SwagHt | i] += 5000;
  240.   history[Swag0 | i] += 2000;
  241.   history[Swag1 | i] += 60;
  242.   history[Swag2 | i] += 50;
  243.   history[Swag3 | i] += 40;
  244.   history[Swag4 | i] += 30;
  245. #endif
  246. #endif
  247.   for (i = PieceCnt[side]; i >= 0; i--)
  248.     GenMoves (ply, PieceList[side][i], side, xside);
  249.   if (!castld[side])
  250.     {
  251.       f = PieceList[side][0];
  252.       if (castle (side, f, f + 2, 0))
  253.     {
  254. #ifndef KILLTO
  255.       LinkMove (ply, f, f + 2, cstlmask, xside);
  256. #else
  257.       LinkMove (ply, f, f + 2, cstlmask);
  258. #endif
  259.     }
  260.       if (castle (side, f, f - 2, 0))
  261.     {
  262. #ifndef KILLTO
  263.       LinkMove (ply, f, f - 2, cstlmask, xside);
  264. #else
  265.       LinkMove (ply, f, f - 2, cstlmask);
  266. #endif
  267.     }
  268.     }
  269.   if (epsquare > 0)
  270.     {
  271.       f = epmove1[epsquare];
  272.       if (color[f] == side && board[f] == pawn)
  273. #ifndef KILLTO
  274.     LinkMove (ply, f, epsquare, capture | epmask, xside);
  275. #else
  276.     LinkMove (ply, f, epsquare, capture | epmask);
  277. #endif
  278.       f = epmove2[epsquare];
  279.       if (color[f] == side && board[f] == pawn)
  280. #ifndef KILLTO
  281.     LinkMove (ply, f, epsquare, capture | epmask, xside);
  282. #else
  283.     LinkMove (ply, f, epsquare, capture | epmask);
  284. #endif
  285.     }
  286. #ifdef KILLT
  287. #ifdef USE_SIDEBIT
  288.   killt[SwagHt | sidebit] -= 5000;
  289.   killt[Swag0 | sidebit] -= 2000;
  290.   killt[Swag1 | sidebit] -= 60;
  291.   killt[Swag2 | sidebit] -= 50;
  292.   killt[Swag3 | sidebit] -= 40;
  293.   killt[Swag4 | sidebit] -= 30;
  294. #else
  295.   killt[SwagHt] -= 5000;
  296.   killt[Swag0] -= 2000;
  297.   killt[Swag1] -= 60;
  298.   killt[Swag2] -= 50;
  299.   killt[Swag3] -= 40;
  300.   killt[Swag4] -= 30;
  301. #endif
  302. #endif
  303. #ifdef HISTORKILLT
  304. #ifdef HISTORY
  305.  i = (side == black)?0x4000:0;
  306.   history[SwagHt | i] -= 5000;
  307.   history[Swag0 | i] -= 2000;
  308.   history[Swag1 | i] -= 60;
  309.   history[Swag2 | i] -= 50;
  310.   history[Swag3 | i] -= 40;
  311.   history[Swag4 | i] -= 30;
  312. #endif
  313. #endif
  314.   SwagHt = 0;            /* SwagHt is only used once */
  315.   GenCnt += (TrPnt[ply+1] - TrPnt[ply]);
  316. }
  317.  
  318. void
  319. CaptureList (INTSIZE int side, INTSIZE int ply)
  320.  
  321. /*
  322.  * Fill the array Tree[] with all available cature and promote moves for side
  323.  * to play. Array TrPnt[ply] contains the index into Tree[] of the first move
  324.  * at a ply.
  325.  */
  326.  
  327. {
  328.   register short u, sq, xside;
  329.   register struct leaf *node;
  330.   register unsigned char *ppos, *pdir;
  331.   short i, piece, *PL, r7;
  332.  
  333.   xside = side ^ 1;
  334.   TrP = &TrPnt[ply + 1];
  335.   *TrP = TrPnt[ply];
  336.   node = &Tree[*TrP];
  337.   r7 = rank7[side];
  338.   PL = PieceList[side];
  339. #ifdef KILLT
  340. #ifdef USE_SIDEBIT
  341.   sidebit = ((side == white) ? 0 : 0x80);
  342.   killt[SwagHt | sidebit] += 5000;
  343.   killt[Swag0 | sidebit] += 2000;
  344.   killt[Swag1 | sidebit] += 60;
  345.   killt[Swag2 | sidebit] += 50;
  346.   killt[Swag3 | sidebit] += 40;
  347.   killt[Swag4 | sidebit] += 30;
  348. #else
  349.   killt[SwagHt] += 5000;
  350.   killt[Swag0] += 2000;
  351.   killt[Swag1] += 60;
  352.   killt[Swag2] += 50;
  353.   killt[Swag3] += 40;
  354.   killt[Swag4] += 30;
  355. #endif
  356. #endif
  357.  
  358.   for (i = 0; i <= PieceCnt[side]; i++)
  359.     {
  360.       sq = PL[i];
  361.       piece = board[sq];
  362.       if (sweep[piece])
  363.     {
  364.       ppos = nextpos[piece][sq];
  365.       pdir = nextdir[piece][sq];
  366.       u = ppos[sq];
  367.       do
  368.         {
  369.           if (color[u] == neutral)
  370.         u = ppos[u];
  371.           else
  372.         {
  373.           if (color[u] == xside)
  374.             Link (sq, u, capture, value[board[u]] + svalue[board[u]] - piece);
  375.           u = pdir[u];
  376.         }
  377.       } while (u != sq);
  378.     }
  379.       else
  380.     {
  381.       pdir = nextdir[ptype[side][piece]][sq];
  382.       if (piece == pawn && row (sq) == r7)
  383.         {
  384.           u = pdir[sq];
  385.           if (color[u] == xside)
  386.                {
  387.         Link (sq, u, capture | promote | queen, valueQ);
  388. #if !defined OLDXBOARD  && !defined GNU3 && !defined CHESSTOOL
  389.             Link (sq, u, capture | promote | knight, valueN);
  390.         Link (sq, u, capture | promote | rook, valueR);
  391.         Link (sq, u, capture | promote | bishop, valueB);
  392. #endif
  393.                }
  394.           u = pdir[u];
  395.           if (color[u] == xside)
  396.         {
  397.           Link (sq, u, capture | promote | queen, valueQ);
  398. #if !defined OLDXBOARD  && !defined GNU3 && !defined CHESSTOOL
  399.           Link (sq, u, capture | promote | knight, valueN);
  400.           Link (sq, u, capture | promote | rook, valueR);
  401.           Link (sq, u, capture | promote | bishop, valueB);
  402. #endif
  403.         }
  404.           ppos = nextpos[ptype[side][piece]][sq];
  405.           u = ppos[sq];    /* also generate non capture promote */
  406.           if (color[u] == neutral)
  407.         {
  408.           Link (sq, u, promote | queen, valueQ);
  409. #if !defined OLDXBOARD  && !defined GNU3 && !defined CHESSTOOL
  410.           Link (sq, u, promote | knight, valueN);
  411.           Link (sq, u, promote | rook, valueR);
  412.           Link (sq, u, promote | bishop, valueB);
  413. #endif
  414.         }
  415.         }
  416.       else
  417.         {
  418.           u = pdir[sq];
  419.           do
  420.         {
  421.           if (color[u] == xside)
  422.             Link (sq, u, capture, value[board[u]] + svalue[u] - piece);
  423.           u = pdir[u];
  424.           } while (u != sq);
  425.         }
  426.     }
  427.     }
  428. #ifdef KILLT
  429. #ifdef USE_SIDEBIT
  430.   sidebit = ((side == white) ? 0 : 0x80);
  431.   killt[SwagHt | sidebit] -= 5000;
  432.   killt[Swag0 | sidebit] -= 2000;
  433.   killt[Swag1 | sidebit] -= 60;
  434.   killt[Swag2 | sidebit] -= 50;
  435.   killt[Swag3 | sidebit] -= 40;
  436.   killt[Swag4 | sidebit] -= 30;
  437. #else
  438.   killt[SwagHt] -= 5000;
  439.   killt[Swag0] -= 2000;
  440.   killt[Swag1] -= 60;
  441.   killt[Swag2] -= 50;
  442.   killt[Swag3] -= 40;
  443.   killt[Swag4] -= 30;
  444. #endif
  445. #endif
  446.   SwagHt = 0;            /* SwagHt is only used once */
  447. }
  448.