}
int
-ptclen (const char *s)
+ptclen (const char *s, char *escapes)
{
int n = 0;
- while(*s) n += (*s != '\'' && *s != '"' && *s != '`' && *s != '!'), s++;
+ if(!*escapes) return strlen(s);
+ while(*s) n += (*s != ':' && !strchr(escapes, *s)), s++;
return n;
}
int
-SetCharTable (char *table, const char * map)
+SetCharTableEsc (unsigned char *table, const char * map, char * escapes)
/* [HGM] moved here from winboard.c because of its general usefulness */
/* Basically a safe strcpy that uses the last character as King */
{
int result = FALSE; int NrPieces;
- if( map != NULL && (NrPieces=ptclen(map)) <= (int) EmptySquare
+ if( map != NULL && (NrPieces=ptclen(map, escapes)) <= (int) EmptySquare
&& NrPieces >= 12 && !(NrPieces&1)) {
int i, j = 0; /* [HGM] Accept even length from 12 to 88 */
for( i=0; i<(int) EmptySquare; i++ ) table[i] = '.';
for( i=0; i<NrPieces/2-1; i++ ) {
- if(map[j] == ':') i = CHUPROMOTED WhitePawn, j++;
+ char *p;
+ if(map[j] == ':' && *escapes) i = CHUPROMOTED WhitePawn, j++;
table[i] = map[j++];
- if(map[j] == '\'') table[i] += 64;
- if(map[j] == '!') table[i] += 128;
+ if(p = strchr(escapes, map[j])) j++, table[i] += 64*(p - escapes + 1);
}
table[(int) WhiteKing] = map[j++];
for( i=0; i<NrPieces/2-1; i++ ) {
- if(map[j] == ':') i = CHUPROMOTED BlackPawn, j++;
+ char *p;
+ if(map[j] == ':' && *escapes) i = CHUPROMOTED BlackPawn, j++;
table[WHITE_TO_BLACK i] = map[j++];
- if(map[j] == '\'') table[WHITE_TO_BLACK i] += 64;
- if(map[j] == '!') table[WHITE_TO_BLACK i] += 128;
+ if(p = strchr(escapes, map[j])) j++, table[WHITE_TO_BLACK i] += 64*(p - escapes + 1);
}
table[(int) BlackKing] = map[j++];
return result;
}
+int
+SetCharTable (unsigned char *table, const char * map)
+{
+ return SetCharTableEsc(table, map, "");
+}
+
void
Prelude (Board board)
{ // [HGM] superchess: random selection of exo-pieces
gameInfo.boardWidth = 12;
gameInfo.boardHeight = 12;
nrCastlingRights = 0;
- SetCharTable(pieceToChar, "P.BRQSEXOGCATHD.VMLIFN+.++.++++++++++.+++++K"
- "p.brqsexogcathd.vmlifn+.++.++++++++++.+++++k");
+ SetCharTableEsc(pieceToChar, "P.BRQSEXOGCATHD.VMLIFN:+.++.++++++++++.+++++K"
+ "p.brqsexogcathd.vmlifn:+.++.++++++++++.+++++k", SUFFIXES);
break;
case VariantCourier:
pieces = CourierArray;
/* User pieceToChar list overrules defaults */
if(appData.pieceToCharTable != NULL)
- SetCharTable(pieceToChar, appData.pieceToCharTable);
+ SetCharTableEsc(pieceToChar, appData.pieceToCharTable, SUFFIXES);
for( j=0; j<BOARD_WIDTH; j++ ) { ChessSquare s = EmptySquare;
if(appData.icsActive || forwardMostMove != 0 || cps != &first) return;
*buf = NULLCHAR;
if(sscanf(message, "setup (%s", buf) == 1) {
- s = 8 + strlen(buf), buf[s-9] = NULLCHAR, SetCharTable(pieceToChar, buf);
+ s = 8 + strlen(buf), buf[s-9] = NULLCHAR, SetCharTableEsc(pieceToChar, buf, SUFFIXES);
ASSIGN(appData.pieceToCharTable, buf);
}
dummy = sscanf(message+s, "%dx%d+%d_%s", &w, &h, &hand, varName);
appData.NrFiles = w; appData.NrRanks = h; appData.holdingsSize = hand;
if(dummy == 4) gameInfo.variant = StringToVariant(varName); // parent variant
InitPosition(1); // calls InitDrawingSizes to let new parameters take effect
- if(*buf) SetCharTable(pieceToChar, buf); // do again, for it was spoiled by InitPosition
+ if(*buf) SetCharTableEsc(pieceToChar, buf, SUFFIXES); // do again, for it was spoiled by InitPosition
startedFromSetupPosition = FALSE;
}
}
piece = (ChessSquare)(CHUDEMOTED piece);
}
*p++ = (piece == DarkSquare ? '*' : PieceToChar(piece));
+ if(*p = PieceSuffix(piece)) p++;
if(p[-1] == '~') {
/* [HGM] flag promoted pieces as '<promoted>~' (Crazyhouse) */
p[-1] = PieceToChar((ChessSquare)(CHUDEMOTED piece));
if (i != 0 && i != BOARD_HEIGHT-1) return FALSE; // only on back-rank
board[i][(j++)+gameInfo.holdingsWidth] = ClearBoard; p++; subst++; // placeHolder
} else if (*p == '+' || isalpha(*p)) {
+ char *q, *s = SUFFIXES;
if (j >= gameInfo.boardWidth) return FALSE;
if(*p=='+') {
- piece = CharToPiece(*++p);
+ char c = *++p;
+ if(q = strchr(s, p[1])) p++;
+ piece = CharToPiece(c + (q ? 64*(q - s + 1) : 0));
if(piece == EmptySquare) return FALSE; /* unknown piece */
piece = (ChessSquare) (CHUPROMOTED piece ); p++;
if(PieceToChar(piece) != '+') return FALSE; /* unpromotable piece */
- } else piece = CharToPiece(*p++);
+ } else {
+ char c = *p++;
+ if(q = strchr(s, *p)) p++;
+ piece = CharToPiece(c + (q ? 64*(q - s + 1) : 0));
+ }
if(piece==EmptySquare) return FALSE; /* unknown piece */
if(*p == '~') { /* [HGM] make it a promoted piece for Crazyhouse */
#define SameColor(piece1, piece2) (piece1 < EmptySquare && piece2 < EmptySquare && (piece1 < BlackPawn) == (piece2 < BlackPawn) || piece1 == DarkSquare || piece2 == DarkSquare)
#endif
-char pieceToChar[] = {
+unsigned char pieceToChar[EmptySquare+1] = {
'P', 'N', 'B', 'R', 'Q', 'F', 'E', 'A', 'C', 'W', 'M',
'O', 'H', 'I', 'J', 'G', 'D', 'V', 'L', 'S', 'U', 'K',
'p', 'n', 'b', 'r', 'q', 'f', 'e', 'a', 'c', 'w', 'm',
'o', 'h', 'i', 'j', 'g', 'd', 'v', 'l', 's', 'u', 'k',
'x' };
-char pieceNickName[EmptySquare];
+unsigned char pieceNickName[EmptySquare];
char
PieceToChar (ChessSquare p)
{
+ int c;
if((int)p < 0 || (int)p >= (int)EmptySquare) return('x'); /* [HGM] for safety */
- return pieceToChar[(int) p];
+ c = pieceToChar[(int) p];
+ if(c & 128) c = c & 63 | 64;
+ return c;
+}
+
+char
+PieceSuffix (ChessSquare p)
+{
+ int c;
+ if((int)p < 0 || (int)p >= (int)EmptySquare) return 0; /* [HGM] for safety */
+ c = pieceToChar[(int) p];
+ if(c < 128) return 0;
+ return SUFFIXES[c - 128 >> 6];
}
int
}
if(c=='+') *outp++ = c;
*outp++ = ToUpper(PieceToChar(piece));
+ if(*outp = PieceSuffix(piece)) outp++;
if (cl.file || (cl.either && !cl.rank)) {
*outp++ = ff + AAA;
*------------------------------------------------------------------------
** See the file ChangeLog for a revision history. */
+#define SUFFIXES "'!"
+
extern ChessSquare PromoPiece P((ChessMove moveType));
extern ChessMove PromoCharToMoveType P((int whiteOnMove, int promoChar));
extern char PieceToChar P((ChessSquare p));
+extern char PieceSuffix P((ChessSquare p));
extern ChessSquare CharToPiece P((int c));
extern int PieceToNumber P((ChessSquare p));
extern void CopyBoard P((Board to, Board from));
extern int CompareBoards P((Board board1, Board board2));
-extern char pieceToChar[(int)EmptySquare+1];
-extern char pieceNickName[(int)EmptySquare];
+extern unsigned char pieceToChar[(int)EmptySquare+1];
+extern unsigned char pieceNickName[(int)EmptySquare];
extern char *pieceDesc[(int)EmptySquare];
extern Board initialPosition;
extern Boolean pieceDefs;