home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR2 / CBUFF09.ZIP / SRC.ZIP / MOVE.C < prev    next >
C/C++ Source or Header  |  1993-11-16  |  9KB  |  301 lines

  1. /*  $Id: move.c,v 1.1.1.1 1993/06/21 11:12:00 anjo Exp $
  2.  *  
  3.  *  File    move.c
  4.  *  Part of    ChessBase utilities file format (CBUFF)
  5.  *  Author    Anjo Anjewierden, anjo@swi.psy.uva.nl
  6.  *  Purpose    Moves
  7.  *  Works with    GNU CC 2.4.5
  8.  *  
  9.  *  Notice    Copyright (c) 1993  Anjo Anjewierden
  10.  *  
  11.  *  History    10/06/93  (Created)
  12.  *          13/10/93  (Last modified)
  13.  */ 
  14.  
  15.  
  16. /*------------------------------------------------------------
  17.  *  Directives
  18.  *------------------------------------------------------------*/
  19.  
  20. #include "cbuff.h"
  21.  
  22.  
  23. /*------------------------------------------------------------
  24.  *  Initialisation
  25.  *------------------------------------------------------------*/
  26.  
  27. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  28. @node newMove
  29. @deftypefun Move newMove ()
  30. Allocates a new move and returns it.
  31. @end deftypefun
  32. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  33.  
  34. Move
  35. newMove()
  36. { Move me;
  37.  
  38.   me = alloc(sizeof(struct move));
  39.   me->from = 0x00;
  40.   me->to = 0x00;
  41.   me->piece = NO_PIECE;
  42.   me->moveEvaluation = '\0';
  43.   me->positionEvaluation = '\0';
  44.   me->extraEvaluation = '\0';
  45.   me->commentLength = 0;
  46.   me->comments = NULL;
  47.   me->next = NULL;
  48.   me->alternative = NULL;
  49.  
  50.   return me;
  51. }
  52.  
  53.  
  54. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  55. @node freeMove
  56. @deftypefun void freeMove (Move @var{m})
  57. Reclaims the memory of a move previously allocated with @code{newMove}.
  58. @end deftypefun
  59. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  60.  
  61. void
  62. freeMove(Move m)
  63. { if (m->next)
  64.     freeMove(m->next);
  65.   if (m->alternative)
  66.     freeMove(m->alternative);
  67.   if (m->comments)
  68.     unalloc(m->comments);
  69.   unalloc(m);
  70. }
  71.  
  72.  
  73. /*------------------------------------------------------------
  74.  *  Printing
  75.  *------------------------------------------------------------*/
  76.  
  77. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  78. @node diagramMoveP
  79. @deftypefun bool diagramMoveP (Move @var{m})
  80. Succeeds when the comments of the move contain an instruction to
  81. print a diagram.  In ChessBase, a diagram is requested by entering
  82. @key{Control-D} as a comment for the move.
  83. @end deftypefun
  84. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  85.  
  86. bool
  87. diagramMoveP(Move m)
  88. { if (m->commentLength)
  89.   { int n;
  90.  
  91.     for (n=0; n<m->commentLength; n++)
  92.     { if (m->comments[n] == REQUEST_DIAGRAM)
  93.     return TRUE;
  94.     }
  95.   }
  96.   return FALSE;
  97. }
  98.  
  99.  
  100. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  101. @node containsCommentsMoveP
  102. @deftypefun bool containsCommentsMoveP (Move @var{m})
  103. Succeeds when @var{m} contains comments.  The diagram indicator is
  104. ignored here, so when the only comment is to print a diagram this
  105. function fails.
  106. @end deftypefun
  107. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  108.  
  109. bool
  110. containsCommentsMoveP(Move m)
  111. { if (m->commentLength)
  112.   { unsigned char *s;
  113.  
  114.     for (s=m->comments; *s; s++)
  115.     { if (*s == REQUEST_DIAGRAM)
  116.     continue;
  117.       if (*s >= ' ')            /* Printable character */
  118.     return TRUE;
  119.     }
  120.   }
  121.   return FALSE;
  122. }
  123.  
  124.  
  125. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  126. @node containsVariationsMoveP
  127. @deftypefun bool containsVariationsMoveP (Move @var{m})
  128. Succeeds when there are alternatives for move @var{m}.
  129. @end deftypefun
  130. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  131.  
  132. bool
  133. containsVariationsMoveP(Move m)
  134. { return (m->alternative ? TRUE : FALSE);
  135. }
  136.  
  137.  
  138. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  139. @node outputCommentsMove
  140. @deftypefun void outputCommentsMove (Move @var{m}, TextBuffer @var{tb}, Position @var{pos})
  141. Prints the comments for move @var{m} in the textbuffer @var{tb}.
  142. A diagram will be printed at the appropriate point, if the comment
  143. contains a diagram request.
  144. @end deftypefun
  145. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  146.  
  147. void
  148. outputCommentsMove(Move m, TextBuffer tb, Position pos)
  149. { if (m->commentLength)
  150.   { unsigned char *s;
  151.  
  152.     stringTextBuffer(tb, chessSymbol(START_COMMENT));
  153.     for (s=m->comments; *s; s++)
  154.     { if (*s >= ' ' && *s < '\177')
  155.       { char buf[2];
  156.  
  157.     buf[0] = *s;
  158.     buf[1] = '\0';
  159.     stringTextBuffer(tb, buf);
  160.     continue;
  161.       }
  162.       if (*s == '\177')
  163.       { stringTextBuffer(tb, chessSymbol(WITH_IDEA));
  164.     continue;
  165.       }
  166.       if (*s == REQUEST_DIAGRAM)
  167.       { stringTextBuffer(tb, chessSymbol(START_COMMENT));
  168.     diagramPosition(pos, tb);
  169.     stringTextBuffer(tb, chessSymbol(END_COMMENT));
  170.         continue;
  171.       }
  172.       stringTextBuffer(tb, mapChessSymbol(*s));
  173.     }
  174.     stringTextBuffer(tb, chessSymbol(END_COMMENT));
  175.   }
  176. }
  177.  
  178.  
  179. void
  180. outputMove(Move m, TextBuffer tb, Position pos, int algebraic)
  181. { switch (m->extraEvaluation)        /* These are printed before move */
  182.   { case '\000': break;
  183.     case '\001': stringTextBuffer(tb, chessSymbol(EDITORIAL_COMMENT)); break;
  184.     case '\002': stringTextBuffer(tb, chessSymbol(BETTER_IS)); break;
  185.     case '\003': stringTextBuffer(tb, chessSymbol(WITH_IDEA)); break;
  186.     case '\004': stringTextBuffer(tb, "~~"); break;
  187.     case '\005': stringTextBuffer(tb, chessSymbol(BETTER_IS)); break;
  188.     case '\006': stringTextBuffer(tb, chessSymbol(WORSE_IS)); break;
  189.     default:     setError(ERR_UNKNOWN_EXTRA_EVALUATION);
  190.   }
  191.  
  192.   stringTextBuffer(tb, getStringMovePosition(pos, m, algebraic));
  193.  
  194.   switch (m->moveEvaluation)
  195.   { case '\000': break;
  196.     case '\001': stringTextBuffer(tb, chessSymbol(GOOD_MOVE)); break;
  197.     case '\002': stringTextBuffer(tb, chessSymbol(BAD_MOVE)); break;
  198.     case '\003': stringTextBuffer(tb, chessSymbol(INTERESTING_MOVE)); break;
  199.     case '\004': stringTextBuffer(tb, chessSymbol(DUBIOUS_MOVE)); break;
  200.     case '\005': stringTextBuffer(tb, chessSymbol(BRILLIANT_MOVE)); break;
  201.     case '\006': stringTextBuffer(tb, chessSymbol(BLUNDER)); break;
  202.     case '\007': stringTextBuffer(tb, chessSymbol(MATE)); break;
  203.     case '\010': stringTextBuffer(tb, chessSymbol(TIME_TROUBLE)); break;
  204.     case '\011': stringTextBuffer(tb, chessSymbol(DEVELOPMENT_ADVANTAGE)); break;
  205.     default:     setError(ERR_UNKNOWN_MOVE_EVALUATION);
  206.   }
  207.  
  208.   switch (m->positionEvaluation)
  209.   { case '\000': break;
  210.     case '\001': stringTextBuffer(tb, chessSymbol(WHITE_WINNING)); break;
  211.     case '\002': stringTextBuffer(tb, chessSymbol(WHITE_ADVANTAGE)); break;
  212.     case '\003': stringTextBuffer(tb, chessSymbol(WHITE_BETTER)); break;
  213.     case '\004': stringTextBuffer(tb, chessSymbol(EQUALITY)); break;
  214.     case '\005': stringTextBuffer(tb, chessSymbol(UNCLEAR)); break;
  215.     case '\006': stringTextBuffer(tb, chessSymbol(BLACK_BETTER)); break;
  216.     case '\007': stringTextBuffer(tb, chessSymbol(BLACK_ADVANTAGE)); break;
  217.     case '\010': stringTextBuffer(tb, chessSymbol(BLACK_WINNING)); break;
  218.     case '\011': stringTextBuffer(tb, chessSymbol(NOVELTY)); break;
  219.     case '\012': stringTextBuffer(tb, chessSymbol(COMPENSATION)); break;
  220.     case '\013': stringTextBuffer(tb, chessSymbol(WITH_COUNTERPLAY)); break;
  221.     case '\014': stringTextBuffer(tb, chessSymbol(WITH_INITIATIVE)); break;
  222.     case '\015': stringTextBuffer(tb, chessSymbol(WITH_ATTACK)); break;
  223.     case '\016': stringTextBuffer(tb, chessSymbol(TIME_TROUBLE)); break;
  224.     case '\017': stringTextBuffer(tb, chessSymbol(ONLY_MOVE)); break;
  225.     default:     setError(ERR_UNKNOWN_POSITION_EVALUATION);
  226.   }
  227.  
  228. }
  229.  
  230.  
  231. /*------------------------------------------------------------
  232.  *  Functions
  233.  *------------------------------------------------------------*/
  234.  
  235. #define START_OF_COMMENT    0xff
  236. #define COMMENT_PADDING        '\0'
  237.  
  238.  
  239. unsigned char *
  240. commentMove(Move m, unsigned char *s)
  241. { int l;
  242.  
  243.   if (*s != START_OF_COMMENT)
  244.   { setError(ERR_FORMAT_ERROR_ANNOTATIONS);
  245.     return s;
  246.   }
  247.   s++;
  248.   m->moveEvaluation = *s++;
  249.   if (*s == START_OF_COMMENT)
  250.     return s;
  251.   m->positionEvaluation = *s++;
  252.   if (*s == START_OF_COMMENT)
  253.     return s;
  254.   m->extraEvaluation = *s++;
  255.   if (*s == START_OF_COMMENT)
  256.     return s;
  257.  
  258.       /* The current byte should perhaps contain the number of bytes
  259.      * of (textual) comments remaining (Rolf Exner).  At present
  260.      * we ignore it and scan forward to the next START_OF_COMMENT
  261.      * character and use that as a comment terminator.
  262.      */
  263.   if (*s == COMMENT_PADDING)
  264.     l = 256;
  265.   else
  266.     l = (int) *s;
  267.  
  268.   s++;
  269.  
  270.   { unsigned char *t;
  271.     int k = l;
  272.  
  273.     for (t=s; *s != START_OF_COMMENT && k; s++, k--)
  274.       ;
  275.     if (*s != START_OF_COMMENT)
  276.     { setError(ERR_COMMENT_NOT_TERMINATED);
  277.       *s = '\0';
  278.       return s;
  279.     }
  280.     *s = '\0';
  281.     m->commentLength = (s-t);
  282.     m->comments = alloc(m->commentLength+1);
  283.     strcpy((char *) m->comments, (char *) t);
  284.     *s = START_OF_COMMENT;
  285.   }
  286.  
  287.   return s;
  288.  
  289. /* Code used when last byte contains number of characters in comment.
  290.   m->commentLength = *s++;
  291.   m->comments = alloc(m->commentLength+1);
  292.   strncpy((char *) m->comments, (char *) s, m->commentLength);
  293.   m->comments[m->commentLength] = '\0';
  294.   s += m->commentLength;
  295.  
  296.   return s;
  297. */
  298. }
  299.  
  300.  
  301.