home *** CD-ROM | disk | FTP | other *** search
/ Dream 57 / Amiga_Dream_57.iso / Amiga / Jeux / Reflexion / Crafty-15.19.lha / crafty-15.19 / src / input.c < prev    next >
C/C++ Source or Header  |  1998-09-13  |  11KB  |  361 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "chess.h"
  5. #include "data.h"
  6.  
  7. /* last modified 03/11/98 */
  8. /*
  9. ********************************************************************************
  10. *                                                                              *
  11. *   InputMove() is responsible for converting a move from a text string to     *
  12. *   the internal move format.  it allows the so-called "reduced algebraic      *
  13. *   move format" which makes the origin square optional unless required for    *
  14. *   clarity.  it also accepts as little as required to remove ambiguity from   *
  15. *   the move, by using GenerateMoves() to produce a set of legal moves         *
  16. *   that the text can be applied against to eliminate those moves not          *
  17. *   intended.  hopefully, only one move will remain after the elimination      *
  18. *   and legality checks.                                                       *
  19. *                                                                              *
  20. ********************************************************************************
  21. */
  22. int InputMove(TREE *tree, char *text, int ply, int wtm, int silent,
  23.               int ponder_list) {
  24.   int moves[220], *mv, *mvp, *goodmove=0;
  25.   int piece=-1, capture, promote, give_check;
  26.   int ffile, frank, tfile, trank;
  27.   int current, i, nleft, ambig;
  28.   char *goodchar;
  29.   char movetext[128];
  30.   char pieces[17]={' ',' ','P','p','N','n','K','k',' ',' ',
  31.                    'B','B','R','r','Q','q','\0'};
  32.   char pro_pieces[17]={' ',' ','P','p','N','n','K','k',' ',' ',
  33.                        'B','b','R','r','Q','q','\0'};
  34.  
  35. /*
  36.    check for fully-qualified input (f1e1) and handle if needed.
  37. */
  38.   if (strlen(text) == 0) return(0);
  39.   if ((text[0] >= 'a') && (text[0] <= 'h') &&
  40.       (text[1] >= '1') && (text[1] <= '8') &&
  41.       (text[2] >= 'a') && (text[2] <= 'h') &&
  42.       (text[3] >= '1') && (text[3] <= '8'))
  43.     return(InputMoveICS(tree,text,ply,wtm,silent,ponder_list));
  44. /*
  45.    initialize move structure in case an error is found
  46. */
  47.   tree->position[MAXPLY]=tree->position[ply];
  48.   strcpy(movetext,text);
  49.   moves[0]=0;
  50.   piece=0;
  51.   capture=0;
  52.   promote=0;
  53.   give_check=0;
  54.   frank=-1;
  55.   ffile=-1;
  56.   trank=-1;
  57.   tfile=-1;
  58.   ambig=0;
  59.   goodchar=strchr(movetext,'#');
  60.   if (goodchar) *goodchar=0;
  61. /*
  62.    first, figure out what each character means.  the first thing to
  63.    do is eliminate castling moves
  64. */
  65.   if (!strcmp(movetext,"o-o") || !strcmp(movetext,"o-o+") ||
  66.       !strcmp(movetext,"O-O") || !strcmp(movetext,"O-O+") ||
  67.       !strcmp(movetext,"0-0") || !strcmp(movetext,"0-0+")) {
  68.     piece=king;
  69.     if(wtm) {
  70.       ffile=4;
  71.       frank=0;
  72.       tfile=6;
  73.       trank=0;
  74.     }
  75.     else {
  76.       ffile=4;
  77.       frank=7;
  78.       tfile=6;
  79.       trank=7;
  80.     }
  81.   }
  82.   else 
  83.     if (!strcmp(movetext,"o-o-o") || !strcmp(movetext,"o-o-o+") ||
  84.         !strcmp(movetext,"O-O-O") || !strcmp(movetext,"O-O-O+") ||
  85.         !strcmp(movetext,"0-0-0") || !strcmp(movetext,"0-0-0+")) {
  86.       piece=king;
  87.       if(wtm) {
  88.         ffile=4;
  89.         frank=0;
  90.         tfile=2;
  91.         trank=0;
  92.       }
  93.       else {
  94.         ffile=4;
  95.         frank=7;
  96.         tfile=2;
  97.         trank=7;
  98.       }
  99.     }
  100.   else {
  101. /*
  102.    ok, it's not a castling.  check for the first two characters of "bb" which
  103.    indicates that the first "b" really means "B" since pawn advances don't
  104.    require a source file.  
  105. */
  106.     if ((movetext[0] == 'b') && (movetext[1] == 'b')) movetext[0]='B';
  107. /*
  108.    now, start by picking off the check indicator (+) if one is present.
  109. */
  110.     if (strchr(movetext,'+')) {
  111.       *strchr(movetext,'+')=0;
  112.       give_check=1;
  113.     }
  114. /*
  115.    now, continue by picking off the promotion piece if one is present.  this 
  116.    is indicated by something like =q on the end of the move string.
  117. */
  118.     if (strchr(movetext,'=')) {
  119.       goodchar=strchr(movetext,'=');
  120.       goodchar++;
  121.       promote=(strchr(pro_pieces,*goodchar)-pro_pieces) >> 1;
  122.       *strchr(movetext,'=')=0;
  123.     }
  124. /*
  125.    the next thing to do is extract the last rank/file designators since
  126.    the destination is required.  note that we can have either or both.
  127. */
  128.     current=strlen(movetext)-1;
  129.     trank=movetext[current]-'1';
  130.     if ((trank >= 0) && (trank <= 7)) 
  131.       movetext[current]=0;
  132.     else 
  133.       trank=-1;
  134.     current=strlen(movetext)-1;
  135.     tfile=movetext[current]-'a';
  136.     if ((tfile >= 0) && (tfile <= 7)) 
  137.       movetext[current]=0;
  138.     else
  139.       tfile=-1;
  140.     if (strlen(movetext)) {
  141. /*
  142.    now check the first character to see if it's a piece indicator
  143.    (PpNnBbRrQqKk).  if so, strip it off.
  144. */
  145.       if (strchr("  PpNnBBRrQqKk",*movetext)) {
  146.         piece=(strchr(pieces,movetext[0])-pieces) >> 1;
  147.         for(i=0;i<(int) strlen(movetext);i++) 
  148.           movetext[i]=movetext[i+1];
  149.       }
  150. /*
  151.    now that we have the destination and the moving piece (if any)
  152.    the next step is to see if the last character is now an "x"
  153.    indicating a capture   if so, set the capture flag, remove the
  154.    trailing "x" and continue.
  155. */
  156.       if ((strlen(movetext)) && (movetext[strlen(movetext)-1] == 'x')) {
  157.         capture=1;
  158.         movetext[strlen(movetext)-1]=0;
  159.       }
  160.       else
  161.         capture=0;
  162. /*
  163.    now, all that can be left is a rank designator, a file designator
  164.    or both.  if the last character a number, then the first (if present)
  165.    has to be a letter.
  166. */
  167.       if (strlen(movetext)) {
  168.         ffile=movetext[0]-'a';
  169.         if ((ffile < 0) || (ffile > 7)) {
  170.           ffile=-1;
  171.           frank=movetext[0]-'1';
  172.           if ((frank < 0) || (frank > 7)) piece=-1;
  173.         }
  174.         else {
  175.           if (strlen(movetext) == 2) {
  176.             frank=movetext[1]-'1';
  177.             if ((frank < 0) || (frank > 7)) piece=-1;
  178.           }
  179.         }
  180.       }
  181.     }
  182.   }
  183.   if (!piece) piece=1;
  184.   if (!ponder_list) {
  185.     mvp=GenerateCaptures(tree,MAXPLY, wtm, moves);
  186.     mvp=GenerateNonCaptures(tree,MAXPLY, wtm, mvp);
  187.   }
  188.   else {
  189.     for (i=0;i<num_ponder_moves;i++)
  190.     moves[i]=ponder_moves[i];
  191.     mvp=moves+num_ponder_moves;
  192.   }
  193.   for (mv=&moves[0];mv<mvp;mv++) {
  194.     if (piece && (Piece(*mv) != piece)) *mv=0;
  195.     if ((ffile >= 0) && (File(From(*mv)) != ffile)) *mv=0;
  196.     if (capture && (!Captured(*mv))) *mv=0;
  197.     if (promote && (Promote(*mv) != promote)) *mv=0;
  198.     if ((frank >= 0)  && (Rank(From(*mv)) != frank)) *mv=0;
  199.     if ((tfile >= 0)  && (File(To(*mv)) != tfile)) *mv=0;
  200.     if ((trank >= 0)  && (Rank(To(*mv)) != trank)) *mv=0;
  201.     if (!ponder_list && *mv) {
  202.       MakeMove(tree,MAXPLY, *mv, wtm);
  203.       if (Check(wtm) || (give_check && !Check(ChangeSide(wtm)))) {
  204.         UnMakeMove(tree,MAXPLY, *mv, wtm);
  205.         *mv=0;
  206.       }
  207.       else UnMakeMove(tree,MAXPLY, *mv, wtm);
  208.     }
  209.   }
  210.   nleft=0;
  211.   for (mv=&moves[0];mv<mvp;mv++) {
  212.     if (*mv) {
  213.       nleft++;
  214.       goodmove=mv;
  215.     }
  216.   }
  217.   if (nleft == 1) return(*goodmove);
  218.   if (ambig) {
  219.     if (nleft > 1) {
  220.       for (mv=&moves[0];mv<mvp;mv++) 
  221.         if (Piece(*mv) != pawn) *mv=0;
  222.       nleft=0;
  223.       for (mv=&moves[0];mv<mvp;mv++) {
  224.         if (*mv) {
  225.           nleft++;
  226.           goodmove=mv;
  227.         }
  228.       }
  229.       if (nleft == 1)
  230.         return(*goodmove);
  231.     }
  232.   }
  233.   if (!silent) {
  234.     if (nleft == 0) Print(4095,"Illegal move: %s\n",text);
  235.     else if (piece < 0) Print(4095,"Illegal move (unrecognizable): %s\n",text);
  236.     else Print(4095,"Illegal move (ambiguous): %s\n",text);
  237.   }
  238.   return(0);
  239. }
  240.  
  241. /* last modified 03/11/97 */
  242. /*
  243. ********************************************************************************
  244. *                                                                              *
  245. *   InputMoveICS() is responsible for converting a move from the ics format    *
  246. *   [from][to][promote] to the program's internal format.                      *
  247. *                                                                              *
  248. ********************************************************************************
  249. */
  250. int InputMoveICS(TREE *tree, char *text, int ply, int wtm, int silent,
  251.                  int ponder_list) {
  252.   int moves[220], *mv, *mvp, *goodmove=0;
  253.   int piece=-1, promote;
  254.   int ffile, frank, tfile, trank;
  255.   int i, nleft;
  256.   char movetext[128];
  257.   char pieces[17]={' ',' ','P','p','N','n','K','k',' ',' ',
  258.                    'B','b','R','r','Q','q','\0'};
  259. /*
  260.    initialize move structure in case an error is found
  261. */
  262.   if (strlen(text) == 0) return(0);
  263.   tree->position[MAXPLY]=tree->position[ply];
  264.   strcpy(movetext,text);
  265.   moves[0]=0;
  266.   promote=0;
  267. /*
  268.    first, figure out what each character means.  the first thing to
  269.    do is eliminate castling moves
  270. */
  271.   if (!strcmp(movetext,"o-o") || !strcmp(movetext,"O-O") ||
  272.       !strcmp(movetext,"0-0")) {
  273.     piece=king;
  274.     if(wtm) {
  275.       ffile=4;
  276.       frank=0;
  277.       tfile=6;
  278.       trank=0;
  279.     }
  280.     else {
  281.       ffile=4;
  282.       frank=7;
  283.       tfile=6;
  284.       trank=7;
  285.     }
  286.   }
  287.   else 
  288.     if (!strcmp(movetext,"o-o-o") || !strcmp(movetext,"O-O-O") ||
  289.         !strcmp(movetext,"0-0-0")) {
  290.       piece=king;
  291.       if(wtm) {
  292.         ffile=4;
  293.         frank=0;
  294.         tfile=2;
  295.         trank=0;
  296.       }
  297.       else {
  298.         ffile=4;
  299.         frank=7;
  300.         tfile=2;
  301.         trank=7;
  302.       }
  303.     }
  304.   else {
  305. /*
  306.    the next thing to do is extract the last rank/file designators since
  307.    the destination is required.  note that we can have either or both.
  308. */
  309.     ffile=movetext[0]-'a';
  310.     frank=movetext[1]-'1';
  311.     tfile=movetext[2]-'a';
  312.     trank=movetext[3]-'1';
  313. /*
  314.    now, continue by picking off the promotion piece if one is present.  this 
  315.    is indicated by something like q on the end of the move string.
  316. */
  317.     if (movetext[4]=='=')
  318.       promote=(strchr(pieces,movetext[5])-pieces) >> 1;
  319.     else if ((movetext[4] != 0) && (movetext[4] != ' '))
  320.       promote=(strchr(pieces,movetext[4])-pieces) >> 1;
  321.   }
  322.   if (!ponder_list) {
  323.     mvp=GenerateCaptures(tree,MAXPLY, wtm, moves);
  324.     mvp=GenerateNonCaptures(tree,MAXPLY, wtm, mvp);
  325.   }
  326.   else {
  327.     for (i=0;i<num_ponder_moves;i++) moves[i]=ponder_moves[i];
  328.     mvp=moves+num_ponder_moves;
  329.   }
  330.   for (mv=&moves[0];mv<mvp;mv++) {
  331.     if (auto232 && Promote(*mv) && (Promote(*mv) != queen)) *mv = 0;
  332.     if (!auto232 && Promote(*mv) != promote) *mv=0;
  333.     if (Rank(From(*mv)) != frank) *mv=0;
  334.     if (File(From(*mv)) != ffile) *mv=0;
  335.     if (Rank(To(*mv)) != trank) *mv=0;
  336.     if (File(To(*mv)) != tfile) *mv=0;
  337.     if (!ponder_list && *mv) {
  338.       MakeMove(tree,MAXPLY, *mv, wtm);
  339.       if(Check(wtm)) {
  340.         UnMakeMove(tree,MAXPLY, *mv, wtm);
  341.         *mv=0;
  342.       }
  343.       else UnMakeMove(tree,MAXPLY, *mv, wtm);
  344.     }
  345.   }
  346.   nleft=0;
  347.   for (mv=&moves[0];mv<mvp;mv++) {
  348.     if (*mv) {
  349.       nleft++;
  350.       goodmove=mv;
  351.     }
  352.   }
  353.   if (nleft == 1) return(*goodmove);
  354.   if (!silent) {
  355.     if (nleft == 0) Print(4095,"Illegal move: %s\n",text);
  356.     else if (piece < 0) Print(4095,"Illegal move (unrecognizable): %s\n",text);
  357.     else Print(4095,"Illegal move (ambiguous): %s\n",text);
  358.   }
  359.   return(0);
  360. }
  361.