return WhiteKing;\r
case BlackPromotionKing:\r
return BlackKing;\r
-#ifdef FAIRY\r
case WhitePromotionChancellor:\r
return WhiteMarshall;\r
case BlackPromotionChancellor:\r
return BlackMarshall;\r
case WhitePromotionArchbishop:\r
- return WhiteCardinal;\r
+ return WhiteAngel;\r
case BlackPromotionArchbishop:\r
- return BlackCardinal;\r
-#endif\r
- }\r
-}\r
-\r
-ChessMove PromoCharToMoveType(whiteOnMove, promoChar)\r
- int whiteOnMove;\r
- int promoChar;\r
-{\r
- if (whiteOnMove) {\r
- switch (promoChar) {\r
- case 'n':\r
- case 'N':\r
- return WhitePromotionKnight;\r
- case 'b':\r
- case 'B':\r
- return WhitePromotionBishop;\r
- case 'r':\r
- case 'R':\r
- return WhitePromotionRook;\r
-#ifdef FAIRY\r
- case 'a':\r
- case 'A':\r
- return WhitePromotionArchbishop;\r
- case 'c':\r
- case 'C':\r
- return WhitePromotionChancellor;\r
-#endif\r
- case 'q':\r
- case 'Q':\r
- return WhitePromotionQueen;\r
- case 'k':\r
- case 'K':\r
- return WhitePromotionKing;\r
- case NULLCHAR:\r
- default:\r
- return NormalMove;\r
- }\r
- } else {\r
- switch (promoChar) {\r
- case 'n':\r
- case 'N':\r
- return BlackPromotionKnight;\r
- case 'b':\r
- case 'B':\r
- return BlackPromotionBishop;\r
- case 'r':\r
- case 'R':\r
- return BlackPromotionRook;\r
-#ifdef FAIRY\r
- case 'a':\r
- case 'A':\r
- return BlackPromotionArchbishop;\r
- case 'c':\r
- case 'C':\r
- return BlackPromotionChancellor;\r
-#endif\r
- case 'q':\r
- case 'Q':\r
- return BlackPromotionQueen;\r
- case 'k':\r
- case 'K':\r
- return BlackPromotionKing;\r
- case NULLCHAR:\r
- default:\r
- return NormalMove;\r
- }\r
+ return BlackAngel;\r
+ case WhitePromotionCentaur:\r
+ return WhiteSilver;\r
+ case BlackPromotionCentaur:\r
+ return BlackSilver;\r
}\r
}\r
\r
char pieceToChar[] = {\r
'P', 'N', 'B', 'R', 'Q', 'F', 'E', 'A', 'C', 'W', 'M', \r
- 'O', 'H', 'I', 'J', 'G', 'D', 'V', 'S', 'L', 'U', 'K',\r
+ 'O', 'H', 'I', 'J', 'G', 'D', 'V', 'L', 's', 'U', 'K',\r
'p', 'n', 'b', 'r', 'q', 'f', 'e', 'a', 'c', 'w', 'm', \r
- 'o', 'h', 'i', 'j', 'g', 'd', 'v', 's', 'l', 'u', 'k', \r
+ 'o', 'h', 'i', 'j', 'g', 'd', 'v', 'l', 's', 'u', 'k', \r
'x' };\r
\r
char PieceToChar(p)\r
return EmptySquare;\r
}\r
\r
+ChessMove PromoCharToMoveType(whiteOnMove, promoChar)\r
+ int whiteOnMove;\r
+ int promoChar;\r
+{ /* [HGM] made dependent on CharToPiece to alow alternate piece letters */\r
+ ChessSquare piece = CharToPiece(whiteOnMove ? ToUpper(promoChar) : ToLower(promoChar) );\r
+\r
+
+ if(promoChar == NULLCHAR) return NormalMove;\r
+\r
+ switch(piece) {\r
+ case WhiteQueen:\r
+ return WhitePromotionQueen;\r
+ case WhiteRook:\r
+ return WhitePromotionRook;\r
+ case WhiteBishop:\r
+ return WhitePromotionBishop;\r
+ case WhiteKnight:\r
+ return WhitePromotionKnight;\r
+ case WhiteKing:\r
+ return WhitePromotionKing;\r
+ case WhiteAngel:\r
+ return WhitePromotionArchbishop;\r
+ case WhiteMarshall:\r
+ return WhitePromotionChancellor;\r
+ case WhiteSilver:\r
+ return WhitePromotionCentaur;\r
+ case BlackQueen:\r
+ return BlackPromotionQueen;\r
+ case BlackRook:\r
+ return BlackPromotionRook;\r
+ case BlackBishop:\r
+ return BlackPromotionBishop;\r
+ case BlackKnight:\r
+ return BlackPromotionKnight;\r
+ case BlackKing:\r
+ return BlackPromotionKing;\r
+ case BlackAngel:\r
+ return BlackPromotionArchbishop;\r
+ case BlackMarshall:\r
+ return BlackPromotionChancellor;\r
+ case BlackSilver:\r
+ return BlackPromotionCentaur;\r
+ default:\r
+ // not all promotion implemented yet! Take Queen for those we don't know.\r
+ return (whiteOnMove ? WhitePromotionQueen : BlackPromotionQueen);\r
+ }\r
+}\r
+\r
void CopyBoard(to, from)\r
Board to, from;\r
{\r
if (board[rt][ft] != EmptySquare) break;\r
}\r
if(m==1) goto mounted;\r
- if(m==2) goto walking;\r
+ if(m==2) goto finishGold;\r
break;\r
\r
case WhiteQueen:\r
}\r
break;\r
\r
+ case WhiteSilver:\r
+ case BlackSilver:\r
+ m++; // [HGM] superchess: use for Centaur\r
case WhiteMan:\r
case BlackMan:\r
case SHOGI WhiteKing:\r
callback(board, flags, NormalMove,\r
rf, ff, rt, ft, closure);\r
}\r
+ if(m==1) goto mounted;\r
break;\r
\r
case WhiteNightrider:\r
(ignoreCheck || \r
(!CheckTest(board, flags, 0, ff, 0, ff + 1, FALSE) &&\r
!CheckTest(board, flags, 0, ff, 0, BOARD_RGHT-3, FALSE) &&\r
+ (gameInfo.variant != VariantJanus || !CheckTest(board, flags, 0, ff, 0, BOARD_RGHT-2, FALSE)) &&\r
!CheckTest(board, flags, 0, ff, 0, ff + 2, FALSE)))) {\r
\r
callback(board, flags,\r
ff==BOARD_WIDTH>>1 ? WhiteKingSideCastle : WhiteKingSideCastleWild,\r
- 0, ff, 0, ff + ((gameInfo.boardWidth+2)>>2), closure);\r
+ 0, ff, 0, ff + ((gameInfo.boardWidth+2)>>2) + (gameInfo.variant == VariantJanus), closure);\r
}\r
if ((flags & F_WHITE_ON_MOVE) &&\r
(flags & F_WHITE_QCASTLE_OK) &&\r
( castlingRights[2] == ff || castlingRights[6] == ff ) &&\r
(ignoreCheck ||\r
(!CheckTest(board, flags, 0, ff, 0, ff - 1, FALSE) &&\r
- !CheckTest(board, flags, 0, ff, 0, BOARD_LEFT+3, FALSE) &&\r
+ !CheckTest(board, flags, 0, ff, 0, BOARD_LEFT+3, FALSE) &&\r
!CheckTest(board, flags, 0, ff, 0, ff - 2, FALSE)))) {\r
\r
callback(board, flags,\r
(ignoreCheck ||\r
(!CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff + 1, FALSE) &&\r
!CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, BOARD_RGHT-3, FALSE) &&\r
+ (gameInfo.variant != VariantJanus || !CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, BOARD_RGHT-2, FALSE)) &&\r
!CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff + 2, FALSE)))) {\r
\r
callback(board, flags,\r
ff==BOARD_WIDTH>>1 ? BlackKingSideCastle : BlackKingSideCastleWild,\r
- BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff + ((gameInfo.boardWidth+2)>>2), closure);\r
+ BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff + ((gameInfo.boardWidth+2)>>2) + (gameInfo.variant == VariantJanus), closure);\r
}\r
if (!(flags & F_WHITE_ON_MOVE) &&\r
(flags & F_BLACK_QCASTLE_OK) &&\r
( castlingRights[5] == ff || castlingRights[7] == ff ) &&\r
(ignoreCheck ||\r
(!CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff - 1, FALSE) &&\r
- !CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, BOARD_LEFT+3, FALSE) &&\r
+ !CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, BOARD_LEFT+3, FALSE) &&\r
!CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff - 2, FALSE)))) {\r
\r
callback(board, flags,\r
\r
if ((flags & F_WHITE_ON_MOVE) != 0) {\r
ff = castlingRights[2]; /* King file if we have any rights */\r
- if(ff > 0) {\r
+ if(ff > 0 && board[0][ff] == WhiteKing) {\r
if (appData.debugMode) {\r
fprintf(debugFP, "FRC castling, %d %d %d %d %d %d\n",\r
castlingRights[0],castlingRights[1],ff,castlingRights[3],castlingRights[4],castlingRights[5]);\r
if(k != ft && board[0][k] != EmptySquare) ft = -1;\r
for(k=left; k<right && ft >= 0; k++) /* then if not checked */\r
if(!ignoreCheck && CheckTest(board, flags, 0, ff, 0, k, FALSE)) ft = -1;\r
- if(ft >= 0)\r
+ if(ft >= 0 && board[0][ft] == WhiteRook)\r
callback(board, flags, WhiteHSideCastleFR, 0, ff, 0, ft, closure);\r
\r
ft = castlingRights[1]; /* Rook file if we have A-side rights */\r
if(ff > BOARD_LEFT+2) \r
for(k=left+1; k<=right && ft >= 0; k++) /* then if not checked */\r
if(!ignoreCheck && CheckTest(board, flags, 0, ff, 0, k, FALSE)) ft = -1;\r
-\r
- if(ft >= 0)\r
+ if(ft >= 0 && board[0][ft] == WhiteRook)\r
callback(board, flags, WhiteASideCastleFR, 0, ff, 0, ft, closure);\r
}\r
} else {\r
ff = castlingRights[5]; /* King file if we have any rights */\r
- if(ff > 0) {\r
+ if(ff > 0 && board[BOARD_HEIGHT-1][ff] == BlackKing) {\r
ft = castlingRights[3]; /* Rook file if we have H-side rights */\r
left = ff+1;\r
right = BOARD_RGHT-2;\r
if(k != ft && board[BOARD_HEIGHT-1][k] != EmptySquare) ft = -1;\r
for(k=left; k<right && ft >= 0; k++) /* then if not checked */\r
if(!ignoreCheck && CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, k, FALSE)) ft = -1;\r
- if(ft >= 0)\r
+ if(ft >= 0 && board[BOARD_HEIGHT-1][ft] == BlackRook)\r
callback(board, flags, BlackHSideCastleFR, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ft, closure);\r
\r
ft = castlingRights[4]; /* Rook file if we have A-side rights */\r
if(ff > BOARD_LEFT+2) \r
for(k=left+1; k<=right && ft >= 0; k++) /* then if not checked */\r
if(!ignoreCheck && CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, k, FALSE)) ft = -1;\r
-\r
- if(ft >= 0)\r
+ if(ft >= 0 && board[BOARD_HEIGHT-1][ft] == BlackRook)\r
callback(board, flags, BlackASideCastleFR, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ft, closure);\r
}\r
}\r
}\r
} else\r
if (promoChar != NULLCHAR && promoChar != 'x') {\r
+ if(promoChar == '=') cl.kind = IllegalMove; else // [HGM] shogi: no deferred promotion outside Shogi\r
if (cl.kind == WhitePromotionQueen || cl.kind == BlackPromotionQueen) {\r
cl.kind = \r
PromoCharToMoveType((flags & F_WHITE_ON_MOVE) != 0, promoChar);\r
if (cl.count > 0) {\r
return inCheck ? MT_CHECK : MT_NONE;\r
} else {\r
- return inCheck || gameInfo.variant == VariantXiangqi ?\r
+ return inCheck || gameInfo.variant == VariantXiangqi || gameInfo.variant == VariantShatranj ?\r
MT_CHECKMATE : MT_STALEMATE;\r
}\r
}\r
closure->count = 0;\r
closure->rf = closure->ff = closure->rt = closure->ft = 0;\r
closure->kind = ImpossibleMove;\r
+ if (appData.debugMode) {\r
+ fprintf(debugFP, "Disambiguate in: %d(%d,%d)-(%d,%d) = %d (%c)\n",\r
+ closure->pieceIn,closure->ffIn,closure->rfIn,closure->ftIn,closure->rtIn,\r
+ closure->promoCharIn, closure->promoCharIn >= ' ' ? closure->promoCharIn : '-');\r
+ }\r
GenLegal(board, flags, epfile, initialRights, DisambiguateCallback, (VOIDSTAR) closure);\r
if (closure->count == 0) {\r
/* See if it's an illegal move due to check */\r
(VOIDSTAR) closure); \r
if (closure->count == 0) {\r
/* No, it's not even that */\r
+ if (appData.debugMode) { int i, j;\r
+ for(i=BOARD_HEIGHT-1; i>=0; i--) {\r
+ for(j=0; j<BOARD_WIDTH; j++)\r
+ fprintf(debugFP, "%3d", (int) board[i][j]);\r
+ fprintf(debugFP, "\n");\r
+ }\r
+ }\r
return;\r
}\r
}\r
\r
- if (appData.debugMode) {\r
- fprintf(debugFP, "Disambiguate in: %d(%d,%d)-(%d,%d) = %d (%c)\n",\r
- closure->pieceIn,closure->ffIn,closure->rfIn,closure->ftIn,closure->rtIn,\r
- closure->promoCharIn,closure->promoCharIn);\r
- }\r
if(gameInfo.variant == VariantShogi) {\r
/* [HGM] Shogi promotions. '=' means defer */\r
if(closure->rfIn != DROP_RANK && closure->kind == NormalMove) {\r
#endif\r
/* [HGM] returns 'q' for optional promotion, 'n' for mandatory */\r
if(closure->promoCharIn != '=')\r
- closure->promoChar = ToLower(PieceToChar(PromoPiece(closure->kind)));\r
+ closure->promoChar = ToLower(closure->promoCharIn);\r
else closure->promoChar = '=';\r
if (closure->promoChar == 'x') closure->promoChar = NULLCHAR;\r
if (closure->count > 1) {\r
}\r
if(closure->kind == IllegalMove)\r
/* [HGM] might be a variant we don't understand, pass on promotion info */\r
- closure->promoChar = closure->promoCharIn;\r
+ closure->promoChar = ToLower(closure->promoCharIn);\r
if (appData.debugMode) {\r
fprintf(debugFP, "Disambiguate out: %d(%d,%d)-(%d,%d) = %d (%c)\n",\r
- closure->piece,closure->ff,closure->rf,closure->ft,closure->rt,closure->promoChar,closure->promoChar);\r
+ closure->piece,closure->ff,closure->rf,closure->ft,closure->rt,closure->promoChar,\r
+ closure->promoChar >= ' ' ? closure->promoChar:'-');\r
}\r
}\r
\r
if(PieceToChar(piece)=='~') piece = (ChessSquare)(DEMOTED piece);\r
\r
if (appData.debugMode)\r
- fprintf(debugFP, "CoordsToAlgebraic, piece=%d (%d,%d)-(%d,%d) %c\n", (int)piece,ff,rf,ft,rt,promoChar );\r
+ fprintf(debugFP, "CoordsToAlgebraic, piece=%d (%d,%d)-(%d,%d) %c\n", (int)piece,ff,rf,ft,rt,promoChar >= ' ' ? promoChar : '-');\r
switch (piece) {\r
case WhitePawn:\r
case BlackPawn:\r
/* Use promotion suffix style "=Q" */\r
*outp = NULLCHAR;\r
if (appData.debugMode)\r
- fprintf(debugFP, "movetype=%d, promochar=%d=%c\n", (int)kind, promoChar, promoChar);\r
+ fprintf(debugFP, "movetype=%d, promochar=%d=%c\n", (int)kind, promoChar, promoChar >= ' ' ? promoChar : '-');\r
if (promoChar != NULLCHAR) {\r
if(gameInfo.variant == VariantShogi) {\r
/* [HGM] ... but not in Shogi! */\r
/* [HGM] Always long notation for fairies we don't know */\r
case WhiteFalcon:\r
case BlackFalcon:\r
- case WhiteSilver:\r
- case BlackSilver:\r
case WhiteLance:\r
case BlackLance:\r
case WhiteGrasshopper:\r