return BlackKing;\r
#ifdef FAIRY\r
case WhitePromotionChancellor:\r
- return WhiteFairyRook;\r
+ return WhiteMarshall;\r
case BlackPromotionChancellor:\r
- return BlackFairyRook;\r
+ return BlackMarshall;\r
case WhitePromotionArchbishop:\r
- return WhiteFairyBishop;\r
+ return WhiteCardinal;\r
case BlackPromotionArchbishop:\r
- return BlackFairyBishop;\r
+ return BlackCardinal;\r
#endif\r
}\r
}\r
}\r
\r
char pieceToChar[] = {\r
- 'P', 'N', 'B', 'R', \r
-#ifdef FAIRY\r
- 'A', 'C', 'F', 'H', 'E', 'W', 'D', 'O', 'G', 'M',\r
-#endif\r
- 'Q', 'K', 'p', 'n', 'b', 'r', \r
-#ifdef FAIRY \r
- 'a', 'c', 'f', 'h', 'e', 'w', 'd', 'o', 'g', 'm',\r
-#endif\r
- 'q', 'k', 'x'\r
+ 'P', 'N', 'B', 'R', 'Q', 'F', \r
+ 'W', 'E', 'M', 'O', 'U', 'H', 'A', 'C', 'G', 'S',\r
+ 'K', 'p', 'n', 'b', 'r', 'q', 'f', \r
+ 'w', 'e', 'm', 'o', 'u', 'h', 'a', 'c', 'g', 's',\r
+ 'k', 'x'\r
};\r
\r
char PieceToChar(p)\r
ChessSquare p;\r
{\r
+ if((int)p < 0 || (int)p >= (int)EmptySquare) return('x'); /* [HGM] for safety */\r
return pieceToChar[(int) p];\r
}\r
\r
+int PieceToNumber(p)\r
+ ChessSquare p;\r
+{\r
+ int i=0;\r
+ ChessSquare start = (int)p >= (int)BlackPawn ? BlackPawn : WhitePawn;\r
+\r
+ while(start++ != p) if(pieceToChar[(int)start-1] != '.') i++;\r
+ return i;\r
+}\r
+\r
ChessSquare CharToPiece(c)\r
int c;\r
-{ switch (c) {\r
- default:\r
- case 'x': return EmptySquare;\r
- case 'P': return WhitePawn;\r
- case 'R': return WhiteRook;\r
- case 'N': return WhiteKnight;\r
- case 'B': return WhiteBishop;\r
- case 'Q': return WhiteQueen;\r
- case 'K': return WhiteKing;\r
- case 'p': return BlackPawn;\r
- case 'r': return BlackRook;\r
- case 'n': return BlackKnight;\r
- case 'b': return BlackBishop;\r
- case 'q': return BlackQueen;\r
- case 'k': return BlackKing;\r
-#ifdef FAIRY\r
- case 'A': return WhiteCardinal;\r
- case 'C': return WhiteMarshall;\r
- case 'F': return WhiteFairyPawn;\r
- case 'H': return WhiteFairyKnight;\r
- case 'E': return WhiteFairyBishop;\r
- case 'W': return WhiteFairyRook;\r
- case 'D': return WhiteFairyCardinal;\r
- case 'O': return WhiteFairyMarshall;\r
- case 'G': return WhiteFairyQueen;\r
- case 'M': return WhiteFairyKing;\r
- \r
- case 'a': return BlackCardinal;\r
- case 'c': return BlackMarshall;\r
- case 'f': return BlackFairyPawn;\r
- case 'h': return BlackFairyKnight;\r
- case 'e': return BlackFairyBishop;\r
- case 'w': return BlackFairyRook;\r
- case 'd': return BlackFairyCardinal;\r
- case 'o': return BlackFairyMarshall;\r
- case 'g': return BlackFairyQueen;\r
- case 'm': return BlackFairyKing;\r
- \r
-#endif\r
- }\r
+{\r
+ int i;\r
+ for(i=0; i< (int) EmptySquare; i++)\r
+ if(pieceToChar[i] == c) return (ChessSquare) i;\r
+ return EmptySquare;\r
}\r
\r
void CopyBoard(to, from)\r
int i, j, d, s, fs, rs, rt, ft, m;\r
\r
for (rf = 0; rf < BOARD_HEIGHT; rf++) \r
- for (ff = 0; ff < BOARD_WIDTH; ff++) {\r
+ for (ff = BOARD_LEFT; ff < BOARD_RGHT; ff++) {\r
+ ChessSquare piece;\r
+\r
if (flags & F_WHITE_ON_MOVE) {\r
if (!WhitePiece(board[rf][ff])) continue;\r
} else {\r
if (!BlackPiece(board[rf][ff])) continue;\r
}\r
- m = 0;\r
- switch (board[rf][ff]) {\r
- case EmptySquare:\r
+ m = 0; piece = board[rf][ff];\r
+ if(gameInfo.variant == VariantCrazyhouse &&\r
+ ( (int) piece > (int) WhiteQueen && (int) piece < (int) WhiteKing\r
+ || (int) piece > (int) BlackQueen && (int) piece < (int) BlackKing ))\r
+ piece = (ChessSquare) ( DEMOTED piece );\r
+ if(gameInfo.variant == VariantShogi)\r
+ piece = (ChessSquare) ( SHOGI piece );\r
+\r
+ switch (piece) {\r
+ /* case EmptySquare: [HGM] this is nonsense, and conflicts with Shogi cases */\r
default:\r
/* can't happen ([HGM] except for faries...) */\r
break;\r
\r
case WhitePawn:\r
-#ifdef FAIRY\r
if(gameInfo.variant == VariantXiangqi) {\r
/* [HGM] capture and move straight ahead in Xiangqi */\r
if (rf < BOARD_HEIGHT-1 &&\r
/* and move sideways when across the river */\r
for (s = -1; s <= 1; s += 2) {\r
if (rf >= BOARD_HEIGHT>>1 &&\r
- ff + s >= 0 && ff + s < BOARD_WIDTH &&\r
+ ff + s >= BOARD_LEFT && ff + s < BOARD_RGHT &&\r
!WhitePiece(board[rf][ff+s]) ) {\r
callback(board, flags, NormalMove,\r
rf, ff, rf, ff+s, closure);\r
}\r
break;\r
}\r
-#endif\r
if (rf < BOARD_HEIGHT-1 && board[rf + 1][ff] == EmptySquare) {\r
callback(board, flags,\r
rf == BOARD_HEIGHT-2 ? WhitePromotionQueen : NormalMove,\r
}\r
if (rf == 1 && board[2][ff] == EmptySquare &&\r
gameInfo.variant != VariantShatranj && /* [HGM] */\r
+ gameInfo.variant != VariantCourier && /* [HGM] */\r
board[3][ff] == EmptySquare ) {\r
callback(board, flags, NormalMove,\r
rf, ff, 3, ff, closure);\r
}\r
for (s = -1; s <= 1; s += 2) {\r
- if (rf < BOARD_HEIGHT-1 && ff + s >= 0 && ff + s < BOARD_WIDTH &&\r
+ if (rf < BOARD_HEIGHT-1 && ff + s >= BOARD_LEFT && ff + s < BOARD_RGHT &&\r
((flags & F_KRIEGSPIEL_CAPTURE) ||\r
BlackPiece(board[rf + 1][ff + s]))) {\r
callback(board, flags, \r
rf, ff, rf + 1, ff + s, closure);\r
}\r
if (rf == BOARD_HEIGHT-4) {\r
- if (ff + s >= 0 && ff + s < BOARD_WIDTH &&\r
+ if (ff + s >= BOARD_LEFT && ff + s < BOARD_RGHT &&\r
(epfile == ff + s || epfile == EP_UNKNOWN) &&\r
board[BOARD_HEIGHT-4][ff + s] == BlackPawn &&\r
board[BOARD_HEIGHT-3][ff + s] == EmptySquare) {\r
break;\r
\r
case BlackPawn:\r
-#ifdef FAIRY\r
if(gameInfo.variant == VariantXiangqi) {\r
/* [HGM] capture straight ahead in Xiangqi */\r
if (rf > 0 && !SameColor(board[rf][ff], board[rf - 1][ff]) ) {\r
/* and move sideways when across the river */\r
for (s = -1; s <= 1; s += 2) {\r
if (rf < BOARD_HEIGHT>>1 &&\r
- ff + s >= 0 && ff + s < BOARD_WIDTH &&\r
+ ff + s >= BOARD_LEFT && ff + s < BOARD_RGHT &&\r
!BlackPiece(board[rf][ff+s]) ) {\r
callback(board, flags, NormalMove,\r
rf, ff, rf, ff+s, closure);\r
}\r
break;\r
}\r
-#endif\r
if (rf > 0 && board[rf - 1][ff] == EmptySquare) {\r
callback(board, flags, \r
rf == 1 ? BlackPromotionQueen : NormalMove,\r
}\r
if (rf == BOARD_HEIGHT-2 && board[BOARD_HEIGHT-3][ff] == EmptySquare &&\r
gameInfo.variant != VariantShatranj && /* [HGM] */\r
+ gameInfo.variant != VariantCourier && /* [HGM] */\r
board[BOARD_HEIGHT-4][ff] == EmptySquare) {\r
callback(board, flags, NormalMove,\r
rf, ff, BOARD_HEIGHT-4, ff, closure);\r
}\r
for (s = -1; s <= 1; s += 2) {\r
- if (rf > 0 && ff + s >= 0 && ff + s < BOARD_WIDTH &&\r
+ if (rf > 0 && ff + s >= BOARD_LEFT && ff + s < BOARD_RGHT &&\r
((flags & F_KRIEGSPIEL_CAPTURE) ||\r
WhitePiece(board[rf - 1][ff + s]))) {\r
callback(board, flags, \r
rf, ff, rf - 1, ff + s, closure);\r
}\r
if (rf == 3) {\r
- if (ff + s >= 0 && ff + s < BOARD_WIDTH &&\r
+ if (ff + s >= BOARD_LEFT && ff + s < BOARD_RGHT &&\r
(epfile == ff + s || epfile == EP_UNKNOWN) &&\r
board[3][ff + s] == WhitePawn &&\r
board[2][ff + s] == EmptySquare) {\r
} \r
break;\r
\r
+ case WhiteUnicorn:\r
+ case BlackUnicorn:\r
case WhiteKnight:\r
case BlackKnight:\r
mounted:\r
for (s = 1; s <= 2; s++) {\r
rt = rf + i*s;\r
ft = ff + j*(3-s);\r
- if (rt < 0 || rt >= BOARD_HEIGHT || ft < 0 || ft >= BOARD_WIDTH) continue;\r
- if (SameColor(board[rf][ff], board[rt][ft])) continue;\r
+ if (!(rt < 0 || rt >= BOARD_HEIGHT || ft < BOARD_LEFT || ft >= BOARD_RGHT)\r
+ && ( gameInfo.variant != VariantXiangqi || board[rf+i*(s-1)][ff+j*(2-s)] == EmptySquare)\r
+ && !SameColor(board[rf][ff], board[rt][ft]))\r
callback(board, flags, NormalMove,\r
rf, ff, rt, ft, closure);\r
}\r
break;\r
-#ifdef FAIRY\r
- case WhiteFairyMarshall:\r
- case BlackFairyMarshall:\r
+\r
+ case SHOGI WhiteKnight:\r
+ for (s = -1; s <= 1; s += 2) {\r
+ if (rf < BOARD_HEIGHT-2 && ff + s >= BOARD_LEFT && ff + s < BOARD_RGHT &&\r
+ !SameColor(board[rf][ff], board[rf + 2][ff + s])) {\r
+ callback(board, flags, NormalMove,\r
+ rf, ff, rf + 2, ff + s, closure);\r
+ }\r
+ }\r
+ break;\r
+\r
+ case SHOGI BlackKnight:\r
+ for (s = -1; s <= 1; s += 2) {\r
+ if (rf > 1 && ff + s >= BOARD_LEFT && ff + s < BOARD_RGHT &&\r
+ !SameColor(board[rf][ff], board[rf - 2][ff + s])) {\r
+ callback(board, flags, NormalMove,\r
+ rf, ff, rf - 2, ff + s, closure);\r
+ }\r
+ } \r
+ break;\r
+\r
+ case WhiteCannon:\r
+ case BlackCannon:\r
for (d = 0; d <= 1; d++)\r
for (s = -1; s <= 1; s += 2) {\r
m = 0;\r
for (i = 1;; i++) {\r
rt = rf + (i * s) * d;\r
ft = ff + (i * s) * (1 - d);\r
- if (rt < 0 || rt >= BOARD_HEIGHT || ft < 0 || ft >= BOARD_WIDTH) break;\r
+ if (rt < 0 || rt >= BOARD_HEIGHT || ft < BOARD_LEFT || ft >= BOARD_RGHT) break;\r
if (m == 0 && board[rt][ft] == EmptySquare)\r
callback(board, flags, NormalMove,\r
rf, ff, rt, ft, closure);\r
}\r
break;\r
\r
- case WhiteFairyRook:\r
- case BlackFairyRook:\r
+ /* Gold General (and all its promoted versions) . First do the */\r
+ /* diagonal forward steps, then proceed as normal Wazir */\r
+ case SHOGI WhiteWazir:\r
+ case SHOGI (PROMOTED WhitePawn):\r
+ case SHOGI (PROMOTED WhiteKnight):\r
+ case SHOGI (PROMOTED WhiteQueen):\r
+ case SHOGI (PROMOTED WhiteFerz):\r
+ for (s = -1; s <= 1; s += 2) {\r
+ if (rf < BOARD_HEIGHT-1 && ff + s >= BOARD_LEFT && ff + s < BOARD_RGHT &&\r
+ !SameColor(board[rf][ff], board[rf + 1][ff + s])) {\r
+ callback(board, flags, NormalMove,\r
+ rf, ff, rf + 1, ff + s, closure);\r
+ }\r
+ }\r
+ goto finishGold;\r
+\r
+ case SHOGI BlackWazir:\r
+ case SHOGI (PROMOTED BlackPawn):\r
+ case SHOGI (PROMOTED BlackKnight):\r
+ case SHOGI (PROMOTED BlackQueen):\r
+ case SHOGI (PROMOTED BlackFerz):\r
+ for (s = -1; s <= 1; s += 2) {\r
+ if (rf > 0 && ff + s >= BOARD_LEFT && ff + s < BOARD_RGHT &&\r
+ !SameColor(board[rf][ff], board[rf - 1][ff + s])) {\r
+ callback(board, flags, NormalMove,\r
+ rf, ff, rf - 1, ff + s, closure);\r
+ }\r
+ } \r
+\r
+ case WhiteWazir:\r
+ case BlackWazir:\r
+ finishGold:\r
for (d = 0; d <= 1; d++)\r
- for (s = -1; s <= 1; s += 2)\r
+ for (s = -1; s <= 1; s += 2) {\r
rt = rf + s * d;\r
ft = ff + s * (1 - d);\r
- if (!(rt < 0 || rt >= BOARD_HEIGHT || ft < 0 || ft >= BOARD_WIDTH)\r
- && !SameColor(board[rf][ff], board[rt][ft]))\r
+ if (!(rt < 0 || rt >= BOARD_HEIGHT || ft < BOARD_LEFT || ft >= BOARD_RGHT)\r
+ && !SameColor(board[rf][ff], board[rt][ft]) &&\r
+ (gameInfo.variant != VariantXiangqi || InPalace(rt, ft) ) )\r
callback(board, flags, NormalMove,\r
rf, ff, rt, ft, closure);\r
+ }\r
break;\r
\r
- case WhiteFairyBishop:\r
- case BlackFairyBishop:\r
+ case WhiteAlfil:\r
+ case BlackAlfil:\r
/* [HGM] support Shatranj pieces */\r
for (rs = -1; rs <= 1; rs += 2) \r
for (fs = -1; fs <= 1; fs += 2) {\r
rt = rf + 2 * rs;\r
ft = ff + 2 * fs;\r
- if (!(rt < 0 || rt >= BOARD_HEIGHT || ft < 0 || ft >= BOARD_WIDTH)\r
+ if (!(rt < 0 || rt >= BOARD_HEIGHT || ft < BOARD_LEFT || ft >= BOARD_RGHT)\r
+ && ( gameInfo.variant != VariantXiangqi ||\r
+ board[rf+rs][ff+fs] == EmptySquare && (2*rf < BOARD_HEIGHT) == (2*rt < BOARD_HEIGHT) )\r
+ \r
&& !SameColor(board[rf][ff], board[rt][ft]))\r
callback(board, flags, NormalMove,\r
rf, ff, rt, ft, closure);\r
}\r
break;\r
\r
+ /* Shogi Dragon Horse has to continue with Wazir after Bishop */\r
+ case SHOGI WhiteCardinal:\r
+ case SHOGI BlackCardinal:\r
+ m++;\r
+\r
+ /* Capablanca Archbishop continues as Knight */\r
case WhiteCardinal:\r
case BlackCardinal:\r
m++;\r
-#endif\r
+\r
+ /* Shogi Bishops are ordinary Bishops */\r
+ case SHOGI WhiteBishop:\r
+ case SHOGI BlackBishop:\r
case WhiteBishop:\r
case BlackBishop:\r
for (rs = -1; rs <= 1; rs += 2) \r
for (i = 1;; i++) {\r
rt = rf + (i * rs);\r
ft = ff + (i * fs);\r
- if (rt < 0 || rt >= BOARD_HEIGHT || ft < 0 || ft >= BOARD_WIDTH) break;\r
+ if (rt < 0 || rt >= BOARD_HEIGHT || ft < BOARD_LEFT || ft >= BOARD_RGHT) break;\r
if (SameColor(board[rf][ff], board[rt][ft])) break;\r
callback(board, flags, NormalMove,\r
rf, ff, rt, ft, closure);\r
if (board[rt][ft] != EmptySquare) break;\r
}\r
- if(m) goto mounted;\r
+ if(m==1) goto mounted;\r
+ if(m==2) goto finishGold;\r
+ /* Bishop falls through */\r
break;\r
\r
-#ifdef FAIRY\r
+ /* Shogi Lance is unlike anything, and asymmetric at that */\r
+ case SHOGI WhiteQueen:\r
+ for(i = 1;; i++) {\r
+ rt = rf + i;\r
+ ft = ff;\r
+ if (rt >= BOARD_HEIGHT) break;\r
+ if (SameColor(board[rf][ff], board[rt][ft])) break;\r
+ callback(board, flags, NormalMove,\r
+ rf, ff, rt, ft, closure);\r
+ if (board[rt][ft] != EmptySquare) break;\r
+ }\r
+ break;\r
+\r
+ case SHOGI BlackQueen:\r
+ for(i = 1;; i++) {\r
+ rt = rf - i;\r
+ ft = ff;\r
+ if (rt < 0) break;\r
+ if (SameColor(board[rf][ff], board[rt][ft])) break;\r
+ callback(board, flags, NormalMove,\r
+ rf, ff, rt, ft, closure);\r
+ if (board[rt][ft] != EmptySquare) break;\r
+ }\r
+ break;\r
+\r
+ /* Shogi Dragon King has to continue as Ferz after Rook moves */\r
+ case SHOGI WhiteMarshall:\r
+ case SHOGI BlackMarshall:\r
+ m++;\r
+\r
+ /* Capablanca Chancellor sets flag to continue as Knight */\r
case WhiteMarshall:\r
case BlackMarshall:\r
m++;\r
-#endif\r
+\r
+ /* Shogi Rooks are ordinary Rooks */\r
+ case SHOGI WhiteRook:\r
+ case SHOGI BlackRook:\r
case WhiteRook:\r
case BlackRook:\r
for (d = 0; d <= 1; d++)\r
for (i = 1;; i++) {\r
rt = rf + (i * s) * d;\r
ft = ff + (i * s) * (1 - d);\r
- if (rt < 0 || rt >= BOARD_HEIGHT || ft < 0 || ft >= BOARD_WIDTH) break;\r
+ if (rt < 0 || rt >= BOARD_HEIGHT || ft < BOARD_LEFT || ft >= BOARD_RGHT) break;\r
if (SameColor(board[rf][ff], board[rt][ft])) break;\r
callback(board, flags, NormalMove,\r
rf, ff, rt, ft, closure);\r
if (board[rt][ft] != EmptySquare) break;\r
}\r
- if(m) goto mounted;\r
+ if(m==1) goto mounted;\r
+ if(m==2) goto walking;\r
break;\r
\r
case WhiteQueen:\r
for (i = 1;; i++) {\r
rt = rf + (i * rs);\r
ft = ff + (i * fs);\r
- if (rt < 0 || rt >= BOARD_HEIGHT || ft < 0 || ft >= BOARD_WIDTH) break;\r
+ if (rt < 0 || rt >= BOARD_HEIGHT || ft < BOARD_LEFT || ft >= BOARD_RGHT) break;\r
if (SameColor(board[rf][ff], board[rt][ft])) break;\r
callback(board, flags, NormalMove,\r
rf, ff, rt, ft, closure);\r
}\r
break;\r
\r
-#ifdef FAIRY\r
- case WhiteFairyPawn:\r
- case BlackFairyPawn:\r
+ /* Shogi Pawn and Silver General: first the Pawn move, */\r
+ /* then the General continues like a Ferz */\r
+ case SHOGI WhitePawn:\r
+ case SHOGI WhiteFerz:\r
+ if (rf < BOARD_HEIGHT-1 &&\r
+ !SameColor(board[rf][ff], board[rf + 1][ff]) ) \r
+ callback(board, flags, NormalMove,\r
+ rf, ff, rf + 1, ff, closure);\r
+ if(piece != SHOGI WhitePawn) goto finishSilver;\r
+ break;\r
+\r
+ case SHOGI BlackPawn:\r
+ case SHOGI BlackFerz:\r
+ if (rf > 0 &&\r
+ !SameColor(board[rf][ff], board[rf - 1][ff]) ) \r
+ callback(board, flags, NormalMove,\r
+ rf, ff, rf - 1, ff, closure);\r
+ if(piece == SHOGI BlackPawn) break;\r
+\r
+ case WhiteFerz:\r
+ case BlackFerz:\r
+ finishSilver:\r
/* [HGM] support Shatranj pieces */\r
for (rs = -1; rs <= 1; rs += 2) \r
for (fs = -1; fs <= 1; fs += 2) {\r
rt = rf + rs;\r
ft = ff + fs;\r
- if (rt < 0 || rt >= BOARD_HEIGHT || ft < 0 || ft >= BOARD_WIDTH) break;\r
- if (!SameColor(board[rf][ff], board[rt][ft]))\r
+ if (rt < 0 || rt >= BOARD_HEIGHT || ft < BOARD_LEFT || ft >= BOARD_RGHT) break;\r
+ if (!SameColor(board[rf][ff], board[rt][ft]) &&\r
+ (gameInfo.variant != VariantXiangqi || InPalace(rt, ft) ) )\r
callback(board, flags, NormalMove,\r
rf, ff, rt, ft, closure);\r
}\r
break;\r
\r
- case WhiteFairyKing:\r
- case BlackFairyKing:\r
-#endif\r
+ case WhiteMan:\r
+ case BlackMan:\r
+ case SHOGI WhiteKing:\r
+ case SHOGI BlackKing:\r
case WhiteKing:\r
case BlackKing:\r
+ walking:\r
for (i = -1; i <= 1; i++)\r
for (j = -1; j <= 1; j++) {\r
if (i == 0 && j == 0) continue;\r
rt = rf + i;\r
ft = ff + j;\r
- if (rt < 0 || rt >= BOARD_HEIGHT || ft < 0 || ft >= BOARD_WIDTH) continue;\r
+ if (rt < 0 || rt >= BOARD_HEIGHT || ft < BOARD_LEFT || ft >= BOARD_RGHT) continue;\r
if (SameColor(board[rf][ff], board[rt][ft])) continue;\r
callback(board, flags, NormalMove,\r
rf, ff, rt, ft, closure);\r
if (board[rf][ff] == king) return;\r
for (r = rt-1; r <= rt+1; r++) {\r
for (f = ft-1; f <= ft+1; f++) {\r
- if (r >= 0 && r < BOARD_HEIGHT && f >= 0 && f < BOARD_WIDTH &&\r
+ if (r >= 0 && r < BOARD_HEIGHT && f >= BOARD_LEFT && f < BOARD_RGHT &&\r
board[r][f] == king) return;\r
}\r
}\r
for (ff = BOARD_WIDTH>>1; ff >= (BOARD_WIDTH-1)>>1; ff-- /*ics wild 1*/) {\r
if ((flags & F_WHITE_ON_MOVE) &&\r
(flags & F_WHITE_KCASTLE_OK) &&\r
- board[0][ff] == WhiteKing &&\r
- board[0][ff + 1] == EmptySquare &&\r
- board[0][ff + 2] == EmptySquare &&\r
- board[0][BOARD_WIDTH-3] == EmptySquare &&\r
- board[0][BOARD_WIDTH-2] == EmptySquare &&\r
- board[0][BOARD_WIDTH-1] == WhiteRook &&\r
+ board[0][ff] == WhiteKing &&\r
+ board[0][ff + 1] == EmptySquare &&\r
+ board[0][ff + 2] == EmptySquare &&\r
+ board[0][BOARD_RGHT-3] == EmptySquare &&\r
+ board[0][BOARD_RGHT-2] == EmptySquare &&\r
+ board[0][BOARD_RGHT-1] == WhiteRook &&\r
castlingRights[0] >= 0 && /* [HGM] check rights */\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_WIDTH-3, FALSE) &&\r
+ !CheckTest(board, flags, 0, ff, 0, BOARD_RGHT-3, FALSE) &&\r
!CheckTest(board, flags, 0, ff, 0, ff + 2, FALSE)))) {\r
\r
callback(board, flags,\r
- ff==4 ? WhiteKingSideCastle : WhiteKingSideCastleWild,\r
- 0, ff, 0, ff + ((BOARD_WIDTH+2)>>2), closure);\r
+ ff==BOARD_WIDTH>>1 ? WhiteKingSideCastle : WhiteKingSideCastleWild,\r
+ 0, ff, 0, ff + ((gameInfo.boardWidth+2)>>2), closure);\r
}\r
if ((flags & F_WHITE_ON_MOVE) &&\r
(flags & F_WHITE_QCASTLE_OK) &&\r
board[0][ff] == WhiteKing &&\r
board[0][ff - 1] == EmptySquare &&\r
board[0][ff - 2] == EmptySquare &&\r
- board[0][2] == EmptySquare &&\r
- board[0][1] == EmptySquare &&\r
- board[0][0] == WhiteRook &&\r
+ board[0][BOARD_LEFT+2] == EmptySquare &&\r
+ board[0][BOARD_LEFT+1] == EmptySquare &&\r
+ board[0][BOARD_LEFT+0] == WhiteRook &&\r
castlingRights[1] >= 0 && /* [HGM] check rights */\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, 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
ff==BOARD_WIDTH>>1 ? WhiteQueenSideCastle : WhiteQueenSideCastleWild,\r
- 0, ff, 0, ff - ((BOARD_WIDTH+2)>>2), closure);\r
+ 0, ff, 0, ff - ((gameInfo.boardWidth+2)>>2), closure);\r
}\r
if (!(flags & F_WHITE_ON_MOVE) &&\r
(flags & F_BLACK_KCASTLE_OK) &&\r
board[BOARD_HEIGHT-1][ff] == BlackKing &&\r
board[BOARD_HEIGHT-1][ff + 1] == EmptySquare &&\r
board[BOARD_HEIGHT-1][ff + 2] == EmptySquare &&\r
- board[BOARD_HEIGHT-1][BOARD_WIDTH-3] == EmptySquare &&\r
- board[BOARD_HEIGHT-1][BOARD_WIDTH-2] == EmptySquare &&\r
- board[BOARD_HEIGHT-1][BOARD_WIDTH-1] == BlackRook &&\r
+ board[BOARD_HEIGHT-1][BOARD_RGHT-3] == EmptySquare &&\r
+ board[BOARD_HEIGHT-1][BOARD_RGHT-2] == EmptySquare &&\r
+ board[BOARD_HEIGHT-1][BOARD_RGHT-1] == BlackRook &&\r
castlingRights[3] >= 0 && /* [HGM] check rights */\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_WIDTH-3, FALSE) &&\r
+ !CheckTest(board, flags, BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, BOARD_RGHT-3, 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 + ((BOARD_WIDTH+2)>>2), closure);\r
+ BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff + ((gameInfo.boardWidth+2)>>2), closure);\r
}\r
if (!(flags & F_WHITE_ON_MOVE) &&\r
(flags & F_BLACK_QCASTLE_OK) &&\r
board[BOARD_HEIGHT-1][ff] == BlackKing &&\r
board[BOARD_HEIGHT-1][ff - 1] == EmptySquare &&\r
board[BOARD_HEIGHT-1][ff - 2] == EmptySquare &&\r
- board[BOARD_HEIGHT-1][2] == EmptySquare &&\r
- board[BOARD_HEIGHT-1][1] == EmptySquare &&\r
- board[BOARD_HEIGHT-1][0] == BlackRook &&\r
+ board[BOARD_HEIGHT-1][BOARD_LEFT+2] == EmptySquare &&\r
+ board[BOARD_HEIGHT-1][BOARD_LEFT+1] == EmptySquare &&\r
+ board[BOARD_HEIGHT-1][BOARD_LEFT+0] == BlackRook &&\r
castlingRights[4] >= 0 && /* [HGM] check rights */\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, 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 - 1, FALSE)))) {\r
\r
callback(board, flags,\r
ff==BOARD_WIDTH>>1 ? BlackQueenSideCastle : BlackQueenSideCastleWild,\r
- BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff - ((BOARD_WIDTH+2)>>2), closure);\r
+ BOARD_HEIGHT-1, ff, BOARD_HEIGHT-1, ff - ((gameInfo.boardWidth+2)>>2), closure);\r
}\r
}\r
\r
\r
if ((flags & F_WHITE_ON_MOVE) != 0) {\r
\r
- for (ff = 1; ff < BOARD_WIDTH-1; ff++) {\r
+ for (ff = BOARD_LEFT+1; ff < BOARD_RGHT-1; ff++) {\r
if (board[0][ff] == WhiteKing) {\r
- for (ft = 0; ft < BOARD_WIDTH; ft++) {\r
+ for (ft = BOARD_LEFT+0; ft < BOARD_RGHT; ft++) {\r
if (board[0][ft] == WhiteRook) {\r
callback(board, flags, \r
(ft > ff) ? WhiteHSideCastleFR : WhiteASideCastleFR,\r
\r
} else {\r
\r
- for (ff = 1; ff < BOARD_WIDTH-1; ff++) {\r
+ for (ff = BOARD_LEFT+1; ff < BOARD_RGHT-1; ff++) {\r
if (board[BOARD_HEIGHT-1][ff] == BlackKing) {\r
- for (ft = 0; ft < BOARD_WIDTH; ft++) {\r
+ for (ft = BOARD_LEFT+0; ft < BOARD_RGHT; ft++) {\r
if (board[BOARD_HEIGHT-1][ft] == BlackRook) {\r
callback(board, flags, \r
(ft > ff) ? BlackHSideCastleFR : BlackASideCastleFR,\r
ChessSquare captured = EmptySquare;\r
/* Suppress warnings on uninitialized variables */\r
\r
+ if(gameInfo.variant == VariantXiangqi)\r
+ king = flags & F_WHITE_ON_MOVE ? WhiteWazir : BlackWazir;\r
+ if(gameInfo.variant == VariantKnightmate)\r
+ king = flags & F_WHITE_ON_MOVE ? WhiteUnicorn : BlackUnicorn;\r
+\r
if (rf >= 0) {\r
if (enPassant) {\r
captured = board[rf][ft];\r
order a1, a2, a3, ... b1, b2, ..., h8 to find the first king,\r
and we test only whether that one is in check. */\r
cl.check = 0;\r
- for (cl.fking = 0; cl.fking < BOARD_WIDTH; cl.fking++)\r
+ for (cl.fking = BOARD_LEFT+0; cl.fking < BOARD_RGHT; cl.fking++)\r
for (cl.rking = 0; cl.rking < BOARD_HEIGHT; cl.rking++) {\r
- if (board[cl.rking][cl.fking] == king) {\r
+ if (board[cl.rking][cl.fking] == king) {\r
GenPseudoLegal(board, flags ^ F_WHITE_ON_MOVE, -1,\r
CheckTestCallback, (VOIDSTAR) &cl);\r
goto undo_move; /* 2-level break */\r
{\r
register LegalityTestClosure *cl = (LegalityTestClosure *) closure;\r
\r
+ if (appData.debugMode) {\r
+ fprintf(debugFP, "Legality test: %c%c%c%c\n", ff+AAA, rf+ONE, ft+AAA, rt+ONE);\r
+ }\r
if (rf == cl->rf && ff == cl->ff && rt == cl->rt && ft == cl->ft)\r
cl->kind = kind;\r
}\r
cl.ft = ft;\r
cl.kind = IllegalMove;\r
GenLegal(board, flags, epfile, castlingRights, LegalityTestCallback, (VOIDSTAR) &cl);\r
+\r
+ if(gameInfo.variant == VariantShogi) {\r
+ /* [HGM] Shogi promotions. '=' means defer */\r
+ if(rf != DROP_RANK && cl.kind == NormalMove) {\r
+ ChessSquare piece = board[rf][ff];\r
+\r
+ if(promoChar == PieceToChar(BlackQueen)) promoChar = NULLCHAR; /* [HGM] Kludge */\r
+ if(promoChar != NULLCHAR && promoChar != 'x' &&\r
+ promoChar != '+' && promoChar != '=' &&\r
+ ToUpper(PieceToChar(PROMOTED piece)) != ToUpper(promoChar) )\r
+ cl.kind = IllegalMove;\r
+ else if(flags & F_WHITE_ON_MOVE) {\r
+ if( (int) piece < (int) WhiteWazir &&\r
+ (rf > BOARD_HEIGHT-4 || rt > BOARD_HEIGHT-4) ) {\r
+ if( (piece == WhitePawn || piece == WhiteQueen) && rt > BOARD_HEIGHT-2 ||\r
+ piece == WhiteKnight && rt > BOARD_HEIGHT-3) /* promotion mandatory */\r
+ cl.kind = promoChar == '=' ? IllegalMove : WhitePromotionKnight;\r
+ else /* promotion optional, default is promote */\r
+ cl.kind = promoChar == '=' ? NormalMove : WhitePromotionQueen;\r
+ \r
+ } else cl.kind = (promoChar == NULLCHAR || promoChar == 'x' || promoChar == '=') ?\r
+ NormalMove : IllegalMove;\r
+ } else {\r
+ if( (int) piece < (int) BlackWazir && (rf < 3 || rt < 3) ) {\r
+ if( (piece == BlackPawn || piece == BlackQueen) && rt < 1 ||\r
+ piece == BlackKnight && rt < 2 ) /* promotion obligatory */\r
+ cl.kind = promoChar == '=' ? IllegalMove : BlackPromotionKnight;\r
+ else /* promotion optional, default is promote */\r
+ cl.kind = promoChar == '=' ? NormalMove : BlackPromotionQueen;\r
+\r
+ } else cl.kind = (promoChar == NULLCHAR || promoChar == 'x' || promoChar == '=') ?\r
+ NormalMove : IllegalMove;\r
+ }\r
+ }\r
+ } else\r
if (promoChar != NULLCHAR && promoChar != 'x') {\r
if (cl.kind == WhitePromotionQueen || cl.kind == BlackPromotionQueen) {\r
cl.kind = \r
cl.kind = IllegalMove;\r
}\r
}\r
+ /* [HGM] For promotions, 'ToQueen' = optional, 'ToKnight' = mandatory */\r
return cl.kind;\r
}\r
\r
if (cl.count > 0) {\r
return inCheck ? MT_CHECK : MT_NONE;\r
} else {\r
- return inCheck ? MT_CHECKMATE : MT_STALEMATE;\r
+ return inCheck || gameInfo.variant == VariantXiangqi ?\r
+ MT_CHECKMATE : MT_STALEMATE;\r
}\r
}\r
\r
(cl->ftIn == -1 || cl->ftIn == ft)) {\r
\r
cl->count++;\r
- cl->piece = board[rf][ff];\r
+ cl->piece = board[rf][ff];\r
cl->rf = rf;\r
cl->ff = ff;\r
cl->rt = rt;\r
int flags, epfile;\r
DisambiguateClosure *closure;\r
{\r
- int illegal = 0;\r
+ int illegal = 0; char c = closure->promoCharIn;\r
closure->count = 0;\r
closure->rf = closure->ff = closure->rt = closure->ft = 0;\r
closure->kind = ImpossibleMove;\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,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
+ ChessSquare piece = closure->piece;\r
+\r
+ if (appData.debugMode) {\r
+ fprintf(debugFP, "Disambiguate A: %d(%d,%d)-(%d,%d) = %d (%c)\n",\r
+ closure->pieceIn,closure->ffIn,closure->rfIn,closure->ftIn,closure->rtIn,closure->promoCharIn,closure->promoCharIn);\r
+ }\r
+ if(c != NULLCHAR && c != 'x' && c != '+' && c != '=' &&\r
+ ToUpper(PieceToChar(PROMOTED piece)) != ToUpper(c) ) \r
+ closure->kind = IllegalMove;\r
+ else if(flags & F_WHITE_ON_MOVE) {\r
+ if (appData.debugMode) {\r
+ fprintf(debugFP, "Disambiguate B: %d(%d,%d)-(%d,%d) = %d (%c)\n",\r
+ closure->pieceIn,closure->ffIn,closure->rfIn,closure->ftIn,closure->rtIn,closure->promoCharIn,closure->promoCharIn);\r
+ }\r
+ if( (int) piece < (int) WhiteWazir &&\r
+ (closure->rf > BOARD_HEIGHT-4 || closure->rt > BOARD_HEIGHT-4) ) {\r
+ if( (piece == WhitePawn || piece == WhiteQueen) && closure->rt > BOARD_HEIGHT-2 ||\r
+ piece == WhiteKnight && closure->rt > BOARD_HEIGHT-3) /* promotion mandatory */\r
+ closure->kind = c == '=' ? IllegalMove : WhitePromotionKnight;\r
+ else /* promotion optional, default is promote */\r
+ closure->kind = c == '=' ? NormalMove : WhitePromotionQueen;\r
+ \r
+ } else closure->kind = (c == NULLCHAR || c == 'x' || c == '=') ?\r
+ NormalMove : IllegalMove;\r
+ } else {\r
+ if( (int) piece < (int) BlackWazir && (closure->rf < 3 || closure->rt < 3) ) {\r
+ if( (piece == BlackPawn || piece == BlackQueen) && closure->rt < 1 ||\r
+ piece == BlackKnight && closure->rt < 2 ) /* promotion obligatory */\r
+ closure->kind = c == '=' ? IllegalMove : BlackPromotionKnight;\r
+ else /* promotion optional, default is promote */\r
+ closure->kind = c == '=' ? NormalMove : BlackPromotionQueen;\r
+\r
+ } else closure->kind = (c == NULLCHAR || c == 'x' || c == '=') ?\r
+ NormalMove : IllegalMove;\r
+ }\r
+ }\r
+ } else\r
if (closure->promoCharIn != NULLCHAR && closure->promoCharIn != 'x') {\r
if (closure->kind == WhitePromotionQueen\r
|| closure->kind == BlackPromotionQueen) {\r
closure->kind = IllegalMove;\r
}\r
}\r
- closure->promoChar = ToLower(PieceToChar(PromoPiece(closure->kind)));\r
+ if (appData.debugMode) {\r
+ fprintf(debugFP, "Disambiguate C: %d(%d,%d)-(%d,%d) = %d (%c)\n",\r
+ closure->pieceIn,closure->ffIn,closure->rfIn,closure->ftIn,closure->rtIn,closure->promoCharIn,closure->promoCharIn);\r
+ }\r
+ /* [HGM] returns 'q' for optional promotion, 'n' for mandatory */\r
+ if(closure->promoCharIn != '=')\r
+ closure->promoChar = ToLower(PieceToChar(PromoPiece(closure->kind)));\r
+ else closure->promoChar = '=';\r
if (closure->promoChar == 'x') closure->promoChar = NULLCHAR;\r
if (closure->count > 1) {\r
closure->kind = AmbiguousMove;\r
*/\r
closure->kind = IllegalMove;\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
+ 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
+ }\r
}\r
\r
\r
/* Bughouse piece drop */\r
*outp++ = ToUpper(PieceToChar((ChessSquare) ff));\r
*outp++ = '@';\r
- *outp++ = ft + 'a';\r
+ *outp++ = ft + AAA;\r
if(rt+ONE <= '9')\r
*outp++ = rt + ONE;\r
else { *outp++ = (rt+ONE-'0')/10 + '0';*outp++ = (rt+ONE-'0')%10 + '0'; }\r
*outp = NULLCHAR;\r
+ AlphaRank(out, 5);\r
return (flags & F_WHITE_ON_MOVE) ? WhiteDrop : BlackDrop;\r
}\r
\r
if (promoChar == 'x') promoChar = NULLCHAR;\r
piece = board[rf][ff];\r
+\r
+ if (appData.debugMode)\r
+ fprintf(debugFP, "CoordsToAlgebraic, piece=%d\n", (int)piece);\r
switch (piece) {\r
case WhitePawn:\r
case BlackPawn:\r
+ if (appData.debugMode)\r
+ fprintf(debugFP, "CoordsToAlgebraic, Pawn\n");\r
kind = LegalityTest(board, flags, epfile, initialRights, rf, ff, rt, ft, promoChar);\r
if (kind == IllegalMove && !(flags&F_IGNORE_CHECK)) {\r
/* Keep short notation if move is illegal only because it\r
kind = IllegalMove;\r
}\r
/* Pawn move */\r
- *outp++ = ff + 'a';\r
+ *outp++ = ff + AAA;\r
if (ff == ft && board[rt][ft] == EmptySquare) { /* [HGM] Xiangqi has straight noncapts! */\r
/* Non-capture; use style "e5" */\r
if(rt+ONE <= '9')\r
/* Capture; use style "exd5" */\r
if(gameInfo.variant != VariantXiangqi || board[rt][ft] != EmptySquare )\r
*outp++ = 'x'; /* [HGM] Xiangqi has sideway noncaptures across river! */\r
- *outp++ = ft + 'a';\r
+ *outp++ = ft + AAA;\r
if(rt+ONE <= '9')\r
*outp++ = rt + ONE;\r
else { *outp++ = (rt+ONE-'0')/10 + '0';*outp++ = (rt+ONE-'0')%10 + '0'; }\r
}\r
/* Use promotion suffix style "=Q" */\r
- if (promoChar != NULLCHAR && promoChar != 'x') {\r
- *outp++ = '=';\r
- *outp++ = ToUpper(promoChar);\r
- }\r
*outp = NULLCHAR;\r
- return kind;\r
+ if (promoChar != NULLCHAR) {\r
+ if(gameInfo.variant == VariantShogi) {\r
+ /* [HGM] ... but not in Shogi! */\r
+ *outp++ = promoChar == '=' ? '=' : '+';\r
+ } else {\r
+ *outp++ = '=';\r
+ *outp++ = ToUpper(promoChar);\r
+ }\r
+ *outp = NULLCHAR;\r
+ }\r
+ AlphaRank(out, 10);\r
+ return kind;\r
\r
\r
case WhiteKing:\r
/* Use style "O-O" (oh-oh) for PGN compatibility */\r
else if (rf == rt &&\r
rf == ((piece == WhiteKing) ? 0 : BOARD_HEIGHT-1) &&\r
- ((ff == BOARD_WIDTH>>1 && (ft == 2 || ft == BOARD_WIDTH-2)) ||\r
- (ff == (BOARD_WIDTH-1)>>1 && (ft == 1 || ft == BOARD_WIDTH-3)))) {\r
- if(ft==1 || ft==BOARD_WIDTH-2)\r
+ ((ff == BOARD_WIDTH>>1 && (ft == BOARD_LEFT+2 || ft == BOARD_RGHT-2)) ||\r
+ (ff == (BOARD_WIDTH-1)>>1 && (ft == BOARD_LEFT+1 || ft == BOARD_RGHT-3)))) {\r
+ if(ft==BOARD_LEFT+1 || ft==BOARD_RGHT-2)\r
strcpy(out, "O-O");\r
else\r
strcpy(out, "O-O-O");\r
else "N1f3" or "N5xf7",\r
else "Ng1f3" or "Ng5xf7".\r
*/\r
- *outp++ = ToUpper(PieceToChar(piece));\r
- \r
+ if(PieceToChar(piece) == '.') {\r
+ /* [HGM] print nonexistent piece as its demoted version */\r
+ piece = (ChessSquare) (DEMOTED piece);\r
+ if( gameInfo.variant == VariantShogi )\r
+ *outp++ = '+';\r
+ }\r
+ *outp++ = ToUpper(PieceToChar(piece));\r
if (cl.file || (cl.either && !cl.rank)) {\r
- *outp++ = ff + 'a';\r
+ *outp++ = ff + AAA;\r
}\r
if (cl.rank) {\r
if(rf+ONE <= '9')\r
if(board[rt][ft] != EmptySquare)\r
*outp++ = 'x';\r
\r
- *outp++ = ft + 'a';\r
+ *outp++ = ft + AAA;\r
if(rt+ONE <= '9')\r
*outp++ = rt + ONE;\r
else { *outp++ = (rt+ONE-'0')/10 + '0';*outp++ = (rt+ONE-'0')%10 + '0'; }\r
*outp = NULLCHAR;\r
- return cl.kind;\r
+ if (gameInfo.variant == VariantShogi) {\r
+ /* [HGM] in Shogi non-pawns can promote */\r
+ if(flags & F_WHITE_ON_MOVE) {\r
+ if( (int) cl.piece < (int) WhiteWazir &&\r
+ (rf > BOARD_HEIGHT-4 || rt > BOARD_HEIGHT-4) ) {\r
+ if( (piece == WhitePawn || piece == WhiteQueen) && rt > BOARD_HEIGHT-2 ||\r
+ piece == WhiteKnight && rt > BOARD_HEIGHT-3) /* promotion mandatory */\r
+ cl.kind = promoChar == '=' ? IllegalMove : WhitePromotionKnight;\r
+ else cl.kind = WhitePromotionQueen; /* promotion optional */\r
+ \r
+ } else cl.kind = (promoChar == NULLCHAR || promoChar == 'x' || promoChar == '=') ?\r
+ NormalMove : IllegalMove;\r
+ } else {\r
+ if( (int) cl.piece < (int) BlackWazir && (rf < 3 || rt < 3) ) {\r
+ if( (piece == BlackPawn || piece == BlackQueen) && rt < 1 ||\r
+ piece == BlackKnight && rt < 2 ) /* promotion obligatory */\r
+ cl.kind = promoChar == '=' ? IllegalMove : BlackPromotionKnight;\r
+ else cl.kind = BlackPromotionQueen; /* promotion optional */\r
+ } else cl.kind = (promoChar == NULLCHAR || promoChar == 'x' || promoChar == '=') ?\r
+ NormalMove : IllegalMove;\r
+ }\r
+ if(cl.kind == WhitePromotionQueen || cl.kind == BlackPromotionQueen) {\r
+ /* for optional promotions append '+' or '=' */\r
+ if(promoChar == '=') {\r
+ *outp++ = '=';\r
+ cl.kind = NormalMove;\r
+ } else *outp++ = '+';\r
+ *outp = NULLCHAR;\r
+ } else if(cl.kind == IllegalMove) {\r
+ /* Illegal move specifies any given promotion */\r
+ if(promoChar != NULLCHAR && promoChar != 'x') {\r
+ *outp++ = '=';\r
+ *outp++ = ToUpper(promoChar);\r
+ *outp = NULLCHAR;\r
+ }\r
+ }\r
+ }\r
+ AlphaRank(out, 10);\r
+ return cl.kind;\r
\r
-#ifdef FAIRY\r
- /* [HGM] Always long notation for fairies, don't know how they move */\r
- case WhiteFairyRook:\r
- case BlackFairyRook:\r
- case WhiteFairyKnight:\r
- case BlackFairyKnight:\r
- case WhiteFairyQueen:\r
- case BlackFairyQueen:\r
-#endif\r
+ /* [HGM] Always long notation for fairies we don't know */\r
+ case WhiteNightrider:\r
+ case BlackNightrider:\r
+ case WhiteGrasshopper:\r
+ case BlackGrasshopper:\r
case EmptySquare:\r
/* Moving a nonexistent piece */\r
break;\r
if (piece != EmptySquare && piece != WhitePawn && piece != BlackPawn) {\r
*outp++ = ToUpper(PieceToChar(piece));\r
}\r
- *outp++ = ff + 'a';\r
+ *outp++ = ff + AAA;\r
if(rf+ONE <= '9')\r
*outp++ = rf + ONE;\r
else { *outp++ = (rf+ONE-'0')/10 + '0';*outp++ = (rf+ONE-'0')%10 + '0'; }\r
if (board[rt][ft] != EmptySquare) *outp++ = 'x';\r
- *outp++ = ft + 'a';\r
+ *outp++ = ft + AAA;\r
if(rt+ONE <= '9')\r
*outp++ = rt + ONE;\r
else { *outp++ = (rt+ONE-'0')/10 + '0';*outp++ = (rt+ONE-'0')%10 + '0'; }\r
}\r
*outp = NULLCHAR;\r
\r
+ AlphaRank(out, 0);\r
return IllegalMove;\r
}\r
\r