home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / gnushogi-1.1 / src / genmoves.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-26  |  17.8 KB  |  759 lines

  1. /*
  2.  * genmoves.c - C source for GNU SHOGI
  3.  *
  4.  * Copyright (c) 1993 Matthias Mutz
  5.  *
  6.  * GNU SHOGI is based on GNU CHESS
  7.  *
  8.  * Copyright (c) 1988,1989,1990 John Stanback
  9.  * Copyright (c) 1992 Free Software Foundation
  10.  *
  11.  * This file is part of GNU SHOGI.
  12.  *
  13.  * GNU Shogi is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 1, or (at your option)
  16.  * any later version.
  17.  *
  18.  * GNU Shogi is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  * GNU General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with GNU Shogi; see the file COPYING.  If not, write to
  25.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  26.  */
  27.  
  28. #include "gnushogi.h"
  29. #include "ataks.h"
  30.  
  31.  
  32. short *TrP;
  33.  
  34. static struct leaf *node;
  35. static short sqking, sqxking;
  36. static short InCheck = false;     
  37.  
  38.  
  39. /*
  40.  * Ply limits for deep search cut.
  41.  * No moves or drops flagged with "stupid" are considered beyond ply BEYOND_STUPID.
  42.  * Only moves or drops flagged with "kingattack" are considered beyond ply BEYOND_KINGATTACK.
  43.  * No moves or drops flagged with "questionable" are considered beyond ply BEYOND_QUESTIONABLE.
  44.  * Only moves or drops flagged with "tesuji" are considered beyond ply BEYOND_TESUJI.
  45.  * No drops are considered beyond ply BEYOND_DROP.
  46.  * Exceptions: moves or drops that prevent check or give check are always considered.
  47.  */
  48.  
  49. #ifdef THINK_C
  50. #define BEYOND_STUPID 2
  51. #define BEYOND_KINGATTACK 4
  52. #define BEYOND_QUESTIONABLE 6
  53. #define BEYOND_TESUJI 6
  54. #define BEYOND_DROP 8
  55. #else
  56. #define BEYOND_STUPID 2
  57. #define BEYOND_KINGATTACK 6
  58. #define BEYOND_QUESTIONABLE 8
  59. #define BEYOND_TESUJI 8
  60. #define BEYOND_DROP 10
  61. #endif
  62.  
  63. inline
  64. static
  65. void
  66. GenMakeMove (short int side,
  67.          short f,
  68.          short t,
  69.          short int *tempb,    /* piece at to square */
  70.          short int *tempc)    /* color of to square */
  71.  
  72. /*
  73.  * Update Arrays board[] and color[] to reflect the new board
  74.  * position obtained after making the move pointed to by node.
  75.  */
  76.  
  77. {
  78.   register short int piece;
  79.  
  80.   t = t & 0x7f;
  81.  
  82.   if (f > NO_SQUARES )
  83.     { 
  84.       piece = f - NO_SQUARES;
  85.       if ( side == white ) piece -= NO_PIECES;
  86.       board[t] = piece;
  87.       color[t] = side;
  88.     }
  89.   else
  90.     {
  91.       *tempb = board[t];
  92.       *tempc = color[t];
  93.       piece = board[f];
  94.       color[f] = neutral;
  95.       board[f] = no_piece;
  96.       color[t] = side;
  97.       board[t] = (node->flags & promote) ? promoted[piece] : piece;
  98.     } 
  99. }
  100.  
  101. static
  102. void
  103. GenUnmakeMove (short int side,
  104.            short f,
  105.            short t,
  106.            short int tempb,
  107.            short int tempc)
  108.  
  109. /*
  110.  * Take back a move.
  111.  */
  112.  
  113. {
  114.   register short piece;
  115.  
  116.   t = t & 0x7f;
  117.   
  118.   if (f > NO_SQUARES )
  119.     { 
  120.       piece = f - NO_SQUARES;
  121.       if ( piece >= NO_PIECES ) piece -= NO_PIECES;
  122.       board[t] = no_piece;
  123.       color[t] = neutral;
  124.     }
  125.   else
  126.     { 
  127.       piece = board[t];
  128.       color[t] = tempc;
  129.       board[t] = tempb;
  130.       color[f] = side;
  131.       board[f] = (node->flags & promote) ? unpromoted[piece] : piece;
  132.     }
  133. }
  134.  
  135.  
  136. inline
  137. static
  138. void
  139. Link (short side, short piece,
  140.       short from, short to, short local_flag, short s) 
  141. {        
  142.     if ( *TrP == TREE ) {
  143.       ShowMessage("TREE overflow\n");
  144.     } else {
  145.       node->f = from; 
  146.       node->t = (local_flag & promote) ? (to | 0x80) : to;
  147.       node->reply = 0;
  148.       node->flags = local_flag;
  149.       node->score = s;
  150.       if ( flag.tsume )
  151.         {
  152.           if ( InCheck )
  153.             {
  154.               short tempb, tempc, sq, threat;
  155.               GenMakeMove (side, node->f, node->t, &tempb, &tempc);
  156.               sq = (from == sqking) ? to : sqking;
  157.           threat = SqAtakd(sq,side ^ 1);
  158.               GenUnmakeMove (side, node->f, node->t, tempb, tempc);
  159.               if ( !threat ) 
  160.             (*TrP)++, node++;
  161.             }
  162.           else if ( !(local_flag & check) && (sqxking != to ) && (board[sqxking] == king) )
  163.             {                               
  164.               short tempb, tempc, sq, threat;
  165.               GenMakeMove (side, node->f, node->t, &tempb, &tempc);
  166.           if ( threat = SqAtakd(sqxking,side) )
  167.             local_flag |= check;
  168.               GenUnmakeMove (side, node->f, node->t, tempb, tempc);
  169.           if ( threat ) 
  170.             (*TrP)++, node++;
  171.             }
  172.           else
  173.         (*TrP)++, node++;
  174.         }
  175.       else
  176.     (*TrP)++, node++;
  177.     }
  178. }
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185. inline
  186. int
  187. InPromotionZone (short int color, short int sq)
  188. {
  189.   if ( color == black ) {
  190.     if ( sq < 54 ) return(false);
  191.   } else {
  192.     if ( sq > 26 ) return(false);
  193.   };
  194.   return(true);
  195. }
  196.  
  197.  
  198.  
  199. inline
  200. int
  201. PromotionPossible (short int color, short int f, short int t, short int p)
  202.   if ( color == black ) {
  203.     if ( f < 54 && t < 54 ) return(false);
  204.   } else {
  205.     if ( f > 26 && t > 26 ) return(false);
  206.   };
  207.  
  208.   switch ( p ) {
  209.     case pawn: return(true);
  210.     case lance: return(true);
  211.     case knight: return(true);
  212.     case silver: return(true);
  213.     case bishop: return(true);
  214.     case rook: return(true);
  215.   };
  216.  
  217.   return(false);
  218. }
  219.  
  220.  
  221. inline
  222. int
  223. NonPromotionPossible (short int color, short int f, short int t, short int p)
  224. {
  225.   switch ( p ) {
  226.     case pawn : 
  227.            if ( color == black )
  228.              return ( t < 72 );
  229.            else
  230.              return ( t > 8 );
  231.     case lance: 
  232.            if ( color == black )
  233.              return ( t < 72 );
  234.            else
  235.              return ( t > 8 );
  236.     case knight:
  237.            if ( color == black )
  238.              return ( t < 63 );
  239.            else
  240.              return ( t > 17 );
  241.   };
  242.  
  243.   return(true);
  244. }
  245.  
  246.  
  247. #if defined FIELDBONUS || defined DROPBONUS
  248.  
  249. inline
  250. static 
  251. short
  252. field_bonus (short int ply, short int side, short int piece, short int f, short int t, 
  253.          short int *local_flag)
  254.  
  255. /* bonus for possible next moves */
  256.  
  257. {
  258.   register short s, u, ptyp;
  259.   register unsigned char *ppos, *pdir;
  260.   register short xside;
  261.  
  262.   xside = side ^ 1;
  263.  
  264.   s = 0;
  265.  
  266.   ptyp = ptype[side][piece];
  267.   ppos = (*nextpos[ptyp])[t];
  268.   pdir = (*nextdir[ptyp])[t];
  269.  
  270.   u = ppos[t];
  271.  
  272.   do 
  273.     { short coloru = color[u];
  274.       if (distance(u,WhiteKing) <= 1 || distance(u,BlackKing) <= 1 ) {
  275.         /* move controls square near own king or enemy king */
  276.     s += 2;
  277.     *local_flag |= kingattack; 
  278.       }
  279.       if (coloru == side ) {
  280.         /* impossible next move */
  281.         u = pdir[u];
  282.       } else {
  283.         /* possible next move */
  284.         if (PromotionPossible(side,t,u,piece)) {
  285.           /* possible promotion in next move */
  286.       if ( piece == pawn )
  287.             {
  288.           s += 2;
  289. #ifdef TESUJIBONUS
  290.               if ( !InPromotionZone(side,t) ) {
  291.                 *local_flag |= tesuji; /* The dangling pawn */ 
  292.         s++;
  293.               }
  294. #endif
  295.             }
  296.           else
  297.         s++; 
  298.         }
  299.         if (coloru == neutral) {
  300.           /* next move to an empty square */
  301.       if ( u == FROMsquare )
  302.              /* opponent has just left this square */
  303.          s++;
  304.       u = ppos[u];
  305.         } else {
  306.           /* attack opponents piece */
  307. #ifdef TESUJIBONUS
  308.           short boardu, upiece, rvupiece, rvuboard;
  309. #endif
  310.       s++;
  311.       if ( u == TOsquare )
  312.         /* opponent has moved to TOsquare */
  313.         s++;
  314.           if ( (boardu = board[u]) == king ) {
  315.           *local_flag |= check; /* move threatens opponents king */ 
  316.       }
  317. #ifdef TESUJIBONUS
  318.           upiece = unpromoted[piece];
  319.           rvupiece = relative_value[upiece];
  320.           rvuboard = relative_value[unpromoted[boardu]];
  321.           if ( upiece == pawn && Captured[side][pawn] > 1 )
  322.         {                
  323.           *local_flag |= tesuji; /* The joining pawn attack */
  324.           s++;
  325.         }     
  326.       if ( rvupiece <= rvuboard ) 
  327.         {                
  328.           *local_flag |= tesuji; /* The striking pawn (piece) attack */
  329.               if ( f > NO_SQUARES )
  330.             s += 2;
  331.               else
  332.         s++;
  333.               if ( upiece == pawn )
  334.         s++;
  335.           if ( rvupiece == rvuboard && 
  336.                    upiece == pawn || upiece == bishop || upiece == knight ) {
  337.                 s++; /* The opposing pawn (piece) */
  338.         if ( upiece == pawn )
  339.           s++;
  340.               }
  341.         }
  342. #endif 
  343.       u = pdir[u];
  344.     }
  345.       };
  346.   } while (u != t);
  347.  
  348.   return(s);
  349. }
  350.  
  351.  
  352. #endif
  353.  
  354.  
  355.  
  356. inline void
  357. LinkMove (short int ply, short int f,
  358.       register short int t,
  359.       short int local_flag,
  360.       short int xside)
  361.  
  362. /*
  363.  * Add a move to the tree.  Assign a bonus to order the moves as follows:
  364.  * 1. Principle variation 2. Capture of last moved piece 3. Other captures
  365.  * (major pieces first) 4. Killer moves 5. Tesuji drops 6. Other Moves
  366.  * 7. Other drops. 8. Non-promoting moves
  367.  * If the flag.tsume is set, assign a high bonus for checks.
  368.  */
  369.  
  370. {
  371.   register short s = 0;
  372.   register short piece;
  373.   register short principle = false;
  374.   short flag_tsume;
  375.  
  376. #if defined DROPBONUS || defined FIELDBONUS
  377.   register short side;
  378.   side = xside ^ 1;
  379. #endif
  380.  
  381. #ifdef HISTORY
  382.   /* Principle variation */
  383.     { 
  384.       unsigned short c, z, ds;
  385.       c = (xside == black);
  386.       z = (f << 8) | t;
  387.       ds = history[hindex(c,z)];
  388.       principle = (ds != 0);
  389.       s += ds;
  390.     }   
  391. #endif
  392.  
  393.   if ( !flag.tsume ) {
  394.  
  395.     if (distance(t,WhiteKing) <= 1 || distance(t,BlackKing) <= 1 ) {
  396.       /* bonus for square near own king or enemy king */
  397.       s += 10;
  398.       local_flag |= kingattack; 
  399.     }
  400.  
  401.     if ( f > NO_SQUARES )
  402.       { 
  403.        /* bonus for drops, in order to place the before questionable moves */
  404.         s += 10;
  405.         if (t == FROMsquare) {
  406.           /* drop to the square the opponent has just left */
  407.           s++;
  408.         };
  409. #if defined DROPBONUS
  410.         piece = f - NO_SQUARES; 
  411.         if (piece > NO_PIECES) piece -= NO_PIECES;
  412.         s += field_bonus(ply,side,piece,f,t,&local_flag);
  413.         if ( s == 10 && piece != pawn )
  414.         local_flag |= questionable;
  415. #endif
  416.       }
  417.     else 
  418.       {
  419.         /* bonus for moves (non-drops) */
  420.         int consider_last = false;
  421.         piece = board[f];
  422.         s += 20; 
  423.         if (t == FROMsquare) {
  424.           /* move to the square the opponent has just left */
  425.           s++;
  426.         }
  427.         if (color[t] != neutral)
  428.           {
  429.             /* Captures */  
  430.             s +=  value[board[t]] - relative_value[piece];
  431.             if (t == TOsquare)
  432.               /* Capture of last moved piece */ 
  433.               s += 500;
  434.           }  
  435.         if ( local_flag & promote )
  436.           {
  437.             /* bonus for promotions */
  438.             s++;
  439.           }
  440.         else
  441.           {
  442.             /* bonus for non-promotions */
  443.             if ( PromotionPossible(side,f,t,piece) )
  444. #ifdef TESUJIBONUS
  445.             /* Look at non-promoting silver or knight */
  446.               if ( piece == silver || piece == knight ) 
  447.                 {
  448.                   local_flag |= tesuji; /* Non-promotion */
  449.                   s++;
  450.                 }
  451.               else           
  452. #endif        
  453.               if ( !principle )
  454.               {
  455.               consider_last = true;
  456.                   if ( piece == pawn || piece == bishop || piece == rook )
  457.             local_flag |= stupid;
  458.           else
  459.             local_flag |= questionable;
  460.             }
  461.           }
  462.         if ( consider_last )
  463.       {
  464.         if ( local_flag & stupid )
  465.           s = 0;
  466.         else 
  467.               s = s % 20;
  468.       }
  469. #if defined FIELDBONUS
  470.         else 
  471.             {
  472.             s += field_bonus(ply,side,piece,f,t,&local_flag);
  473.           }
  474. #endif
  475.       }
  476.  
  477.   }
  478.  
  479.   flag_tsume = flag.tsume;
  480.  
  481.   /* check conditions for deep search cut */
  482.  
  483.   if ( !flag.tsume )      
  484.   if ( *TrP > TREE - 300 ) {
  485.     /* too close to tree table limit */
  486.     flag.tsume = true;
  487.   }
  488. #ifdef DEEPSEARCHCUT
  489.     else if ( *TrP > TREE - 1000 ) {
  490.     if ( ply > BEYOND_STUPID  && (local_flag & questionable) ) {
  491.       flag.tsume = true; 
  492.     } else if ( ply > BEYOND_KINGATTACK && !(local_flag & kingattack) ) {
  493.       flag.tsume = true;
  494.     } else if ( ply > BEYOND_QUESTIONABLE && (local_flag & stupid) ) {
  495.       flag.tsume = true; 
  496.     } else if ( ply > BEYOND_TESUJI && !(local_flag & tesuji) ) {
  497.       flag.tsume = true;
  498.     } else if ( ply > BEYOND_DROP && (f > NO_SQUARES) ) {
  499.       flag.tsume = true;
  500.     } 
  501.   }
  502. #endif
  503.  
  504.   Link (side, piece, 
  505.         f, t, local_flag, s - ((SCORE_LIMIT+1000)*2));
  506.  
  507.   flag.tsume = flag_tsume;
  508. }                                                 
  509.  
  510.  
  511.  
  512.  
  513. inline
  514. static
  515. void
  516. GenDrops (register short int ply, register short int piece, short int side,
  517.       short int xside)
  518.  
  519. /*
  520.  * Generate drops for a piece.
  521.  */
  522.  
  523. { register short u; 
  524.  
  525.   for (u = 0; u < NO_SQUARES; u++)
  526.  
  527.     { short r = row(u), possible = true;
  528.  
  529.       if ( board[u] != no_piece )
  530.          possible = false; 
  531.       else if ( piece == pawn )
  532.         { 
  533.           if ( side == black && r == 8 )
  534.             possible = false;
  535.           else if ( side == white && r == 0 )
  536.             possible = false;
  537.           else if ( PawnCnt[side][column(u)] )
  538.             possible = false;
  539.         }
  540.       else if ( piece == lance )
  541.         {
  542.           if ( side == black && r == 8 )
  543.             possible = false;
  544.           else if ( side == white && r == 0 )
  545.             possible = false;          
  546.         }
  547.       else if ( piece == knight )
  548.         {
  549.           if ( side == black && r >= 7 )
  550.             possible = false;
  551.           else if ( side == white && r <= 1 )
  552.             possible = false;
  553.         } 
  554.  
  555.       if ( possible )
  556.        { short f;
  557.          f = NO_SQUARES + piece;
  558.          if ( side == white ) f += NO_PIECES;
  559.          LinkMove (ply, f, u, (dropmask | piece), xside);
  560.        }
  561.   
  562.     }
  563.  
  564. }
  565.  
  566.  
  567.  
  568. inline
  569. void
  570. GenMoves (register short int ply, register short int sq, short int side, 
  571.       short int xside)
  572.  
  573. /*
  574.  * Generate moves for a piece. The moves are taken from the precalulated
  575.  * array nextpos/nextdir. If the board is free, next move is choosen from
  576.  * nextpos else from nextdir.
  577.  */
  578.  
  579. {
  580.   register short u, piece, col;
  581.   register unsigned char *ppos, *pdir;
  582.   short ptyp;
  583.  
  584.   TrP = &TrPnt[ply + 1];
  585.   piece = board[sq];
  586.   ptyp = ptype[side][piece];
  587.   ppos = (*nextpos[ptyp])[sq];
  588.   pdir = (*nextdir[ptyp])[sq];
  589.  
  590.   u = ppos[sq];
  591.   do
  592.     { short int local_flag, c;
  593.       if ( (c = color[u]) == xside )
  594.         local_flag = capture;
  595.       else
  596.         local_flag = 0;
  597.       if ( c != side && board[u] != king ) {
  598.         if ( PromotionPossible(color[sq],sq,u,piece) ) {
  599.           LinkMove (ply, sq, u, local_flag | promote, xside);
  600.           if ( NonPromotionPossible(color[sq],sq,u,piece) )
  601.             LinkMove (ply, sq, u, local_flag, xside);
  602.         } else {
  603.           LinkMove (ply, sq, u, local_flag, xside);
  604.         }
  605.       }
  606.       if (c == neutral)
  607.         u = ppos[u];
  608.       else
  609.         u = pdir[u];
  610.   } while (u != sq);
  611. }
  612.  
  613.  
  614.  
  615. void
  616. MoveList (short int side, register short int ply)
  617.  
  618. /*
  619.  * Fill the array Tree[] with all available moves for side to play. Array
  620.  * TrPnt[ply] contains the index into Tree[] of the first move at a ply.
  621.  */
  622.  
  623. {
  624.   register short i, xside, f;
  625.   struct leaf *firstnode;
  626.  
  627.   xside = side ^ 1;
  628.   if ( flag.tsume )
  629.     {
  630.       sqking  = PieceList[side][0];
  631.       sqxking = PieceList[xside][0];
  632.       InCheck = (board[sqking] == king) ? SqAtakd(sqking,xside) : false;
  633.     }
  634.   TrP = &TrPnt[ply + 1];
  635.   *TrP = TrPnt[ply];
  636.   firstnode = node = &Tree[*TrP];
  637.   if (!PV)
  638.     Swag0 = killr0[ply];
  639.    else Swag0 = PV;
  640.   Swag1 = killr1[ply];
  641.   Swag2 = killr2[ply];
  642.   Swag3 = killr3[ply];
  643.   if (ply > 2)
  644.     Swag4 = killr1[ply - 2]; else Swag4 = 0;
  645. #ifdef HISTORY
  646.   history[hindex(side,SwagHt)] += 5000;
  647.   history[hindex(side,Swag0)] += 2000;
  648.   history[hindex(side,Swag1)] += 60;
  649.   history[hindex(side,Swag2)] += 50;
  650.   history[hindex(side,Swag3)] += 40;
  651.   history[hindex(side,Swag4)] += 30;
  652. #endif
  653.   for (i = PieceCnt[side]; i >= 0; i--)
  654.     GenMoves (ply, PieceList[side][i], side, xside);
  655.   for (i = pawn; i < king; i++)
  656.     if ( Captured[side][i] )
  657.       GenDrops (ply, i, side, xside);
  658. #ifdef HISTORY
  659.   history[hindex(side,SwagHt)] -= 5000;
  660.   history[hindex(side,Swag0)] -= 2000;
  661.   history[hindex(side,Swag1)] -= 60;
  662.   history[hindex(side,Swag2)] -= 50;
  663.   history[hindex(side,Swag3)] -= 40;
  664.   history[hindex(side,Swag4)] -= 30;
  665. #endif
  666.   SwagHt = 0;            /* SwagHt is only used once */
  667.   if ( 0 /* flag.tsume */ )
  668.     if ( node == firstnode )
  669.       (*TrP)++;
  670.   GenCnt += (TrPnt[ply+1] - TrPnt[ply]);
  671. }
  672.  
  673. void
  674. CaptureList (register short int side, short int ply)
  675.  
  676. /*
  677.  * Fill the array Tree[] with all available captures for side to play.
  678.  * If there is a non-promote option, discard the non-promoting move.
  679.  * Array TrPnt[ply] contains the index into Tree[] of the first move
  680.  * at a ply.      
  681.  * If flag.tsume is set, add moves (even non-promoting moves)
  682.  * that threatens the opponents piece.
  683.  */
  684.  
  685. {
  686.   register short u, sq, xside;
  687.   register unsigned char *ppos, *pdir;
  688.   short i, piece, flag_tsume;
  689.   small_short *PL;
  690.   struct leaf *firstnode;
  691.  
  692.   xside = side ^ 1;
  693.  
  694.   if ( flag.tsume )
  695.     {
  696.       sqking = PieceList[side][0];
  697.       sqxking = PieceList[xside][0];
  698.       InCheck = (board[sqking] == king) ? SqAtakd(sqking,xside) : false;
  699.     }
  700.  
  701.   TrP = &TrPnt[ply + 1];
  702.   *TrP = TrPnt[ply];
  703.   firstnode = node = &Tree[*TrP];
  704.  
  705.   flag_tsume = flag.tsume;
  706.  
  707.   if ( *TrP > TREE - 300 ) 
  708.     {
  709.       /* too close to tree table limit */
  710.       flag.tsume = true;
  711.     }
  712.  
  713.   PL = PieceList[side];
  714.  
  715.   for (i = 0; i <= PieceCnt[side]; i++)
  716.     { short ptyp;
  717.       sq = PL[i];
  718.       piece = board[sq];
  719.       ptyp = ptype[side][piece];
  720.       ppos = (*nextpos[ptyp])[sq];
  721.       pdir = (*nextdir[ptyp])[sq];
  722.       u = ppos[sq];
  723.       do
  724.     { 
  725.       if (color[u] == neutral)
  726.         { 
  727.           u = ppos[u];
  728.         }
  729.       else
  730.         { 
  731.           if ( color[u] == xside && board[u] != king )
  732.         { 
  733.           short PP;
  734.           if ( PP = PromotionPossible(color[sq],sq,u,piece) ) {
  735.                     Link (side, piece, 
  736.               sq, u, capture | promote,
  737.                           value[board[u]] + svalue[board[u]] 
  738.                             - relative_value[piece]);
  739.                   } 
  740.           if ( !PP || flag.tsume ) {
  741.                     Link (side, piece, 
  742.               sq, u, capture,
  743.                           value[board[u]] + svalue[board[u]] 
  744.                             - relative_value[piece]);
  745.                   }  
  746.            }
  747.           u = pdir[u];
  748.         }
  749.     } while (u != sq);
  750.     }
  751.  
  752.   flag.tsume = flag_tsume;
  753.  
  754.   SwagHt = 0;            /* SwagHt is only used once */
  755.  
  756.  
  757.