X-Git-Url: http://winboard.nl/cgi-bin?p=capablanca.git;a=blobdiff_plain;f=lasker-2.2.3%2Fsrc%2Fmovecheck.c;h=6996d09215fa25f9b8ad571079b234b7773d5bb0;hp=8f0dd9cb42c4075afdb72c40732835ab1dc2c862;hb=ec7b6bb32ba9632cda17b308808ce9ba1e27c090;hpb=de64701702c2b4d4d951be0e77afeda5177bc494 diff --git a/lasker-2.2.3/src/movecheck.c b/lasker-2.2.3/src/movecheck.c index 8f0dd9c..6996d09 100644 --- a/lasker-2.2.3/src/movecheck.c +++ b/lasker-2.2.3/src/movecheck.c @@ -1296,7 +1296,7 @@ int legal_move(struct game_state_t * gs, if (fFile == ALG_DROP) { move_piece = fRank; - if(!gs->drops) return 0; // [HGM] variants: no drops in this variant + if(gs->drops != 1) return 0; // [HGM] variants: no drops in this variant if (move_piece == KING) return 0; if (gs->holding[gs->onMove==WHITE ? 0 : 1][move_piece-1] == 0) @@ -1387,10 +1387,12 @@ int legal_move(struct game_state_t * gs, case ROOK: legal = legal_rook_move(gs, fFile, fRank, tFile, tRank); break; + case HAWK: case CARDINAL: case PRINCESS: legal = legal_cardinal_move(gs, fFile, fRank, tFile, tRank); break; + case SELEPHANT: case MARSHALL: case EMPRESS: legal = legal_marshall_move(gs, fFile, fRank, tFile, tRank); @@ -1484,6 +1486,7 @@ int legal_move(struct game_state_t * gs, static int move_calculate(struct game_state_t * gs, struct move_t * mt, int promote) { struct game_state_t fakeMove; + int gating = 0; mt->pieceCaptured = gs->board[mt->toFile][mt->toRank]; mt->enPassant = 0; /* Don't know yet, let execute move take care @@ -1536,15 +1539,23 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom int stm = colorval(gs->board[mt->fromFile][mt->fromRank]); if(!promote && (mt->toRank == 0 || mt->toRank == gs->ranks-1)) { // promotion obligatory, but not specified if(gs->promoType != 2) promote = QUEEN; else { // choose a default - for(promote=KING-1; promote>PAWN; promote--) if(gs->holding[stm == BLACK][promote-1]) break; + for(promote=PIECES-1; promote>PAWN; promote--) if(gs->holding[stm == BLACK][promote-1]) break; if(promote == PAWN) return MOVE_ILLEGAL; // nothing available } - } // if not obligatory, we defer unless promoton was explicitly specified! + } // if not obligatory, we defer unless promotion was explicitly specified! if(!gs->pawnDblStep && promote == PRINCESS) promote = MAN2; if(!gs->pawnDblStep && promote != FERZ2 && promote != MAN2) promote = FERZ; // [HGM] kludge to recognize shatranj // non-promotion can still be an option for deeper promotion zones mt->piecePromotionTo = promote ? (promote | stm) : NOPIECE; if(promote && gs->promoType == 2 && !gs->holding[stm == BLACK][promote-1]) return MOVE_ILLEGAL; // unavailable piece specified + } else if(gs->drops == 2 && promote && mt->fromRank == (stm == WHITE ? 0 : gs->ranks-1)) { // [HGM] Seirawan-style gating + int i; struct game *g = &game_globals.garray[gs->gameNum]; + if(!gs->holding[stm == BLACK][promote-1]) return MOVE_ILLEGAL; // unavailable piece specified + // now we must test virginity of the moved piece. Yegh! + for (i = g->numHalfMoves-2; i > 0; i -= 2) { + if (g->moveList[i].toFile == mt->fromFile && g->moveList[i].toRank == mt->fromRank) return MOVE_ILLEGAL; + } + gating = 1; // gating OK; remember we did it for check test } else { mt->piecePromotionTo = NOPIECE; } @@ -1579,6 +1590,7 @@ static int move_calculate(struct game_state_t * gs, struct move_t * mt, int prom fakeMove = *gs; /* Calculates enPassant also */ execute_move(&fakeMove, mt, 0); + if(gating) fakeMove.board[mt-fromFile][mt->fromRank] = NOPIECE; // [HGM] gating is only legal if non-gating move was (weird, but true) /* Does making this move leave ME in check? */ if (in_check(&fakeMove)) @@ -1667,10 +1679,12 @@ int has_legal_move(struct game_state_t * gs) case ROOK: possible_rook_moves(gs, f, r, possiblef, possibler, &numpossible); break; + case HAWK: case CARDINAL: case PRINCESS: possible_cardinal_moves(gs, f, r, possiblef, possibler, &numpossible); break; + case SELEPHANT: case MARSHALL: case EMPRESS: possible_marshall_moves(gs, f, r, possiblef, possibler, &numpossible); @@ -1922,13 +1936,19 @@ int execute_move(struct game_state_t * gs, struct move_t * mt, int check_game_st } else { movedPiece = gs->board[mt->fromFile][mt->fromRank]; tookPiece = gs->board[mt->toFile][mt->toRank]; - if (mt->piecePromotionTo == NOPIECE) { + if(gs->drops == 2 && mt->piecePromotionTo != NOPIECE && pieceType(movedPiece) != PAWN) { // [HGM] Seirawan-style gating gs->board[mt->toFile][mt->toRank] = gs->board[mt->fromFile][mt->fromRank]; + gs->board[mt->fromFile][mt->fromRank] = mt->piecePromotionTo | gs->onMove;; + gs->holding[gs->onMove==WHITE ? 0 : 1][mt->piecePromotionTo-1]--; // remove gated piece from holdings } else { - gs->board[mt->toFile][mt->toRank] = mt->piecePromotionTo | gs->onMove; - if(gs->promoType == 2) gs->holding[gs->onMove][mt->piecePromotionTo-1]--; + if (mt->piecePromotionTo == NOPIECE) { + gs->board[mt->toFile][mt->toRank] = gs->board[mt->fromFile][mt->fromRank]; + } else { + gs->board[mt->toFile][mt->toRank] = mt->piecePromotionTo | gs->onMove; + if(gs->promoType == 2) gs->holding[gs->onMove][mt->piecePromotionTo-1]--; + } + gs->board[mt->fromFile][mt->fromRank] = NOPIECE; } - gs->board[mt->fromFile][mt->fromRank] = NOPIECE; /* Check if irreversable */ if ((piecetype(movedPiece) == PAWN) && (mt->fromRank != mt->toRank) // [HGM] XQ: sideway Pawn move reversible! || (tookPiece != NOPIECE)) { @@ -2243,6 +2263,9 @@ int backup_move(int g, int mode) goto cleanupMove; } gs->board[m->toFile][m->toRank] = m->pieceCaptured; + if(gs->board[m->fromFile][m->fromRank] != NOPIECE) { // [HGM] from-square occupied, must have been Seirawan-style gating + gs->holding[gs->onMove==WHITE ? 1 : 0][piecetype(gs->board[m->fromFile][m->fromRank])-1]++; // put back in holdings (onMove not flipped yet!) + } cleanupMove: if (game_globals.garray[g].status != GAME_EXAMINE) { game_update_time(g);