AAA + ff, ONE + rf, AAA + ft, ONE + rt);
} else {
sprintf(move, "%c%c%c%c%c\n",
- AAA + ff, ONE + rf, AAA + ft, ONE + rt, promoChar == '^' ? '+' : promoChar);
+ AAA + ff, ONE + rf, AAA + ft, ONE + rt, promoChar);
}
}
}
int *fromX, *fromY, *toX, *toY;
char *promoChar;
{
- char moveCopy[20], *p = moveCopy;
- strncpy(moveCopy, move, 20); // make a copy of move to preprocess it
- if(gameInfo.variant == VariantShogi) {
- while(*p && *p != ' ') p++;
- if(p[-1] == '+') p[-1] = '^'; // in Shogi '+' is promotion, distinguish from check
- }
- if (appData.debugMode) {
- fprintf(debugFP, "move to parse: %s\n", moveCopy);
- }
- *moveType = yylexstr(moveNum, moveCopy, yy_textstr, sizeof yy_textstr);
+ *moveType = yylexstr(moveNum, move, yy_textstr, sizeof yy_textstr);
switch (*moveType) {
case WhitePromotion:
if(toY == 0 && piece == BlackPawn ||
toY == 0 && piece == BlackQueen ||
toY <= 1 && piece == BlackKnight) {
- *promoChoice = '^';
+ *promoChoice = '+';
return FALSE;
}
} else {
if(toY == BOARD_HEIGHT-1 && piece == WhitePawn ||
toY == BOARD_HEIGHT-1 && piece == WhiteQueen ||
toY >= BOARD_HEIGHT-2 && piece == WhiteKnight) {
- *promoChoice = '^';
+ *promoChoice = '+';
return FALSE;
}
}
gameMode == IcsPlayingBlack && WhiteOnMove(currentMove);
if(appData.testLegality && !premove) {
moveType = LegalityTest(boards[currentMove], PosFlags(currentMove),
- fromY, fromX, toY, toX, gameInfo.variant == VariantShogi ? '^' : NULLCHAR);
+ fromY, fromX, toY, toX, gameInfo.variant == VariantShogi ? '+' : NULLCHAR);
if(moveType != WhitePromotion && moveType != BlackPromotion)
return FALSE;
}
board[toY][toX] = EmptySquare;
}
}
- if(promoChar == '^') {
+ if(promoChar == '+') {
/* [HGM] Shogi-style promotions, to piece implied by original (Might overwrite orinary Pawn promotion) */
board[toY][toX] = (ChessSquare) (PROMOTED piece);
- } else if(!appData.testLegality) { // without legality testing, unconditionally believe promoChar
- board[toY][toX] = CharToPiece(promoChar);
+ } else if(!appData.testLegality && promoChar != NULLCHAR && promoChar != '=') { // without legality testing, unconditionally believe promoChar
+ board[toY][toX] = CharToPiece(piece < BlackPawn ? ToUpper(promoChar) : ToLower(promoChar));
}
if((gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat)
&& promoChar != NULLCHAR && gameInfo.holdingsSize) {
if(promoChar == 'd' && (piece == WhiteRook || piece == BlackRook) ||
promoChar == 'h' && (piece == WhiteBishop || piece == BlackBishop) ||
promoChar == 'g' && (piece <= WhiteFerz || piece <= BlackFerz && piece >= BlackPawn) )
- promoChar = '^'; // allowed ICS notations
+ promoChar = '+'; // allowed ICS notations
if(appData.debugMode)fprintf(debugFP,"SHOGI promoChar = %c\n", promoChar ? promoChar : '-');
- if(promoChar != NULLCHAR && promoChar != '^' && promoChar != '=')
+ if(promoChar != NULLCHAR && promoChar != '+' && promoChar != '=')
return CharToPiece(promoChar) == EmptySquare ? ImpossibleMove : IllegalMove;
else if(flags & F_WHITE_ON_MOVE) {
if( (int) piece < (int) WhiteWazir &&
piece == WhiteKnight && rt > BOARD_HEIGHT-3) /* promotion mandatory */
cl.kind = promoChar == '=' ? IllegalMove : WhitePromotion;
else /* promotion optional, default is defer */
- cl.kind = promoChar == '^' ? WhitePromotion : WhiteNonPromotion;
- } else cl.kind = promoChar == '^' ? IllegalMove : NormalMove;
+ cl.kind = promoChar == '+' ? WhitePromotion : WhiteNonPromotion;
+ } else cl.kind = promoChar == '+' ? IllegalMove : NormalMove;
} else {
if( (int) piece < (int) BlackWazir && (rf < BOARD_HEIGHT/3 || rt < BOARD_HEIGHT/3) ) {
if( (piece == BlackPawn || piece == BlackQueen) && rt < 1 ||
piece == BlackKnight && rt < 2 ) /* promotion obligatory */
cl.kind = promoChar == '=' ? IllegalMove : BlackPromotion;
else /* promotion optional, default is defer */
- cl.kind = promoChar == '^' ? BlackPromotion : BlackNonPromotion;
- } else cl.kind = promoChar == '^' ? IllegalMove : NormalMove;
+ cl.kind = promoChar == '+' ? BlackPromotion : BlackNonPromotion;
+ } else cl.kind = promoChar == '+' ? IllegalMove : NormalMove;
}
}
} else
if (c == 'x') c = NULLCHAR; // get rid of any 'x' (which should never happen?)
if(gameInfo.variant == VariantShogi) {
- /* [HGM] Shogi promotions. On input, '=' means defer, '^' promote. Afterwards, c is set to '+' for promotions, NULL other */
+ /* [HGM] Shogi promotions. On input, '=' means defer, '+' promote. Afterwards, c is set to '+' for promotions, NULL other */
if(closure->rfIn != DROP_RANK && closure->kind == NormalMove) {
ChessSquare piece = closure->piece;
if (c == 'd' && (piece == WhiteRook || piece == BlackRook) ||
c == 'h' && (piece == WhiteBishop || piece == BlackBishop) ||
c == 'g' && (piece <= WhiteFerz || piece <= BlackFerz && piece >= BlackPawn) )
- c = '^'; // allowed ICS notations
- if(c != NULLCHAR && c != '^' && c != '=') closure->kind = IllegalMove; // otherwise specifying a piece is illegal
+ c = '+'; // allowed ICS notations
+ if(c != NULLCHAR && c != '+' && c != '=') closure->kind = IllegalMove; // otherwise specifying a piece is illegal
else if(flags & F_WHITE_ON_MOVE) {
if( (int) piece < (int) WhiteWazir &&
(closure->rf >= BOARD_HEIGHT-(BOARD_HEIGHT/3) || closure->rt >= BOARD_HEIGHT-(BOARD_HEIGHT/3)) ) {
piece == WhiteKnight && closure->rt > BOARD_HEIGHT-3) /* promotion mandatory */
closure->kind = c == '=' ? IllegalMove : WhitePromotion;
else /* promotion optional, default is defer */
- closure->kind = c == '^' ? WhitePromotion : WhiteNonPromotion;
- } else closure->kind = c == '^' ? IllegalMove : NormalMove;
+ closure->kind = c == '+' ? WhitePromotion : WhiteNonPromotion;
+ } else closure->kind = c == '+' ? IllegalMove : NormalMove;
} else {
if( (int) piece < (int) BlackWazir && (closure->rf < BOARD_HEIGHT/3 || closure->rt < BOARD_HEIGHT/3) ) {
if( (piece == BlackPawn || piece == BlackQueen) && closure->rt < 1 ||
piece == BlackKnight && closure->rt < 2 ) /* promotion obligatory */
closure->kind = c == '=' ? IllegalMove : BlackPromotion;
else /* promotion optional, default is defer */
- closure->kind = c == '^' ? BlackPromotion : BlackNonPromotion;
- } else closure->kind = c == '^' ? IllegalMove : NormalMove;
+ closure->kind = c == '+' ? BlackPromotion : BlackNonPromotion;
+ } else closure->kind = c == '+' ? IllegalMove : NormalMove;
}
}
- if(closure->kind == WhitePromotion || closure->kind == BlackPromotion) c = '^'; else
+ if(closure->kind == WhitePromotion || closure->kind == BlackPromotion) c = '+'; else
if(closure->kind == WhiteNonPromotion || closure->kind == BlackNonPromotion) c = '=';
} else
if (closure->kind == WhitePromotion || closure->kind == BlackPromotion) {
} else if (c != NULLCHAR) closure->kind = IllegalMove;
closure->promoChar = ToLower(c); // this can be NULLCHAR! Note we keep original promoChar even if illegal.
- if(c != '^' && c != '=' && c != NULLCHAR && CharToPiece(c) == EmptySquare)
+ if(c != '+' && c != '=' && c != NULLCHAR && CharToPiece(c) == EmptySquare)
closure->kind = ImpossibleMove; // but we cannot handle non-existing piece types!
if (closure->count > 1) {
closure->kind = AmbiguousMove;
else { *outp++ = (rt+ONE-'0')/10 + '0';*outp++ = (rt+ONE-'0')%10 + '0'; }
if (gameInfo.variant == VariantShogi) {
/* [HGM] in Shogi non-pawns can promote */
- if(promoChar == '^') promoChar = '+';
*outp++ = promoChar; // Don't bother to correct move type, return value is never used!
}
*outp = NULLCHAR;
* Ranks can be 0-9. The parser returns 0 for off-board files and ranks.
* For an unknown piece (as mover or promotion piece) it returns
* IllegalMove, like it does when the piece doesn't match.
- * Promotions can now also be appended Shogi-style, a bare '=' or '^',
+ * Promotions can now also be appended Shogi-style, a bare '=' or '+',
* and this is then returned as promotion character. The piece indicator
* can be prefixed by a '+' to indicate it is a promoted piece.
*/
%}
%%
-"+"?[A-Z][/]?[a-l][0-9][xX:-]?[a-l][0-9]((=?\(?[A-Z]\)?)|[=^])? {
+"+"?[A-Z][/]?[a-l][0-9][xX:-]?[a-l][0-9]((=?\(?[A-Z]\)?)|[=+])? {
/*
* Fully-qualified algebraic move, possibly with promotion
*/
} else {
c = currentMoveString[4] = ToLower(yytext[yyleng-1]);
}
+ if(c == '+' && gameInfo.variant != VariantShogi) c = currentMoveString[4] = NULLCHAR; // + means check outside Shogi
currentMoveString[5] = NULLCHAR;
}
else if(gameInfo.variant == VariantGreat)
currentMoveString[4] = PieceToChar(BlackMan);
else if(gameInfo.variant == VariantShogi)
- currentMoveString[4] = '^';
+ currentMoveString[4] = '+';
else
currentMoveString[4] = PieceToChar(BlackQueen);
} else if(result == WhiteNonPromotion || result == BlackNonPromotion)
return (int) result;
}
-[a-l][0-9][xX:-]?[a-l][0-9]((=?\(?[A-Za-z]\)?)|[=^])? {
+[a-l][0-9][xX:-]?[a-l][0-9]((=?\(?[A-Za-z]\)?)|[=+])? {
/*
* Simple algebraic move, possibly with promotion
* [HGM] Engine moves are received in this format, with lower-case promoChar!
} else {
c = currentMoveString[4] = ToLower(yytext[yyleng-1]);
}
+ if(c == '+' && gameInfo.variant != VariantShogi) c = currentMoveString[4] = NULLCHAR; // + means check outside Shogi
currentMoveString[5] = NULLCHAR;
}
else if(gameInfo.variant == VariantGreat)
currentMoveString[4] = PieceToChar(BlackMan);
else if(gameInfo.variant == VariantShogi)
- currentMoveString[4] = '^'; // Queen might not be defined in mini variants!
+ currentMoveString[4] = '+'; // Queen might not be defined in mini variants!
else
currentMoveString[4] = PieceToChar(BlackQueen);
} else if(result == WhiteNonPromotion || result == BlackNonPromotion)
return (int) result;
}
-[a-l][0-9]((=?\(?[A-Za-z]\)?)|[=^])? {
+[a-l][0-9]((=?\(?[A-Za-z]\)?)|[=+])? {
/*
* Pawn move, possibly with promotion
*/
cl.ffIn = yytext[0] - AAA;
cl.rtIn = yytext[1] - ONE;
cl.ftIn = yytext[0] - AAA;
- c = cl.promoCharIn = ToLower(yytext[2+skip]);
+ cl.promoCharIn = ToLower(yytext[2+skip]);
+ if(cl.promoCharIn == '+' && gameInfo.variant != VariantShogi) cl.promoCharIn = NULLCHAR; // + means check outside Shogi
/* [HGM] do not allow values beyond board size */
if(cl.rtIn >= BOARD_HEIGHT ||
cl.ffIn = yytext[0] - AAA;
cl.rtIn = -1;
cl.ftIn = yytext[1+skip1] - AAA;
- c = cl.promoCharIn = yytext[2+skip1+skip2];
+ cl.promoCharIn = yytext[2+skip1+skip2];
+ if(cl.promoCharIn == '+' && gameInfo.variant != VariantShogi) cl.promoCharIn = NULLCHAR; // + means check outside Shogi
/* [HGM] do not allow values beyond board size */
if(cl.ffIn >= BOARD_RGHT ||
return (int) cl.kind;
}
-[a-l][xX:]?[a-l][0-9]((=?\(?[A-Z]\)?)|ep|"e.p."|[=^])? {
+[a-l][xX:]?[a-l][0-9]((=?\(?[A-Z]\)?)|ep|"e.p."|[=+])? {
/*
* unambiguously abbreviated Pawn capture, possibly with promotion
*/
else
c = currentMoveString[4] = ToLower(yytext[yyleng-1]);
currentMoveString[5] = NULLCHAR;
- if(c != '=' && c != '^' && CharToPiece(c) == EmptySquare)
+ if(c != '=' && c != '+' && CharToPiece(c) == EmptySquare)
return ImpossibleMove;
+ if(c == '+' && gameInfo.variant != VariantShogi) c = currentMoveString[4] = NULLCHAR; // + means check outside Shogi
} else {
currentMoveString[4] = NULLCHAR;
}
if(gameInfo.variant == VariantGreat)
currentMoveString[4] = PieceToChar(BlackMan);
if(gameInfo.variant == VariantShogi)
- currentMoveString[4] = '^';
+ currentMoveString[4] = '+';
} else if(result == WhiteNonPromotion || result == BlackNonPromotion)
currentMoveString[4] = '=';
currentMoveString[5] = NULLCHAR;
return (int) IllegalMove;
}
-"+"?[A-Z][xX:-]?[a-l][0-9]((=?\(?[A-Z]\)?)|[=^])? {
+"+"?[A-Z][xX:-]?[a-l][0-9]((=?\(?[A-Z]\)?)|[=+])? {
/*
* piece move, possibly ambiguous
*/
cl.ftIn = yytext[1+skip] - AAA;
cl.promoCharIn = NULLCHAR;
- if(yyleng-skip > 3) /* [HGM] can have Shogi-style promotion */
+ if(yyleng-skip > 3 && gameInfo.variant == VariantShogi) /* [HGM] can have Shogi-style promotion */
cl.promoCharIn = yytext[yyleng-1-(yytext[yyleng-1]==')')];
+ if(cl.promoCharIn == '+' && gameInfo.variant != VariantShogi) cl.promoCharIn = NULLCHAR; // + means check outside Shogi
if (appData.debugMode) {
fprintf(debugFP, "Parser Qa1: yyleng=%d, %d(%d,%d)-(%d,%d) = %d (%c)\n",
return (int) cl.kind;
}
-"+"?[A-Z][a-l0-9][xX:-]?[a-l][0-9]((=?\(?[A-Z]\)?)|[=^])? {
+"+"?[A-Z][a-l0-9][xX:-]?[a-l][0-9]((=?\(?[A-Z]\)?)|[=+])? {
/*
* piece move with rank or file disambiguator
*/
if(yyleng-skip > 4) /* [HGM] can have Shogi-style promotion */
cl.promoCharIn = yytext[yyleng-1-(yytext[yyleng-1]==')')];
+ if(cl.promoCharIn == '+' && gameInfo.variant != VariantShogi) cl.promoCharIn = NULLCHAR; // + means check outside Shogi
/* [HGM] do not allow values beyond board size */
if(cl.rtIn >= BOARD_HEIGHT ||
promoChar = gameInfo.variant == VariantSuper ? PieceToChar(BlackSilver) : PieceToChar(BlackKing);\r
break;\r
case PB_Queen:\r
- promoChar = gameInfo.variant == VariantShogi ? '^' : PieceToChar(BlackQueen);\r
+ promoChar = gameInfo.variant == VariantShogi ? '+' : PieceToChar(BlackQueen);\r
break;\r
case PB_Rook:\r
promoChar = PieceToChar(BlackRook);\r
} else if (strcmp(name, _("Knight")) == 0) {
promoChar = 'n';
} else if (strcmp(name, _("Promote")) == 0) {
- promoChar = '^';
+ promoChar = '+';
} else if (strcmp(name, _("Defer")) == 0) {
promoChar = '=';
} else {