// but suppress black pieces that are the same as their white counterpart
ChessSquare p;
static char buf[MSG_SIZ], s[2];
- char *m, c, d, *pieceName = defaultName;
- int len;
+ char *m, *pieceName = defaultName;
+ int len, c, d;
*buf = NULLCHAR;
if(!pieceDefs) return "";
if(gameInfo.variant == VariantChu) return ""; // for now don't do this for Chu Shogi
}
void
-MovesFromString (Board board, int flags, int f, int r, int tx, int ty, int angle, char *desc, MoveCallback cb, VOIDSTAR cl)
+MovesFromString (Board board, int flags, int f, int r, int tx, int ty, int angle, int range, char *desc, MoveCallback cb, VOIDSTAR cl)
{
char buf[80], *p = desc, *atom = NULL;
int mine, his, dir, bit, occup, i, ep, promoRank = -1;
if(isdigit(*++p)) expo = atoi(p++); // read exponent
if(expo > 9) p++; // allow double-digit
desc = p; // this is start of next move
- if(initial == 2) { if(board[r][f] != initialPosition[r-2*his+3][f]) continue; } else
- if(initial && (board[r][f] != initialPosition[r][f] ||
+ if(initial == 2) { if(board[r][f] != initialPosition[r-2*his+3][f]) continue; initial = 0; } else
+ if(initial && !range) {
+ if( (board[r][f] != initialPosition[r][f] ||
r == 0 && board[TOUCHED_W] & 1<<f ||
- r == BOARD_HEIGHT-1 && board[TOUCHED_B] & 1<<f ) ) continue;
+ r == BOARD_HEIGHT-1 && board[TOUCHED_B] & 1<<f )) continue;
+ initial = 0;
+ }
if(expo > 0 && dx == 0 && dy == 0) { // castling indicated by O + number
mode |= 1024; dy = 1;
}
if(board[y][x] < BlackPawn) occup = 0x101; else
if(board[y][x] < EmptySquare) occup = 0x102; else
occup = 4;
+ if(initial && expo - i + 1 != range) { if(occup == 4) continue; else break; }
if(cont) { // non-final leg
if(mode&16 && his&occup) occup &= 3;// suppress hopping foe in t-mode
if(occup & mode) { // valid intermediate square, do continuation
char origAtom = *atom;
+ int rg = (expo != 1 ? expo - i + 1 : range); // pass length of last *slider* leg
if(!(bit & all)) *atom = rotate[*atom - 'A']; // orth-diag interconversion to make direction valid
if(occup & mode & 0x104) // no side effects, merge legs to one move
- MovesFromString(board, flags, f, r, x, y, dir, cont, cb, cl);
- if(occup & mode & 3 && (killX < 0 || killX == x && killY == y)) { // destructive first leg
+ MovesFromString(board, flags, f, r, x, y, dir, rg, cont, cb, cl);
+ if(occup & mode & 3 && (killX < 0 || kill2X < 0 && (legNr > 1 || killX == x && killY == y) ||
+ (legNr == 1 ? kill2X == x && kill2Y == y : killX == x && killY == y))) { // destructive first leg
int cnt = 0;
- MovesFromString(board, flags, f, r, x, y, dir, cont, &OK, &cnt); // count possible continuations
- if(cnt) { // and if there are
- if(killX < 0) cb(board, flags, FirstLeg, r, f, y, x, cl); // then generate their first leg
+ legNr <<= 1;
+ MovesFromString(board, flags, f, r, x, y, dir, rg, cont, &OK, &cnt); // count possible continuations
+ legNr >>= 1;
+ if(cnt) { // and if there are
+ if(legNr & 1 ? killX < 0 : kill2X < 0) cb(board, flags, FirstLeg, r, f, y, x, cl); // then generate their first leg
legNr <<= 1;
- MovesFromString(board, flags, f, r, x, y, dir, cont, cb, cl);
+ MovesFromString(board, flags, f, r, x, y, dir, rg, cont, cb, cl);
legNr >>= 1;
}
}
void
Sting (Board board, int flags, int rf, int ff, int dy, int dx, MoveCallback callback, VOIDSTAR closure)
-{ // Lion-like move of Horned Falcon and Souring Eagle
+{ // Lion-like move of Horned Falcon and Soaring Eagle
int ft = ff + dx, rt = rf + dy;
if (rt < 0 || rt >= BOARD_HEIGHT || ft < BOARD_LEFT || ft >= BOARD_RGHT) return;
legNr += 2;
if (!SameColor(board[rf][ff], board[rt][ft]))
- callback(board, flags, board[rt][ft] != EmptySquare ? FirstLeg : NormalMove, rf, ff, rt, ft, closure);
+ callback(board, flags, killX < 0 && board[rt][ft] != EmptySquare ? FirstLeg : NormalMove, rf, ff, rt, ft, closure);
legNr -= 2;
ft += dx; rt += dy;
if (rt < 0 || rt >= BOARD_HEIGHT || ft < BOARD_LEFT || ft >= BOARD_RGHT) return;
piece = (ChessSquare) ( DEMOTED(piece) );
if(filter != EmptySquare && piece != filter) continue;
if(pieceDefs && pieceDesc[piece]) { // [HGM] gen: use engine-defined moves
- MovesFromString(board, flags, ff, rf, -1, -1, 0, pieceDesc[piece], callback, closure);
+ MovesFromString(board, flags, ff, rf, -1, -1, 0, 0, pieceDesc[piece], callback, closure);
continue;
}
if(IS_SHOGI(gameInfo.variant))
if (rt < 0 || rt >= BOARD_HEIGHT || ft < BOARD_LEFT || ft >= BOARD_RGHT) continue;
if (!(ff == ft && rf == rt) && SameColor(board[rf][ff], board[rt][ft])) continue;
i = (killX >= 0 && (rt-killY)*(rt-killY) + (killX-ft)*(killX-ft) < 3); legNr += 2*i;
- callback(board, flags, (rt-rf)*(rt-rf) + (ff-ft)*(ff-ft) < 3 && board[rt][ft] != EmptySquare ? FirstLeg : NormalMove,
+ callback(board, flags, (rt-rf)*(rt-rf) + (ff-ft)*(ff-ft) < 3 && board[rt][ft] != EmptySquare && !i ? FirstLeg : NormalMove,
rf, ff, rt, ft, closure);
legNr -= 2*i;
}
{
CheckTestClosure cl;
ChessSquare king = flags & F_WHITE_ON_MOVE ? WhiteKing : BlackKing;
- ChessSquare captured = EmptySquare, ep=0, trampled=0;
+ ChessSquare captured = EmptySquare, ep=0, trampled=0, trampled2 = 0;
int saveKill = killX;
/* Suppress warnings on uninitialized variables */
board[rf][ft] = EmptySquare;
} else {
captured = board[rt][ft];
- if(killX >= 0) { trampled = board[killY][killX]; board[killY][killX] = EmptySquare; killX = -1; }
+ if(killX >= 0) {
+ trampled = board[killY][killX]; board[killY][killX] = EmptySquare; killX = -1; saveKill += (kill2X << 16) + (1 << 30);
+ if(kill2X >= 0) { trampled2 = board[kill2Y][kill2X]; board[kill2Y][kill2X] = EmptySquare; kill2X = -1; }
+ }
}
if(rf == DROP_RANK) board[rt][ft] = ff; else { // [HGM] drop
board[rt][ft] = board[rf][ff];
board[rf][ft] = captured;
board[rt][ft] = EmptySquare;
} else {
- if(saveKill >= 0) board[killY][killX = saveKill] = trampled;
+ if(saveKill >= 0) {
+ if(saveKill & 1<<30) board[kill2Y][kill2X = saveKill >> 16 & 0xFFF] = trampled2;
+ board[killY][killX = saveKill & 0xFFF] = trampled;
+ }
board[rt][ft] = captured;
}
board[EP_STATUS] = ep;