X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=moves.c;h=56bd1dae717d34075aaa6b11032c115554397242;hb=88082a3882690efd9ea7d3e01ad9d6dd5f5baf86;hp=2e8d672ec6ff2af9cbdabeadc818cb16f19e1b46;hpb=ccc569b6febbb39ba6e7979f0068c04653456059;p=xboard.git diff --git a/moves.c b/moves.c index 2e8d672..56bd1da 100644 --- a/moves.c +++ b/moves.c @@ -97,47 +97,6 @@ int SameColor(piece1, piece2) (int) piece2 < (int) EmptySquare); } -ChessSquare PromoPiece(moveType) - ChessMove moveType; -{ - switch (moveType) { - default: - return EmptySquare; - case WhitePromotionQueen: - return WhiteQueen; - case BlackPromotionQueen: - return BlackQueen; - case WhitePromotionRook: - return WhiteRook; - case BlackPromotionRook: - return BlackRook; - case WhitePromotionBishop: - return WhiteBishop; - case BlackPromotionBishop: - return BlackBishop; - case WhitePromotionKnight: - return WhiteKnight; - case BlackPromotionKnight: - return BlackKnight; - case WhitePromotionKing: - return WhiteKing; - case BlackPromotionKing: - return BlackKing; - case WhitePromotionChancellor: - return WhiteMarshall; - case BlackPromotionChancellor: - return BlackMarshall; - case WhitePromotionArchbishop: - return WhiteAngel; - case BlackPromotionArchbishop: - return BlackAngel; - case WhitePromotionCentaur: - return WhiteSilver; - case BlackPromotionCentaur: - return BlackSilver; - } -} - char pieceToChar[] = { 'P', 'N', 'B', 'R', 'Q', 'F', 'E', 'A', 'C', 'W', 'M', 'O', 'H', 'I', 'J', 'G', 'D', 'V', 'L', 'S', 'U', 'K', @@ -174,54 +133,6 @@ ChessSquare CharToPiece(c) return EmptySquare; } -ChessMove PromoCharToMoveType(whiteOnMove, promoChar) - int whiteOnMove; - int promoChar; -{ /* [HGM] made dependent on CharToPiece to alow alternate piece letters */ - ChessSquare piece = CharToPiece(whiteOnMove ? ToUpper(promoChar) : ToLower(promoChar) ); - - if(promoChar == '=') return whiteOnMove ? WhiteNonPromotion : BlackNonPromotion; - if(promoChar == NULLCHAR) return NormalMove; - - switch(piece) { - case WhiteQueen: - return WhitePromotionQueen; - case WhiteRook: - return WhitePromotionRook; - case WhiteBishop: - return WhitePromotionBishop; - case WhiteKnight: - return WhitePromotionKnight; - case WhiteKing: - return WhitePromotionKing; - case WhiteAngel: - return WhitePromotionArchbishop; - case WhiteMarshall: - return WhitePromotionChancellor; - case WhiteSilver: - return WhitePromotionCentaur; - case BlackQueen: - return BlackPromotionQueen; - case BlackRook: - return BlackPromotionRook; - case BlackBishop: - return BlackPromotionBishop; - case BlackKnight: - return BlackPromotionKnight; - case BlackKing: - return BlackPromotionKing; - case BlackAngel: - return BlackPromotionArchbishop; - case BlackMarshall: - return BlackPromotionChancellor; - case BlackSilver: - return BlackPromotionCentaur; - default: - // not all promotion implemented yet! Take Queen for those we don't know. - return (whiteOnMove ? WhitePromotionQueen : BlackPromotionQueen); - } -} - void CopyBoard(to, from) Board to, from; { @@ -310,7 +221,7 @@ void GenPseudoLegal(board, flags, callback, closure) } if (rf < BOARD_HEIGHT-1 && board[rf + 1][ff] == EmptySquare) { callback(board, flags, - rf >= BOARD_HEIGHT-1-promoRank ? WhitePromotionQueen : NormalMove, + rf >= BOARD_HEIGHT-1-promoRank ? WhitePromotion : NormalMove, rf, ff, rf + 1, ff, closure); } if (rf == 1 && board[2][ff] == EmptySquare && @@ -325,7 +236,7 @@ void GenPseudoLegal(board, flags, callback, closure) ((flags & F_KRIEGSPIEL_CAPTURE) || BlackPiece(board[rf + 1][ff + s]))) { callback(board, flags, - rf >= BOARD_HEIGHT-1-promoRank ? WhitePromotionQueen : NormalMove, + rf >= BOARD_HEIGHT-1-promoRank ? WhitePromotion : NormalMove, rf, ff, rf + 1, ff + s, closure); } if (rf == BOARD_HEIGHT-4) { @@ -360,7 +271,7 @@ void GenPseudoLegal(board, flags, callback, closure) } if (rf > 0 && board[rf - 1][ff] == EmptySquare) { callback(board, flags, - rf <= promoRank ? BlackPromotionQueen : NormalMove, + rf <= promoRank ? BlackPromotion : NormalMove, rf, ff, rf - 1, ff, closure); } if (rf == BOARD_HEIGHT-2 && board[BOARD_HEIGHT-3][ff] == EmptySquare && @@ -375,7 +286,7 @@ void GenPseudoLegal(board, flags, callback, closure) ((flags & F_KRIEGSPIEL_CAPTURE) || WhitePiece(board[rf - 1][ff + s]))) { callback(board, flags, - rf <= promoRank ? BlackPromotionQueen : NormalMove, + rf <= promoRank ? BlackPromotion : NormalMove, rf, ff, rf - 1, ff + s, closure); } if (rf == 3) { @@ -1116,24 +1027,24 @@ ChessMove LegalityTest(board, flags, rf, ff, rt, ft, promoChar) && cl.kind != WhiteCapturesEnPassant && cl.kind != BlackCapturesEnPassant) return(IllegalMove); // [HGM] losers: if there are legal captures, non-capts are illegal + if(promoChar == 'x') promoChar = NULLCHAR; // [HGM] is this ever the case? if(gameInfo.variant == VariantShogi) { /* [HGM] Shogi promotions. '=' means defer */ if(rf != DROP_RANK && cl.kind == NormalMove) { ChessSquare piece = board[rf][ff]; if(promoChar == PieceToChar(BlackQueen)) promoChar = NULLCHAR; /* [HGM] Kludge */ - if(promoChar != NULLCHAR && promoChar != 'x' && - promoChar != '+' && promoChar != '=' && + if(promoChar != NULLCHAR && promoChar != '+' && promoChar != '=' && ToUpper(PieceToChar(PROMOTED piece)) != ToUpper(promoChar) ) cl.kind = IllegalMove; else if(flags & F_WHITE_ON_MOVE) { if( (int) piece < (int) WhiteWazir && - (rf >= BOARD_HEIGHT-(BOARD_HEIGHT/3) || rt >= BOARD_HEIGHT-(BOARD_HEIGHT/3)) ) { + (rf >= BOARD_HEIGHT*2/3 || rt >= BOARD_HEIGHT*2/3) ) { if( (piece == WhitePawn || piece == WhiteQueen) && rt > BOARD_HEIGHT-2 || piece == WhiteKnight && rt > BOARD_HEIGHT-3) /* promotion mandatory */ - cl.kind = promoChar == '=' ? IllegalMove : WhitePromotionKnight; + cl.kind = promoChar == '=' ? IllegalMove : WhitePromotion; else /* promotion optional, default is promote */ - cl.kind = promoChar == '=' ? WhiteNonPromotion : WhitePromotionQueen; + cl.kind = promoChar == '=' ? WhiteNonPromotion : WhitePromotion; } else cl.kind = (promoChar == NULLCHAR || promoChar == 'x' || promoChar == '=') ? NormalMove : IllegalMove; @@ -1141,25 +1052,22 @@ ChessMove LegalityTest(board, flags, rf, ff, rt, ft, promoChar) 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 : BlackPromotionKnight; + cl.kind = promoChar == '=' ? IllegalMove : BlackPromotion; else /* promotion optional, default is promote */ - cl.kind = promoChar == '=' ? BlackNonPromotion : BlackPromotionQueen; + cl.kind = promoChar == '=' ? BlackNonPromotion : BlackPromotion; - } else cl.kind = (promoChar == NULLCHAR || promoChar == 'x' || promoChar == '=') ? - NormalMove : IllegalMove; + } else cl.kind = (promoChar == NULLCHAR || promoChar == '=') ? NormalMove : IllegalMove; } } } else - if (promoChar != NULLCHAR && promoChar != 'x') { + if (promoChar != NULLCHAR) { if(promoChar == '=') cl.kind = IllegalMove; else // [HGM] shogi: no deferred promotion outside Shogi - if (cl.kind == WhitePromotionQueen || cl.kind == BlackPromotionQueen) { - cl.kind = - PromoCharToMoveType((flags & F_WHITE_ON_MOVE) != 0, promoChar); + if (cl.kind == WhitePromotion || cl.kind == BlackPromotion) { + if(CharToPiece(promoChar) == EmptySquare) cl.kind = ImpossibleMove; // non-existing piece } else { cl.kind = IllegalMove; } } - /* [HGM] For promotions, 'ToQueen' = optional, 'ToKnight' = mandatory */ return cl.kind; } @@ -1317,52 +1225,41 @@ void Disambiguate(board, flags, closure) } } + if (c == 'x') c = NULLCHAR; // get rid of any 'x' (which should never happen?) if(gameInfo.variant == VariantShogi) { - /* [HGM] Shogi promotions. '=' means defer */ + /* [HGM] Shogi promotions. On input, '=' means defer, NULL promote. Afterwards, c is set to '+' for promotions, NULL other */ if(closure->rfIn != DROP_RANK && closure->kind == NormalMove) { ChessSquare piece = closure->piece; - if(c != NULLCHAR && c != 'x' && c != '+' && c != '=' && + if(c != NULLCHAR && c != '+' && c != '=' && ToUpper(PieceToChar(PROMOTED piece)) != ToUpper(c) ) - closure->kind = IllegalMove; + closure->kind = IllegalMove; // the only allowed cases are '+', '=' and the promoted partner. 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)) ) { if( (piece == WhitePawn || piece == WhiteQueen) && closure->rt > BOARD_HEIGHT-2 || piece == WhiteKnight && closure->rt > BOARD_HEIGHT-3) /* promotion mandatory */ - closure->kind = c == '=' ? IllegalMove : WhitePromotionKnight; + closure->kind = c == '=' ? IllegalMove : WhitePromotion; else /* promotion optional, default is promote */ - closure->kind = c == '=' ? NormalMove : WhitePromotionQueen; - if(c != '=') closure->promoCharIn = 'q'; - } else closure->kind = (c == NULLCHAR || c == 'x' || c == '=') ? - NormalMove : IllegalMove; + closure->kind = c == '=' ? WhiteNonPromotion : WhitePromotion; + } else closure->kind = (c == NULLCHAR || c == '=') ? NormalMove : IllegalMove; } 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 : BlackPromotionKnight; + closure->kind = c == '=' ? IllegalMove : BlackPromotion; else /* promotion optional, default is promote */ - closure->kind = c == '=' ? NormalMove : BlackPromotionQueen; - if(c != '=') closure->promoCharIn = 'q'; - } else closure->kind = (c == NULLCHAR || c == 'x' || c == '=') ? - NormalMove : IllegalMove; + closure->kind = c == '=' ? BlackNonPromotion : BlackPromotion; + } else closure->kind = (c == NULLCHAR || c == '=') ? NormalMove : IllegalMove; } } + c = (closure->kind == WhitePromotion || closure->kind == BlackPromotion) ? '+' : NULLCHAR; } else - if (closure->promoCharIn != NULLCHAR && closure->promoCharIn != 'x') { - if (closure->kind == WhitePromotionQueen - || closure->kind == BlackPromotionQueen) { - closure->kind = - PromoCharToMoveType((flags & F_WHITE_ON_MOVE) != 0, - closure->promoCharIn); - } else { - closure->kind = IllegalMove; - } - } - /* [HGM] returns 'q' for optional promotion, 'n' for mandatory */ - if(closure->promoCharIn != '=') - closure->promoChar = ToLower(closure->promoCharIn); - else closure->promoChar = '='; - if (closure->promoChar == 'x') closure->promoChar = NULLCHAR; + if (closure->kind == WhitePromotion || closure->kind == BlackPromotion) { + if(c == NULLCHAR) c = 'q'; // even in Shatranj, Courier, Makruk, as Apply move corrects this to Ferz (how messy!) + } 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 != NULLCHAR && CharToPiece(c) == EmptySquare) closure->kind = ImpossibleMove; // but we cannot handle non-existing piece types! if (closure->count > 1) { closure->kind = AmbiguousMove; } @@ -1373,9 +1270,6 @@ void Disambiguate(board, flags, closure) */ closure->kind = IllegalMove; } - if(closure->kind == IllegalMove) - /* [HGM] might be a variant we don't understand, pass on promotion info */ - closure->promoChar = ToLower(closure->promoCharIn); if (appData.debugMode) { fprintf(debugFP, "Disambiguate out: %d(%d,%d)-(%d,%d) = %d (%c)\n", closure->piece,closure->ff,closure->rf,closure->ft,closure->rt,closure->promoChar, @@ -1598,8 +1492,8 @@ ChessMove CoordsToAlgebraic(board, flags, rf, ff, rt, ft, promoChar, out) (rf >= BOARD_HEIGHT-(BOARD_HEIGHT/3) || rt >= BOARD_HEIGHT-(BOARD_HEIGHT/3)) ) { if( (piece == WhitePawn || piece == WhiteQueen) && rt > BOARD_HEIGHT-2 || piece == WhiteKnight && rt > BOARD_HEIGHT-3) /* promotion mandatory */ - cl.kind = promoChar == '=' ? IllegalMove : WhitePromotionKnight; - else cl.kind = WhitePromotionQueen; /* promotion optional */ + cl.kind = promoChar == '=' ? IllegalMove : WhitePromotion; + else cl.kind = WhitePromotion; /* promotion optional */ } else cl.kind = (promoChar == NULLCHAR || promoChar == 'x' || promoChar == '=') ? NormalMove : IllegalMove; @@ -1607,12 +1501,12 @@ ChessMove CoordsToAlgebraic(board, flags, rf, ff, rt, ft, promoChar, out) if( (int) cl.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 : BlackPromotionKnight; - else cl.kind = BlackPromotionQueen; /* promotion optional */ + cl.kind = promoChar == '=' ? IllegalMove : BlackPromotion; + else cl.kind = BlackPromotion; /* promotion optional */ } else cl.kind = (promoChar == NULLCHAR || promoChar == 'x' || promoChar == '=') ? NormalMove : IllegalMove; } - if(cl.kind == WhitePromotionQueen || cl.kind == BlackPromotionQueen) { + if(cl.kind == WhitePromotion || cl.kind == BlackPromotion) { /* for optional promotions append '+' or '=' */ if(promoChar == '=') { *outp++ = '=';