Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Keep track of virginity of back-rank pieces in variant seirawan

The forelast rank of the Board array is now used in VariantSChess to
contain flags that indicate virginity of the back-rank pieces, one bit
for white, the other for black. Legality checking of gatings now makes
use of this info. FENs mention all virgin pieces not implied by castling
rights in the castling field, by printing the corresponding file IDs,
as long as holdings are non-empty. The FEN reader now also understands
this format. EditPositionDone fakes virginity for all pieces that are
on their starting square.
  • Loading branch information...
commit 2d0f4769e69d228d9593c574014c634706edea97 1 parent 2fd5b93
H.G. Muller authored
Showing with 64 additions and 12 deletions.
  1. +55 −11 backend.c
  2. +3 −0  common.h
  3. +6 −1 moves.c
View
66 backend.c
@@ -5866,6 +5866,7 @@ InitPosition (int redraw)
case VariantSChess:
SetCharTable(pieceToChar, "PNBRQ..HEKpnbrq..hek");
gameInfo.holdingsSize = 7;
+ for(i=0; i<BOARD_FILES; i++) initialPosition[VIRGIN][i] = VIRGIN_W | VIRGIN_B;
break;
case VariantJanus:
pieces = JanusArray;
@@ -9314,6 +9315,13 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board)
) board[CASTLING][i] = NoRights; // revoke for moved or captured piece
}
+ if(gameInfo.variant == VariantSChess) { // update virginity
+ if(fromY == 0) board[VIRGIN][fromX] &= ~VIRGIN_W; // loss by moving
+ if(fromY == BOARD_HEIGHT-1) board[VIRGIN][fromX] &= ~VIRGIN_B;
+ if(toY == 0) board[VIRGIN][toX] &= ~VIRGIN_W; // loss by capture
+ if(toY == BOARD_HEIGHT-1) board[VIRGIN][toX] &= ~VIRGIN_B;
+ }
+
if (fromX == toX && fromY == toY) return;
piece = board[fromY][fromX]; /* [HGM] remember, for Shogi promotion */
@@ -13931,14 +13939,22 @@ EditPositionDone (Boolean fakeRights)
if(fakeRights) { // [HGM] suppress this if we just pasted a FEN.
boards[0][EP_STATUS] = EP_NONE;
boards[0][CASTLING][2] = boards[0][CASTLING][5] = BOARD_WIDTH>>1;
- if(boards[0][0][BOARD_WIDTH>>1] == king) {
+ if(boards[0][0][BOARD_WIDTH>>1] == king) {
boards[0][CASTLING][1] = boards[0][0][BOARD_LEFT] == WhiteRook ? BOARD_LEFT : NoRights;
boards[0][CASTLING][0] = boards[0][0][BOARD_RGHT-1] == WhiteRook ? BOARD_RGHT-1 : NoRights;
} else boards[0][CASTLING][2] = NoRights;
- if(boards[0][BOARD_HEIGHT-1][BOARD_WIDTH>>1] == WHITE_TO_BLACK king) {
+ if(boards[0][BOARD_HEIGHT-1][BOARD_WIDTH>>1] == WHITE_TO_BLACK king) {
boards[0][CASTLING][4] = boards[0][BOARD_HEIGHT-1][BOARD_LEFT] == BlackRook ? BOARD_LEFT : NoRights;
boards[0][CASTLING][3] = boards[0][BOARD_HEIGHT-1][BOARD_RGHT-1] == BlackRook ? BOARD_RGHT-1 : NoRights;
} else boards[0][CASTLING][5] = NoRights;
+ if(gameInfo.variant = VariantSChess) {
+ int i;
+ for(i=BOARD_LEFT; i<BOARD_RGHT; i++) { // pieces in their original position are assumed virgin
+ boards[0][VIRGIN][i] = 0;
+ if(boards[0][0][i] == FIDEArray[0][i-BOARD_LEFT]) boards[0][VIRGIN][i] |= VIRGIN_W;
+ if(boards[0][BOARD_HEIGHT-1][i] == FIDEArray[1][i-BOARD_LEFT]) boards[0][VIRGIN][i] |= VIRGIN_B;
+ }
+ }
}
SendToProgram("force\n", &first);
if (blackPlaysFirst) {
@@ -16659,14 +16675,30 @@ PositionToFEN (int move, char *overrideCastling)
/* [HGM] write true castling rights */
if( nrCastlingRights == 6 ) {
+ int q, k=0;
if(boards[move][CASTLING][0] == BOARD_RGHT-1 &&
- boards[move][CASTLING][2] != NoRights ) *p++ = 'K';
- if(boards[move][CASTLING][1] == BOARD_LEFT &&
- boards[move][CASTLING][2] != NoRights ) *p++ = 'Q';
+ boards[move][CASTLING][2] != NoRights ) k = 1, *p++ = 'K';
+ q = (boards[move][CASTLING][1] == BOARD_LEFT &&
+ boards[move][CASTLING][2] != NoRights );
+ if(gameInfo.variant = VariantSChess) { // for S-Chess, indicate all vrgin backrank pieces
+ for(i=j=0; i<BOARD_HEIGHT; i++) j += boards[move][i][BOARD_RGHT]; // count white held pieces
+ for(i=BOARD_RGHT-1-k; i>=BOARD_LEFT+q && j; i--)
+ if((boards[move][0][i] != WhiteKing || k+q == 0) &&
+ boards[move][VIRGIN][i] & VIRGIN_W) *p++ = i + AAA + 'A' - 'a';
+ }
+ if(q) *p++ = 'Q';
+ k = 0;
if(boards[move][CASTLING][3] == BOARD_RGHT-1 &&
- boards[move][CASTLING][5] != NoRights ) *p++ = 'k';
- if(boards[move][CASTLING][4] == BOARD_LEFT &&
- boards[move][CASTLING][5] != NoRights ) *p++ = 'q';
+ boards[move][CASTLING][5] != NoRights ) k = 1, *p++ = 'k';
+ q = (boards[move][CASTLING][4] == BOARD_LEFT &&
+ boards[move][CASTLING][5] != NoRights );
+ if(gameInfo.variant = VariantSChess) {
+ for(i=j=0; i<BOARD_HEIGHT; i++) j += boards[move][i][BOARD_LEFT-1]; // count black held pieces
+ for(i=BOARD_RGHT-1-k; i>=BOARD_LEFT+q && j; i--)
+ if((boards[move][BOARD_HEIGHT-1][i] != BlackKing || k+q == 0) &&
+ boards[move][VIRGIN][i] & VIRGIN_B) *p++ = i + AAA;
+ }
+ if(q) *p++ = 'q';
}
}
if (q == p) *p++ = '-'; /* No castling rights */
@@ -16732,7 +16764,7 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen)
{
int i, j;
char *p, c;
- int emptycount;
+ int emptycount, virgin[BOARD_FILES];
ChessSquare piece;
p = fen;
@@ -16861,14 +16893,15 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen)
while(*p==' ') p++;
if(nrCastlingRights) {
- if(*p=='K' || *p=='Q' || *p=='k' || *p=='q' || *p=='-') {
+ if(gameInfo.variant == VariantSChess) for(i=0; i<BOARD_FILES; i++) virgin[i] = 0;
+ if(*p >= 'A' && *p <= 'Z' || *p >= 'a' && *p <= 'z' || *p=='-') {
/* castling indicator present, so default becomes no castlings */
for(i=0; i<nrCastlingRights; i++ ) {
board[CASTLING][i] = NoRights;
}
}
while(*p=='K' || *p=='Q' || *p=='k' || *p=='q' || *p=='-' ||
- (gameInfo.variant == VariantFischeRandom || gameInfo.variant == VariantCapaRandom) &&
+ (gameInfo.variant == VariantFischeRandom || gameInfo.variant == VariantCapaRandom || gameInfo.variant == VariantSChess) &&
( *p >= 'a' && *p < 'a' + gameInfo.boardWidth) ||
( *p >= 'A' && *p < 'A' + gameInfo.boardWidth) ) {
int c = *p++, whiteKingFile=NoRights, blackKingFile=NoRights;
@@ -16888,25 +16921,34 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen)
for(i=BOARD_RGHT-1; board[0][i]!=WhiteRook && i>whiteKingFile; i--);
board[CASTLING][0] = i != whiteKingFile ? i : NoRights;
board[CASTLING][2] = whiteKingFile;
+ if(board[CASTLING][0] != NoRights) virgin[board[CASTLING][0]] |= VIRGIN_W;
+ if(board[CASTLING][2] != NoRights) virgin[board[CASTLING][2]] |= VIRGIN_W;
break;
case'Q':
for(i=BOARD_LEFT; i<BOARD_RGHT && board[0][i]!=WhiteRook && i<whiteKingFile; i++);
board[CASTLING][1] = i != whiteKingFile ? i : NoRights;
board[CASTLING][2] = whiteKingFile;
+ if(board[CASTLING][1] != NoRights) virgin[board[CASTLING][1]] |= VIRGIN_W;
+ if(board[CASTLING][2] != NoRights) virgin[board[CASTLING][2]] |= VIRGIN_W;
break;
case'k':
for(i=BOARD_RGHT-1; board[BOARD_HEIGHT-1][i]!=BlackRook && i>blackKingFile; i--);
board[CASTLING][3] = i != blackKingFile ? i : NoRights;
board[CASTLING][5] = blackKingFile;
+ if(board[CASTLING][3] != NoRights) virgin[board[CASTLING][3]] |= VIRGIN_B;
+ if(board[CASTLING][5] != NoRights) virgin[board[CASTLING][5]] |= VIRGIN_B;
break;
case'q':
for(i=BOARD_LEFT; i<BOARD_RGHT && board[BOARD_HEIGHT-1][i]!=BlackRook && i<blackKingFile; i++);
board[CASTLING][4] = i != blackKingFile ? i : NoRights;
board[CASTLING][5] = blackKingFile;
+ if(board[CASTLING][4] != NoRights) virgin[board[CASTLING][4]] |= VIRGIN_B;
+ if(board[CASTLING][5] != NoRights) virgin[board[CASTLING][5]] |= VIRGIN_B;
case '-':
break;
default: /* FRC castlings */
if(c >= 'a') { /* black rights */
+ if(gameInfo.variant == VariantSChess) { virgin[c-AAA] |= VIRGIN_B; break; } // in S-Chess castlings are always kq, so just virginity
for(i=BOARD_LEFT; i<BOARD_RGHT; i++)
if(board[BOARD_HEIGHT-1][i] == BlackKing) break;
if(i == BOARD_RGHT) break;
@@ -16919,6 +16961,7 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen)
else
board[CASTLING][4] = c;
} else { /* white rights */
+ if(gameInfo.variant == VariantSChess) { virgin[c-AAA-'A'+'a'] |= VIRGIN_W; break; } // in S-Chess castlings are always KQ
for(i=BOARD_LEFT; i<BOARD_RGHT; i++)
if(board[0][i] == WhiteKing) break;
if(i == BOARD_RGHT) break;
@@ -16934,6 +16977,7 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen)
}
for(i=0; i<nrCastlingRights; i++)
if(board[CASTLING][i] != NoRights) initialRights[i] = board[CASTLING][i];
+ if(gameInfo.variant == VariantSChess) for(i=0; i<BOARD_FILES; i++) board[VIRGIN][i] = virgin[i];
if (appData.debugMode) {
fprintf(debugFP, "FEN castling rights:");
for(i=0; i<nrCastlingRights; i++)
View
3  common.h
@@ -132,10 +132,13 @@ int pclose(FILE *);
#define BOARD_LEFT (gameInfo.holdingsWidth) /* [HGM] play-board edges */
#define BOARD_RGHT (gameInfo.boardWidth + gameInfo.holdingsWidth)
#define CASTLING (BOARD_RANKS-1) /* [HGM] hide in upper rank */
+#define VIRGIN (BOARD_RANKS-2) /* [HGM] pieces not moved */
#define EP_STATUS CASTLING][(BOARD_FILES-2) /* [HGM] in upper rank */
#define HOLDINGS_SET CASTLING][(BOARD_FILES-1) /* [HGM] in upper-right corner*/
#define ONE ('1'-(BOARD_HEIGHT>9)) /* [HGM] foremost board rank */
#define AAA ('a'-BOARD_LEFT) /* [HGM] leftmost board file */
+#define VIRGIN_W 1 /* [HGM] flags in Board[VIRGIN][X] */
+#define VIRGIN_B 2
#define DROP_RANK -3
#define MAX_MOVES 1000
#define MSG_SIZ 512
View
7 moves.c
@@ -146,7 +146,8 @@ CopyBoard (Board to, Board from)
for (i = 0; i < BOARD_HEIGHT; i++)
for (j = 0; j < BOARD_WIDTH; j++)
to[i][j] = from[i][j];
- for (j = 0; j < BOARD_FILES-1; j++) // [HGM] gamestate: copy castling rights and ep status
+ for (j = 0; j < BOARD_FILES; j++) // [HGM] gamestate: copy castling rights and ep status
+ to[VIRGIN][j] = from[VIRGIN][j],
to[CASTLING][j] = from[CASTLING][j];
to[HOLDINGS_SET] = 0; // flag used in ICS play
}
@@ -1127,9 +1128,11 @@ LegalityTest (Board board, int flags, int rf, int ff, int rt, int ft, int promoC
if(gameInfo.variant == VariantSChess && promoChar && promoChar != '=' && board[rf][ff] != WhitePawn && board[rf][ff] != BlackPawn) {
if(board[rf][ff] < BlackPawn) { // white
if(rf != 0) return IllegalMove; // must be on back rank
+ if(!(board[VIRGIN][ff] & VIRGIN_W)) return IllegalMove; // non-virgin
if(board[PieceToNumber(CharToPiece(ToUpper(promoChar)))][BOARD_WIDTH-2] == 0) return ImpossibleMove;// must be in stock
} else {
if(rf != BOARD_HEIGHT-1) return IllegalMove;
+ if(!(board[VIRGIN][ff] & VIRGIN_B)) return IllegalMove; // non-virgin
if(board[BOARD_HEIGHT-1-PieceToNumber(CharToPiece(ToLower(promoChar)))][1] == 0) return ImpossibleMove;
}
} else
@@ -1356,9 +1359,11 @@ Disambiguate (Board board, int flags, DisambiguateClosure *closure)
if(gameInfo.variant == VariantSChess && c && c != '=' && closure->piece != WhitePawn && closure->piece != BlackPawn) {
if(closure->piece < BlackPawn) { // white
if(closure->rf != 0) closure->kind = IllegalMove; // must be on back rank
+ if(!(board[VIRGIN][closure->ff] & VIRGIN_W)) closure->kind = IllegalMove; // non-virgin
if(board[PieceToNumber(CharToPiece(ToUpper(c)))][BOARD_WIDTH-2] == 0) closure->kind = ImpossibleMove;// must be in stock
} else {
if(closure->rf != BOARD_HEIGHT-1) closure->kind = IllegalMove;
+ if(!(board[VIRGIN][closure->ff] & VIRGIN_B)) closure->kind = IllegalMove; // non-virgin
if(board[BOARD_HEIGHT-1-PieceToNumber(CharToPiece(ToLower(c)))][1] == 0) closure->kind = ImpossibleMove;
}
} else
Please sign in to comment.
Something went wrong with that request. Please try again.