From 7d36b24250db61fe2fd46465d7685ce008f7d546 Mon Sep 17 00:00:00 2001 From: H.G. Muller Date: Thu, 16 Sep 2010 18:48:29 +0200 Subject: [PATCH] Extend legality testing to drop moves LegalityTest() can nowbe called with (internal-format) drop moves, and delegates their testing to a new routine LegalDrop(). This routine performs the 'no-pawn-on-back-rank' test that used to be in UserMoveTest (which now calls LegalityTest also for drop moves). The more complex Shogi case is also handled (except for Pawn mate drops) in LegalDrop(). --- backend.c | 8 +++----- moves.c | 42 +++++++++++++++++++++++++++++++++++++++--- parser.c | 6 +++--- parser.l | 6 +++--- 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/backend.c b/backend.c index 65ea20d..12cef35 100644 --- a/backend.c +++ b/backend.c @@ -895,7 +895,7 @@ InitBackEnd1() case VariantGothic: /* [HGM] should work */ case VariantCapablanca: /* [HGM] should work */ case VariantCourier: /* [HGM] initial forced moves not implemented */ - case VariantShogi: /* [HGM] drops not tested for legality */ + case VariantShogi: /* [HGM] could still mate with pawn drop */ case VariantKnightmate: /* [HGM] should work */ case VariantCylinder: /* [HGM] untested */ case VariantFalcon: /* [HGM] untested */ @@ -5996,7 +5996,7 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar) fromX = fromX ? WhitePawn : BlackPawn; // first piece type in selected holdings while(PieceToChar(fromX) == '.' || PieceToNumber(fromX) != fromY && fromX != (int) EmptySquare) fromX++; fromY = DROP_RANK; - } else + } /* [HGM] always test for legality, to get promotion info */ moveType = LegalityTest(boards[currentMove], PosFlags(currentMove), @@ -7164,9 +7164,7 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h /* to make sure an illegal e.p. capture does not slip through, */ /* to cause a forfeit on a justified illegal-move complaint */ /* of the opponent. */ - if( gameMode==TwoMachinesPlay && appData.testLegality - && fromY != DROP_RANK /* [HGM] temporary; should still add legality test for drops */ - ) { + if( gameMode==TwoMachinesPlay && appData.testLegality ) { ChessMove moveType; moveType = LegalityTest(boards[forwardMostMove], PosFlags(forwardMostMove), fromY, fromX, toY, toX, promoChar); diff --git a/moves.c b/moves.c index 545a09c..f4f33b2 100644 --- a/moves.c +++ b/moves.c @@ -987,7 +987,7 @@ int CheckTest(board, flags, rf, ff, rt, ft, enPassant) } board[rt][ft] = board[rf][ff]; board[rf][ff] = EmptySquare; - } + } else board[rt][ft] = ff; // [HGM] drop /* For compatibility with ICS wild 9, we scan the board in the order a1, a2, a3, ... b1, b2, ..., h8 to find the first king, @@ -1022,11 +1022,44 @@ int CheckTest(board, flags, rf, ff, rt, ft, enPassant) } else { board[rt][ft] = captured; } - } + } else board[rt][ft] = EmptySquare; // [HGM] drop return cl.fking < BOARD_RGHT ? cl.check : 1000; // [HGM] atomic: return 1000 if we have no king } +ChessMove LegalDrop(board, flags, piece, rt, ft) + Board board; + int flags; + ChessSquare piece; + int rt, ft; +{ // [HGM] put drop legality testing in separate routine for clarity + int n; +if(appData.debugMode) fprintf(debugFP, "LegalDrop: %d @ %d,%d)\n", piece, ft, rt); + if(board[rt][ft] != EmptySquare) return ImpossibleMove; // must drop to empty square + n = PieceToNumber(piece); + if(gameInfo.holdingsWidth == 0 || (flags & F_WHITE_ON_MOVE ? board[n][BOARD_WIDTH-1] : board[BOARD_HEIGHT-1-n][0]) != piece) + return ImpossibleMove; // piece not available + if(gameInfo.variant == VariantShogi) { // in Shogi lots of drops are forbidden! + if((piece == WhitePawn || piece == WhiteQueen) && rt == BOARD_HEIGHT-1 || + (piece == BlackPawn || piece == BlackQueen) && rt == 0 || + piece == WhiteKnight && rt > BOARD_HEIGHT-3 || + piece == BlackKnight && rt < 2 ) return IllegalMove; // e.g. where dropped piece has no moves + if(piece == WhitePawn || piece == BlackPawn) { + int r; + for(r=1; r