X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=moves.c;h=8ca57beaa3b1305f618a206a0c87d07b6865510b;hb=0a1090546ff3f7af136e33eb4fd636b1e5d5178b;hp=970393f3299c8901f85b04ac76151acbb3373af8;hpb=f8ab6dcab6427bb25a1bd4b9bde024e34c6f57bf;p=xboard.git diff --git a/moves.c b/moves.c index 970393f..8ca57be 100644 --- a/moves.c +++ b/moves.c @@ -1,11 +1,13 @@ /* * moves.c - Move generation and checking - * $Id: moves.c,v 2.1 2003/10/27 19:21:00 mann Exp $ * * Copyright 1991 by Digital Equipment Corporation, Maynard, - * Massachusetts. Enhancements Copyright - * 1992-2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software - * Foundation, Inc. + * Massachusetts. + * + * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, + * 2007, 2008, 2009 Free Software Foundation, Inc. + * + * Enhancements Copyright 2005 Alessandro Scotti * * The following terms apply to Digital Equipment Corporation's copyright * interest in XBoard: @@ -67,7 +69,7 @@ int BlackPiece P((ChessSquare)); int SameColor P((ChessSquare, ChessSquare)); int PosFlags(int index); -extern char initialRights[BOARD_SIZE]; /* [HGM] all rights enabled, set in InitPosition */ +extern signed char initialRights[BOARD_SIZE]; /* [HGM] all rights enabled, set in InitPosition */ int WhitePiece(piece) @@ -138,7 +140,7 @@ ChessSquare PromoPiece(moveType) char pieceToChar[] = { 'P', 'N', 'B', 'R', 'Q', 'F', 'E', 'A', 'C', 'W', 'M', - 'O', 'H', 'I', 'J', 'G', 'D', 'V', 'L', 's', 'U', 'K', + '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' }; @@ -584,7 +586,7 @@ void GenPseudoLegal(board, flags, epfile, callback, closure) if (board[rt][ft] != EmptySquare) break; } if(m==1) goto mounted; - if(m==2) goto finishGold; + if(m==2) goto finishSilver; break; case WhiteQueen: @@ -678,6 +680,14 @@ void GenPseudoLegal(board, flags, epfile, callback, closure) } } break; + case WhiteFalcon: // [HGM] wild: for wildcards, self-capture symbolizes move to anywhere + case BlackFalcon: + case WhiteCobra: + case BlackCobra: + case WhiteLance: + case BlackLance: + callback(board, flags, NormalMove, rf, ff, rf, ff, closure); + break; } } @@ -853,10 +863,6 @@ int GenLegal(board, flags, epfile, castlingRights, callback, closure) if ((flags & F_WHITE_ON_MOVE) != 0) { ff = castlingRights[2]; /* King file if we have any rights */ if(ff > 0 && board[0][ff] == WhiteKing) { - if (appData.debugMode) { - fprintf(debugFP, "FRC castling, %d %d %d %d %d %d\n", - castlingRights[0],castlingRights[1],ff,castlingRights[3],castlingRights[4],castlingRights[5]); - } ft = castlingRights[0]; /* Rook file if we have H-side rights */ left = ff+1; right = BOARD_RGHT-2; @@ -1007,7 +1013,7 @@ int CheckTest(board, flags, rf, ff, rt, ft, enPassant) } } - return cl.check; + return cl.fking < BOARD_RGHT ? cl.check : 1000; // [HGM] atomic: return 1000 if we have no king } @@ -1024,9 +1030,6 @@ void LegalityTestCallback(board, flags, kind, rf, ff, rt, ft, closure) { register LegalityTestClosure *cl = (LegalityTestClosure *) closure; -// if (appData.debugMode) { -// fprintf(debugFP, "Legality test: %c%c%c%c\n", ff+AAA, rf+ONE, ft+AAA, rt+ONE); -// } if(board[rt][ft] != EmptySquare || kind==WhiteCapturesEnPassant || kind==BlackCapturesEnPassant) cl->captures++; // [HGM] losers: count legal captures if (rf == cl->rf && ff == cl->ff && rt == cl->rt && ft == cl->ft) @@ -1041,17 +1044,12 @@ ChessMove LegalityTest(board, flags, epfile, castlingRights, rf, ff, rt, ft, pro { LegalityTestClosure cl; ChessSquare piece = board[rf][ff]; - if (appData.debugMode) { - int i; - for(i=0; i<6; i++) fprintf(debugFP, "%d ", castlingRights[i]); - fprintf(debugFP, "Legality test? %c%c%c%c\n", ff+AAA, rf+ONE, ft+AAA, rt+ONE); - } /* [HGM] Lance, Cobra and Falcon are wildcard pieces; consider all their moves legal */ /* (perhaps we should disallow moves that obviously leave us in check?) */ if(piece == WhiteFalcon || piece == BlackFalcon || piece == WhiteCobra || piece == BlackCobra || piece == WhiteLance || piece == BlackLance) - return NormalMove; + return CheckTest(board, flags, rf, ff, rt, ft, FALSE) ? IllegalMove : NormalMove; cl.rf = rf; cl.ff = ff; @@ -1138,13 +1136,42 @@ int MateTest(board, flags, epfile, castlingRights) char castlingRights[]; { MateTestClosure cl; - int inCheck; + int inCheck, r, f, myPieces=0, hisPieces=0, nrKing=0; + ChessSquare king = flags & F_WHITE_ON_MOVE ? WhiteKing : BlackKing; + + for(r=0; r= (int)king - (int)WhiteKing + (int)WhitePawn) + myPieces++; + else hisPieces++; + } + } + switch(gameInfo.variant) { // [HGM] losers: extinction wins + case VariantShatranj: + if(hisPieces == 1) return myPieces > 1 ? MT_BARE : MT_DRAW; + default: + break; + case VariantAtomic: + if(nrKing == 0) return MT_NOKING; + break; + case VariantLosers: + if(myPieces == 1) return MT_BARE; + } cl.count = 0; inCheck = GenLegal(board, flags, epfile, castlingRights, MateTestCallback, (VOIDSTAR) &cl); + // [HGM] 3check: yet to do! if (cl.count > 0) { return inCheck ? MT_CHECK : MT_NONE; } else { + if(gameInfo.variant == VariantSuicide) // [HGM] losers: always stalemate, since no check, but result varies + return myPieces == hisPieces ? MT_STALEMATE : + myPieces > hisPieces ? MT_STAINMATE : MT_STEALMATE; + else if(gameInfo.variant == VariantLosers) return inCheck ? MT_TRICKMATE : MT_STEALMATE; + else if(gameInfo.variant == VariantGiveaway) return MT_STEALMATE; // no check exists, stalemated = win + return inCheck ? MT_CHECKMATE : (gameInfo.variant == VariantXiangqi || gameInfo.variant == VariantShatranj) ? MT_STAINMATE : MT_STALEMATE; @@ -1164,6 +1191,13 @@ void DisambiguateCallback(board, flags, kind, rf, ff, rt, ft, closure) VOIDSTAR closure; { register DisambiguateClosure *cl = (DisambiguateClosure *) closure; + int wildCard = FALSE; ChessSquare piece = board[rf][ff]; + + // [HGM] wild: for wild-card pieces rt and rf are dummies + if(piece == WhiteFalcon || piece == BlackFalcon || + piece == WhiteCobra || piece == BlackCobra || + piece == WhiteLance || piece == BlackLance) + wildCard = TRUE; if ((cl->pieceIn == EmptySquare || cl->pieceIn == board[rf][ff] || PieceToChar(board[rf][ff]) == '~' @@ -1171,15 +1205,15 @@ void DisambiguateCallback(board, flags, kind, rf, ff, rt, ft, closure) ) && (cl->rfIn == -1 || cl->rfIn == rf) && (cl->ffIn == -1 || cl->ffIn == ff) && - (cl->rtIn == -1 || cl->rtIn == rt) && - (cl->ftIn == -1 || cl->ftIn == ft)) { + (cl->rtIn == -1 || cl->rtIn == rt || wildCard) && + (cl->ftIn == -1 || cl->ftIn == ft || wildCard)) { cl->count++; cl->piece = board[rf][ff]; cl->rf = rf; cl->ff = ff; - cl->rt = rt; - cl->ft = ft; + cl->rt = wildCard ? cl->rtIn : rt; + cl->ft = wildCard ? cl->ftIn : ft; cl->kind = kind; } } @@ -1190,14 +1224,11 @@ void Disambiguate(board, flags, epfile, closure) DisambiguateClosure *closure; { int illegal = 0; char c = closure->promoCharIn; + closure->count = 0; closure->rf = closure->ff = closure->rt = closure->ft = 0; closure->kind = ImpossibleMove; - if (appData.debugMode) { - fprintf(debugFP, "Disambiguate in: %d(%d,%d)-(%d,%d) = %d (%c)\n", - closure->pieceIn,closure->ffIn,closure->rfIn,closure->ftIn,closure->rtIn, - closure->promoCharIn, closure->promoCharIn >= ' ' ? closure->promoCharIn : '-'); - } + GenLegal(board, flags, epfile, initialRights, DisambiguateCallback, (VOIDSTAR) closure); if (closure->count == 0) { /* See if it's an illegal move due to check */ @@ -1206,13 +1237,6 @@ void Disambiguate(board, flags, epfile, closure) (VOIDSTAR) closure); if (closure->count == 0) { /* No, it's not even that */ - if (appData.debugMode) { int i, j; - for(i=BOARD_HEIGHT-1; i>=0; i--) { - for(j=0; jkind = IllegalMove; else if(flags & F_WHITE_ON_MOVE) { -#if 0 - if (appData.debugMode) { - fprintf(debugFP, "Disambiguate B: %d(%d,%d)-(%d,%d) = %d (%c)\n", - closure->pieceIn,closure->ffIn,closure->rfIn,closure->ftIn,closure->rtIn, - closure->promoCharIn,closure->promoCharIn); - } -#endif if( (int) piece < (int) WhiteWazir && (closure->rf > BOARD_HEIGHT-4 || closure->rt > BOARD_HEIGHT-4) ) { if( (piece == WhitePawn || piece == WhiteQueen) && closure->rt > BOARD_HEIGHT-2 || @@ -1272,13 +1282,6 @@ void Disambiguate(board, flags, epfile, closure) closure->kind = IllegalMove; } } -#if 0 - if (appData.debugMode) { - fprintf(debugFP, "Disambiguate C: %d(%d,%d)-(%d,%d) = %d (%c)\n", - closure->pieceIn,closure->ffIn,closure->rfIn,closure->ftIn,closure->rtIn, - closure->promoCharIn,closure->promoCharIn); - } -#endif /* [HGM] returns 'q' for optional promotion, 'n' for mandatory */ if(closure->promoCharIn != '=') closure->promoChar = ToLower(closure->promoCharIn); @@ -1297,11 +1300,6 @@ void Disambiguate(board, flags, epfile, closure) 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, - closure->promoChar >= ' ' ? closure->promoChar:'-'); - } } @@ -1383,8 +1381,6 @@ ChessMove CoordsToAlgebraic(board, flags, epfile, piece = board[rf][ff]; if(PieceToChar(piece)=='~') piece = (ChessSquare)(DEMOTED piece); - if (appData.debugMode) - fprintf(debugFP, "CoordsToAlgebraic, piece=%d (%d,%d)-(%d,%d) %c\n", (int)piece,ff,rf,ft,rt,promoChar >= ' ' ? promoChar : '-'); switch (piece) { case WhitePawn: case BlackPawn: @@ -1415,8 +1411,6 @@ ChessMove CoordsToAlgebraic(board, flags, epfile, } /* Use promotion suffix style "=Q" */ *outp = NULLCHAR; - if (appData.debugMode) - fprintf(debugFP, "movetype=%d, promochar=%d=%c\n", (int)kind, promoChar, promoChar >= ' ' ? promoChar : '-'); if (promoChar != NULLCHAR) { if(gameInfo.variant == VariantShogi) { /* [HGM] ... but not in Shogi! */