home *** CD-ROM | disk | FTP | other *** search
/ Dream 44 / Amiga_Dream_44.iso / RiscPc / jeux / ArcBoard004.arc / !GNUChessX / src / c / genmoves < prev    next >
Text File  |  1995-07-02  |  12KB  |  543 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. #include "ataks.h"
  25. SHORT *TrP, InCheck;
  26.  
  27. #define Link(from,to,flag,s) \
  28. {\
  29.    node->f = from; node->t = to;\
  30.      node->reply = 0;\
  31.        node->flags = flag;\
  32.      node->score = s;\
  33.        ++node;\
  34.          (*TrP)++;\
  35.          }
  36.  
  37. inline int
  38. CheckMove (SHORT f, SHORT t, SHORT flag)
  39. {
  40.   SHORT side, incheck;
  41.   SHORT tempb, tempc, tempsf, tempst;   
  42.   struct leaf node;
  43.  
  44.   side = color[f];
  45.   node.f = f;
  46.   node.t = t;
  47.   node.flags = flag;
  48.   MakeMove (side, &node, &tempb, &tempc, &tempsf, &tempst);
  49.   incheck = SqAtakd (PieceList[side][0], 1 ^ side);
  50.   UnmakeMove (side, &node, &tempb, &tempc, &tempsf, &tempst);
  51.   return (!incheck);
  52. }
  53.  
  54.  
  55.  
  56. inline void
  57. LinkMove (SHORT ply, SHORT f,
  58.       register SHORT t,
  59.       SHORT flag,
  60.       SHORT xside)
  61.  
  62. /*
  63.  * Add a move to the tree.  Assign a bonus to order the moves as follows:
  64.     1. Principle variation
  65.     2. Capture of last moved piece
  66.     3. Other captures (major pieces first)
  67.     4. Killer moves
  68.     5.
  69.  */
  70.  
  71. {
  72.     register SHORT s = 0;
  73. #if defined HISTORY
  74.     register SHORT z;
  75. #endif
  76.     register utshort mv;
  77.     SHORT piece;
  78.     register struct leaf *node;
  79.  
  80.     node = &Tree[*TrP];
  81.     mv = (f << 8) | t;
  82.     piece = board[f];
  83. #ifdef KILLT
  84.     s += killt[mv ];
  85. #endif
  86. #ifdef HISTORY
  87.     z = mv;
  88.     if (xside == white)
  89.     z |= 0x4000;
  90.     s += history[z];
  91. #endif
  92.     if (color[t] != neutral)
  93.       {
  94.       /* TOsquare is the square the last piece moved moved to */
  95.       s += value[board[t]] - piece + ((t == TOsquare) ? 500 : 0);
  96.       }
  97.     if (board[f] == pawn)
  98.     if (row (t) == 0 || row (t) == 7)
  99.       {
  100.           flag |= promote;
  101.           s += 800;
  102. #if !defined CHESSTOOL
  103.           Link (f, t, flag | queen, s - 20000);
  104.           s -= 200;
  105.           Link (f, t, flag | rook, s - 20000);
  106.           s -= 50;
  107.           Link (f, t, flag | knight, s - 20000);
  108.           flag |= bishop;
  109.           s -= 50;
  110. #else
  111.           flag |= queen;
  112. #endif
  113.       }
  114.     else if (row (t) == 1 || row (t) == 6)
  115.       {
  116.           flag |= pwnthrt;
  117.           s += 600;
  118.       }
  119.     else if ((row (t) == ((color[f] == white) ? 5 : 2)) && (ply > MINDEPTH) && (ply < Sdepth + 3))
  120.       {
  121.           if ((mtl[white] - pmtl[white] + mtl[black] - pmtl[black]) < PTVALUE)
  122.         {
  123.             flag |= pwnthrt;
  124.             s += 400;
  125.         }
  126.       }
  127.     Link (f, t, flag, s - 20000);
  128. }
  129.  
  130. inline
  131. void
  132. GenMoves (register SHORT ply, register SHORT sq, SHORT side, SHORT xside)
  133.  
  134. /*
  135.  * Generate moves for a piece. The moves are taken from the precalulated
  136.  * array nextpos/nextdir. If the board is free, next move is choosen from
  137.  * nextpos else from nextdir.
  138.  */
  139.  
  140. {
  141.     register SHORT u, piece;
  142.     register UCHAR *ppos, *pdir;
  143.  
  144.  
  145.     TrP = &TrPnt[ply + 1];
  146.     piece = board[sq];
  147.     if (piece == pawn)
  148.       {
  149.           ppos = nextpos[ptype[side][piece]][sq];
  150.           pdir = nextdir[ptype[side][piece]][sq];
  151.       u = ppos[sq];        /* follow no captures thread */
  152.       if (color[u] == neutral)
  153.         {
  154.         LinkMove (ply, sq, u, 0, xside);
  155.         u = ppos[u];
  156.         if (color[u] == neutral)
  157.               LinkMove (ply, sq, u, 0, xside);
  158.         }
  159.       u = pdir[sq];        /* follow captures thread */
  160.       if (color[u] == xside /*&& board[u] != king*/)
  161.         {
  162.               LinkMove (ply, sq, u, capture, xside);
  163.         }
  164.       u = pdir[u];
  165.       if (color[u] == xside /*&& board[u] != king*/)
  166.         {
  167.               LinkMove (ply, sq, u, capture, xside);
  168.         }
  169.       }
  170.     else
  171.       {
  172.       ppos = nextpos[piece][sq];
  173.       pdir = nextdir[piece][sq];
  174.       u = ppos[sq];
  175.       do
  176.         {
  177.         if (color[u] == neutral)
  178.           {
  179.                 LinkMove (ply, sq, u, 0, xside);
  180.               u = ppos[u];
  181.           }
  182.         else
  183.           {
  184.               if (color[u] == xside /*&& board[u] != king*/)
  185.             {
  186.                   LinkMove (ply, sq, u, capture, xside);
  187.             }
  188.               u = pdir[u];
  189.           }
  190.         }
  191.       while (u != sq);
  192.       }
  193. }
  194.  
  195. void
  196. MoveList (SHORT side, register SHORT ply)
  197.  
  198. /*
  199.  * Fill the array Tree[] with all available moves for side to play. Array
  200.  * TrPnt[ply] contains the index into Tree[] of the first move at a ply.
  201.  */
  202.  
  203. {
  204.     register SHORT i, xside, f;
  205.  
  206.     xside = side ^ 1;
  207.     TrP = &TrPnt[ply + 1];
  208.     *TrP = TrPnt[ply];
  209.     if (!PV)
  210.     Swag0 = killr0[ply];
  211.     else
  212.     Swag0 = PV;
  213.     Swag1 = killr1[ply];
  214.     Swag2 = killr2[ply];
  215.     if (ply > 2)
  216.     Swag4 = killr1[ply - 2];
  217.     else
  218.     Swag4 = 0;
  219. #ifdef KILLT
  220.     killt[SwagHt ] += 5000;
  221.     killt[Swag0 ] += 2000;
  222.     killt[Swag1 ] += 60;
  223.     killt[Swag2 ] += 50;
  224.     killt[Swag4 ] += 30;
  225. #endif
  226.     for (i = PieceCnt[side]; i >= 0; i--)
  227.     GenMoves (ply, PieceList[side][i], side, xside);
  228.     if (!castld[side])
  229.       {
  230.       f = PieceList[side][0];
  231.       if (castle (side, f, f + 2, 0))
  232.         {
  233.         LinkMove (ply, f, f + 2, cstlmask, xside);
  234.         }
  235.       if (castle (side, f, f - 2, 0))
  236.         {
  237.         LinkMove (ply, f, f - 2, cstlmask, xside);
  238.         }
  239.       }
  240.     if (epsquare > 0)
  241.       {
  242. /*      register SHORT l; */
  243.  
  244.       f = epmove1[epsquare];
  245.       if (color[f] == side && board[f] == pawn)
  246.         {
  247. /*        l = epsquare + ((epsquare > f) ? -8 : 8);
  248.         board[l] = no_piece;
  249.         color[l] = neutral; */
  250.         LinkMove (ply, f, epsquare, capture | epmask, xside);
  251. /*        board[l] = pawn;
  252.         color[l] = xside; */
  253.         }
  254.       f = epmove2[epsquare];
  255.       if (color[f] == side && board[f] == pawn)
  256.         {
  257. /*        l = epsquare + ((epsquare > f) ? -8 : 8);
  258.         board[l] = no_piece;
  259.         color[l] = neutral; */
  260.         LinkMove (ply, f, epsquare, capture | epmask, xside);
  261. /*        board[l] = pawn;
  262.         color[l] = xside; */
  263.         }
  264.       }
  265. #ifdef KILLT
  266.     killt[SwagHt ] -= 5000;
  267.     killt[Swag0 ] -= 2000;
  268.     killt[Swag1 ] -= 60;
  269.     killt[Swag2 ] -= 50;
  270.     killt[Swag4 ] -= 30;
  271. #endif
  272.     SwagHt = 0;            /* SwagHt is only used once */
  273.     GenCnt += (TrPnt[ply + 1] - TrPnt[ply]);
  274. }
  275.  
  276. void
  277. CaptureList (register SHORT side, SHORT ply)
  278.  
  279. /*
  280.  * Fill the array Tree[] with all available cature and promote moves for side
  281.  * to play. Array TrPnt[ply] contains the index into Tree[] of the first move
  282.  * at a ply.
  283.  */
  284.  
  285. {
  286.     register SHORT u, sq;
  287.     register UCHAR *ppos, *pdir;
  288.     struct leaf *node;
  289.     SHORT i, piece, *PL, r7;
  290.     SHORT xside = side^1;
  291.  
  292.     xside = side ^ 1;
  293.     TrP = &TrPnt[ply + 1];
  294.     *TrP = TrPnt[ply];
  295.     node = &Tree[*TrP];
  296.     r7 = rank7[side];
  297.     PL = PieceList[side];
  298.  
  299.     for (i = 0; i <= PieceCnt[side]; i++)
  300.       {
  301.       sq = PL[i];
  302.       piece = board[sq];
  303.       if (sweep[piece])
  304.         {
  305.         ppos = nextpos[piece][sq];
  306.         pdir = nextdir[piece][sq];
  307.         u = ppos[sq];
  308.         do
  309.           { 
  310.             if (color[u] == neutral) 
  311.             u = ppos[u];
  312.             else 
  313.               {
  314.             if (color[u] == xside) 
  315.               {
  316.                 Link (sq, u, capture, value[board[u]] + svalue[u] - piece); 
  317.               }
  318.             u = pdir[u];
  319.               } 
  320.           }
  321.         while (u != sq);
  322.         } else {
  323.         pdir = nextdir[ptype[side][piece]][sq];
  324.         if (piece == pawn && row (sq) == r7)
  325.           {
  326.               u = pdir[sq];
  327.               if (color[u] == xside)
  328.             {
  329.               Link (sq, u, capture | promote | queen, valueQ);
  330. #if !defined CHESSTOOL
  331.                 Link (sq, u, capture | promote | rook, valueR);
  332.                 Link (sq, u, capture | promote | knight, valueN);
  333.                 Link (sq, u, capture | promote | bishop, valueB);
  334. #endif
  335.               }
  336.               u = pdir[u];
  337.               if (color[u] == xside)
  338.             {
  339.                 Link (sq, u, capture | promote | queen, valueQ);
  340. #if !defined CHESSTOOL
  341.                 Link (sq, u, capture | promote | rook, valueR);
  342.                 Link (sq, u, capture | promote | knight, valueN);
  343.                 Link (sq, u, capture | promote | bishop, valueB);
  344. #endif
  345.             }
  346.               ppos = nextpos[ptype[side][piece]][sq];
  347.               u = ppos[sq];    /* also generate non capture promote */
  348.               if (color[u] == neutral)
  349.             {
  350.                 Link (sq, u, promote | queen, valueQ);
  351. #if !defined CHESSTOOL
  352.                 Link (sq, u, promote | rook, valueR);
  353.                 Link (sq, u, promote | knight, valueN);
  354.                 Link (sq, u, promote | bishop, valueB);
  355. #endif
  356.             }
  357.           }
  358.         else
  359.           {
  360.               u = pdir[sq];
  361.               do
  362.             {
  363.                 if (color[u] == xside)
  364.                 Link (sq, u, capture, value[board[u]] + svalue[u] - piece);
  365.                 u = pdir[u];
  366.             }
  367.               while (u != sq);
  368.           }
  369.         }
  370.       }
  371.     SwagHt = 0;            /* SwagHt is only used once */
  372.     GenCnt += (TrPnt[ply + 1] - TrPnt[ply]);
  373. }
  374.  
  375. inline
  376. void
  377. VGenMoves (register SHORT ply, register SHORT sq, SHORT side, SHORT xside)
  378.  
  379. /*
  380.  * Generate moves for a piece. The moves are taken from the precalulated
  381.  * array nextpos/nextdir. If the board is free, next move is choosen from
  382.  * nextpos else from nextdir.
  383.  */
  384.  
  385. {
  386.     register SHORT u, piece;
  387.     register UCHAR *ppos, *pdir;
  388.  
  389.  
  390.     TrP = &TrPnt[ply + 1];
  391.     piece = board[sq];
  392.     ppos = nextpos[ptype[side][piece]][sq];
  393.     pdir = nextdir[ptype[side][piece]][sq];
  394.     if (piece == pawn)
  395.       {
  396.       u = ppos[sq];        /* follow no captures thread */
  397.       if (color[u] == neutral)
  398.         {
  399.         if (CheckMove (sq, u, 0))
  400.           {
  401.               LinkMove (ply, sq, u, 0, xside);
  402.           }
  403.         u = ppos[u];
  404.         if (color[u] == neutral)
  405.             if (CheckMove (sq, u, 0))
  406.               {
  407.               LinkMove (ply, sq, u, 0, xside);
  408.               }
  409.         }
  410.       u = pdir[sq];        /* follow captures thread */
  411.       if (color[u] == xside /* && board[u] != king */)
  412.         {
  413.         if (CheckMove (sq, u, capture))
  414.           {
  415.               LinkMove (ply, sq, u, capture, xside);
  416.           }
  417.         }
  418.       u = pdir[u];
  419.       if (color[u] == xside /*&& board[u] != king*/)
  420.         {
  421.         if (CheckMove (sq, u, capture))
  422.           {
  423.               LinkMove (ply, sq, u, capture, xside);
  424.           }
  425.         }
  426.       }
  427.     else
  428.       {
  429.       u = ppos[sq];
  430.       do
  431.         {
  432.         if (color[u] == neutral)
  433.           {
  434.               if (CheckMove (sq, u, 0))
  435.             {
  436.                 LinkMove (ply, sq, u, 0, xside);
  437.             }
  438.               u = ppos[u];
  439.           }
  440.         else
  441.           {
  442.               if (color[u] == xside /*&& board[u] != king */)
  443.             {
  444.                 if (CheckMove (sq, u, capture))
  445.                   {
  446.                   LinkMove (ply, sq, u, capture, xside);
  447.                   }
  448.             }
  449.               u = pdir[u];
  450.           }
  451.         }
  452.       while (u != sq);
  453.       }
  454. }
  455.  
  456. void
  457. VMoveList (SHORT side, register SHORT ply)
  458.  
  459. /*
  460.  * Fill the array Tree[] with all available moves for side to play. Array
  461.  * TrPnt[ply] contains the index into Tree[] of the first move at a ply.
  462.  */
  463.  
  464. {
  465.     register SHORT i, xside, f;
  466.  
  467.     xside = side ^ 1;
  468.     TrP = &TrPnt[ply + 1];
  469.     *TrP = TrPnt[ply];
  470.     InCheck = SqAtakd (PieceList[side][0], side ^ 1);
  471.     if (!PV)
  472.     Swag0 = killr0[ply];
  473.     else
  474.     Swag0 = PV;
  475.     Swag1 = killr1[ply];
  476.     Swag2 = killr2[ply];
  477.     if (ply > 2)
  478.     Swag4 = killr1[ply - 2];
  479.     else
  480.     Swag4 = 0;
  481. #ifdef KILLT
  482.     killt[SwagHt] += 5000;
  483.     killt[Swag0] += 2000;
  484.     killt[Swag1] += 60;
  485.     killt[Swag2] += 50;
  486.     killt[Swag4] += 30;
  487. #endif
  488.     for (i = PieceCnt[side]; i >= 0; i--)
  489.     VGenMoves (ply, PieceList[side][i], side, xside);
  490.     if (!castld[side])
  491.       {
  492.       f = PieceList[side][0];
  493.       if (castle (side, f, f + 2, 0))
  494.         {
  495.         LinkMove (ply, f, f + 2, cstlmask, xside);
  496.         }
  497.       if (castle (side, f, f - 2, 0))
  498.         {
  499.         LinkMove (ply, f, f - 2, cstlmask, xside);
  500.         }
  501.       }
  502.     if (epsquare > 0)
  503.       {
  504.       register SHORT l;
  505.  
  506.       f = epmove1[epsquare];
  507.       if (color[f] == side && board[f] == pawn)
  508.         {
  509.         l = epsquare + ((epsquare > f) ? -8 : 8);
  510.         board[l] = no_piece;
  511.         color[l] = neutral;
  512.         if (CheckMove (f, epsquare, capture | epmask))
  513.           {
  514.               LinkMove (ply, f, epsquare, capture | epmask, xside);
  515.           }
  516.         board[l] = pawn;
  517.         color[l] = xside;
  518.         }
  519.       f = epmove2[epsquare];
  520.       if (color[f] == side && board[f] == pawn)
  521.         {
  522.         l = epsquare + ((epsquare > f) ? -8 : 8);
  523.         board[l] = no_piece;
  524.         color[l] = neutral;
  525.         if (CheckMove (f, epsquare, capture | epmask))
  526.           {
  527.               LinkMove (ply, f, epsquare, capture | epmask, xside);
  528.           }
  529.         board[l] = pawn;
  530.         color[l] = xside;
  531.         }
  532.       }
  533. #ifdef KILLT
  534.     killt[SwagHt] -= 5000;
  535.     killt[Swag0] -= 2000;
  536.     killt[Swag1] -= 60;
  537.     killt[Swag2] -= 50;
  538.     killt[Swag4] -= 30;
  539. #endif
  540.     SwagHt = 0;            /* SwagHt is only used once */
  541.     GenCnt += (TrPnt[ply + 1] - TrPnt[ply]);
  542. }
  543.