home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR2
/
CBUFF09.ZIP
/
SRC.ZIP
/
MOVE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-16
|
9KB
|
301 lines
/* $Id: move.c,v 1.1.1.1 1993/06/21 11:12:00 anjo Exp $
*
* File move.c
* Part of ChessBase utilities file format (CBUFF)
* Author Anjo Anjewierden, anjo@swi.psy.uva.nl
* Purpose Moves
* Works with GNU CC 2.4.5
*
* Notice Copyright (c) 1993 Anjo Anjewierden
*
* History 10/06/93 (Created)
* 13/10/93 (Last modified)
*/
/*------------------------------------------------------------
* Directives
*------------------------------------------------------------*/
#include "cbuff.h"
/*------------------------------------------------------------
* Initialisation
*------------------------------------------------------------*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node newMove
@deftypefun Move newMove ()
Allocates a new move and returns it.
@end deftypefun
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
Move
newMove()
{ Move me;
me = alloc(sizeof(struct move));
me->from = 0x00;
me->to = 0x00;
me->piece = NO_PIECE;
me->moveEvaluation = '\0';
me->positionEvaluation = '\0';
me->extraEvaluation = '\0';
me->commentLength = 0;
me->comments = NULL;
me->next = NULL;
me->alternative = NULL;
return me;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node freeMove
@deftypefun void freeMove (Move @var{m})
Reclaims the memory of a move previously allocated with @code{newMove}.
@end deftypefun
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void
freeMove(Move m)
{ if (m->next)
freeMove(m->next);
if (m->alternative)
freeMove(m->alternative);
if (m->comments)
unalloc(m->comments);
unalloc(m);
}
/*------------------------------------------------------------
* Printing
*------------------------------------------------------------*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node diagramMoveP
@deftypefun bool diagramMoveP (Move @var{m})
Succeeds when the comments of the move contain an instruction to
print a diagram. In ChessBase, a diagram is requested by entering
@key{Control-D} as a comment for the move.
@end deftypefun
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
bool
diagramMoveP(Move m)
{ if (m->commentLength)
{ int n;
for (n=0; n<m->commentLength; n++)
{ if (m->comments[n] == REQUEST_DIAGRAM)
return TRUE;
}
}
return FALSE;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node containsCommentsMoveP
@deftypefun bool containsCommentsMoveP (Move @var{m})
Succeeds when @var{m} contains comments. The diagram indicator is
ignored here, so when the only comment is to print a diagram this
function fails.
@end deftypefun
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
bool
containsCommentsMoveP(Move m)
{ if (m->commentLength)
{ unsigned char *s;
for (s=m->comments; *s; s++)
{ if (*s == REQUEST_DIAGRAM)
continue;
if (*s >= ' ') /* Printable character */
return TRUE;
}
}
return FALSE;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node containsVariationsMoveP
@deftypefun bool containsVariationsMoveP (Move @var{m})
Succeeds when there are alternatives for move @var{m}.
@end deftypefun
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
bool
containsVariationsMoveP(Move m)
{ return (m->alternative ? TRUE : FALSE);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@node outputCommentsMove
@deftypefun void outputCommentsMove (Move @var{m}, TextBuffer @var{tb}, Position @var{pos})
Prints the comments for move @var{m} in the textbuffer @var{tb}.
A diagram will be printed at the appropriate point, if the comment
contains a diagram request.
@end deftypefun
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void
outputCommentsMove(Move m, TextBuffer tb, Position pos)
{ if (m->commentLength)
{ unsigned char *s;
stringTextBuffer(tb, chessSymbol(START_COMMENT));
for (s=m->comments; *s; s++)
{ if (*s >= ' ' && *s < '\177')
{ char buf[2];
buf[0] = *s;
buf[1] = '\0';
stringTextBuffer(tb, buf);
continue;
}
if (*s == '\177')
{ stringTextBuffer(tb, chessSymbol(WITH_IDEA));
continue;
}
if (*s == REQUEST_DIAGRAM)
{ stringTextBuffer(tb, chessSymbol(START_COMMENT));
diagramPosition(pos, tb);
stringTextBuffer(tb, chessSymbol(END_COMMENT));
continue;
}
stringTextBuffer(tb, mapChessSymbol(*s));
}
stringTextBuffer(tb, chessSymbol(END_COMMENT));
}
}
void
outputMove(Move m, TextBuffer tb, Position pos, int algebraic)
{ switch (m->extraEvaluation) /* These are printed before move */
{ case '\000': break;
case '\001': stringTextBuffer(tb, chessSymbol(EDITORIAL_COMMENT)); break;
case '\002': stringTextBuffer(tb, chessSymbol(BETTER_IS)); break;
case '\003': stringTextBuffer(tb, chessSymbol(WITH_IDEA)); break;
case '\004': stringTextBuffer(tb, "~~"); break;
case '\005': stringTextBuffer(tb, chessSymbol(BETTER_IS)); break;
case '\006': stringTextBuffer(tb, chessSymbol(WORSE_IS)); break;
default: setError(ERR_UNKNOWN_EXTRA_EVALUATION);
}
stringTextBuffer(tb, getStringMovePosition(pos, m, algebraic));
switch (m->moveEvaluation)
{ case '\000': break;
case '\001': stringTextBuffer(tb, chessSymbol(GOOD_MOVE)); break;
case '\002': stringTextBuffer(tb, chessSymbol(BAD_MOVE)); break;
case '\003': stringTextBuffer(tb, chessSymbol(INTERESTING_MOVE)); break;
case '\004': stringTextBuffer(tb, chessSymbol(DUBIOUS_MOVE)); break;
case '\005': stringTextBuffer(tb, chessSymbol(BRILLIANT_MOVE)); break;
case '\006': stringTextBuffer(tb, chessSymbol(BLUNDER)); break;
case '\007': stringTextBuffer(tb, chessSymbol(MATE)); break;
case '\010': stringTextBuffer(tb, chessSymbol(TIME_TROUBLE)); break;
case '\011': stringTextBuffer(tb, chessSymbol(DEVELOPMENT_ADVANTAGE)); break;
default: setError(ERR_UNKNOWN_MOVE_EVALUATION);
}
switch (m->positionEvaluation)
{ case '\000': break;
case '\001': stringTextBuffer(tb, chessSymbol(WHITE_WINNING)); break;
case '\002': stringTextBuffer(tb, chessSymbol(WHITE_ADVANTAGE)); break;
case '\003': stringTextBuffer(tb, chessSymbol(WHITE_BETTER)); break;
case '\004': stringTextBuffer(tb, chessSymbol(EQUALITY)); break;
case '\005': stringTextBuffer(tb, chessSymbol(UNCLEAR)); break;
case '\006': stringTextBuffer(tb, chessSymbol(BLACK_BETTER)); break;
case '\007': stringTextBuffer(tb, chessSymbol(BLACK_ADVANTAGE)); break;
case '\010': stringTextBuffer(tb, chessSymbol(BLACK_WINNING)); break;
case '\011': stringTextBuffer(tb, chessSymbol(NOVELTY)); break;
case '\012': stringTextBuffer(tb, chessSymbol(COMPENSATION)); break;
case '\013': stringTextBuffer(tb, chessSymbol(WITH_COUNTERPLAY)); break;
case '\014': stringTextBuffer(tb, chessSymbol(WITH_INITIATIVE)); break;
case '\015': stringTextBuffer(tb, chessSymbol(WITH_ATTACK)); break;
case '\016': stringTextBuffer(tb, chessSymbol(TIME_TROUBLE)); break;
case '\017': stringTextBuffer(tb, chessSymbol(ONLY_MOVE)); break;
default: setError(ERR_UNKNOWN_POSITION_EVALUATION);
}
}
/*------------------------------------------------------------
* Functions
*------------------------------------------------------------*/
#define START_OF_COMMENT 0xff
#define COMMENT_PADDING '\0'
unsigned char *
commentMove(Move m, unsigned char *s)
{ int l;
if (*s != START_OF_COMMENT)
{ setError(ERR_FORMAT_ERROR_ANNOTATIONS);
return s;
}
s++;
m->moveEvaluation = *s++;
if (*s == START_OF_COMMENT)
return s;
m->positionEvaluation = *s++;
if (*s == START_OF_COMMENT)
return s;
m->extraEvaluation = *s++;
if (*s == START_OF_COMMENT)
return s;
/* The current byte should perhaps contain the number of bytes
* of (textual) comments remaining (Rolf Exner). At present
* we ignore it and scan forward to the next START_OF_COMMENT
* character and use that as a comment terminator.
*/
if (*s == COMMENT_PADDING)
l = 256;
else
l = (int) *s;
s++;
{ unsigned char *t;
int k = l;
for (t=s; *s != START_OF_COMMENT && k; s++, k--)
;
if (*s != START_OF_COMMENT)
{ setError(ERR_COMMENT_NOT_TERMINATED);
*s = '\0';
return s;
}
*s = '\0';
m->commentLength = (s-t);
m->comments = alloc(m->commentLength+1);
strcpy((char *) m->comments, (char *) t);
*s = START_OF_COMMENT;
}
return s;
/* Code used when last byte contains number of characters in comment.
m->commentLength = *s++;
m->comments = alloc(m->commentLength+1);
strncpy((char *) m->comments, (char *) s, m->commentLength);
m->comments[m->commentLength] = '\0';
s += m->commentLength;
return s;
*/
}