int
Partner (ChessSquare *p)
{ // change piece into promotion partner if one shogi-promotes to the other
- int stride = gameInfo.variant == VariantChu ? WhiteTokin : 11;
- ChessSquare partner;
- partner = (*p/stride & 1 ? *p - stride : *p + stride);
+ ChessSquare partner = promoPartner[*p];
if(PieceToChar(*p) != '+' && PieceToChar(partner) != '+') return 0;
*p = partner;
return 1;
{
int n = 0;
if(!*escapes) return strlen(s);
- while(*s) n += (*s != '/' && !strchr(escapes, *s)), s++;
+ while(*s) n += (*s != '/' && *s != '-' && *s != '^' && *s != '*' && !strchr(escapes, *s)), s++;
return n;
}
/* Basically a safe strcpy that uses the last character as King */
{
int result = FALSE; int NrPieces, offs;
+ unsigned char partner[EmptySquare];
if( map != NULL && (NrPieces=ptclen(map, escapes)) <= (int) EmptySquare
&& NrPieces >= 12 && !(NrPieces&1)) {
for( i=0; i<(int) EmptySquare; i++ ) table[i] = '.';
for( i=offs=0; i<NrPieces/2-1; i++ ) {
- char *p;
+ char *p, c=0;
if(map[j] == '/' && *escapes) offs = WhiteTokin - i, j++;
+ if(*escapes && (map[j] == '*' || map[j] == '-' || map[j] == '^')) c = map[j++];
table[i + offs] = map[j++];
if(p = strchr(escapes, map[j])) j++, table[i + offs] += 64*(p - escapes + 1);
+ if(c) partner[i + offs] = table[i + offs], table[i + offs] = c;
}
table[(int) WhiteKing] = map[j++];
for( i=offs=0; i<NrPieces/2-1; i++ ) {
- char *p;
+ char *p, c=0;
if(map[j] == '/' && *escapes) offs = WhiteTokin - i, j++;
+ if(*escapes && (map[j] == '*' || map[j] == '-' || map[j] == '^')) c = map[j++];
table[WHITE_TO_BLACK i + offs] = map[j++];
if(p = strchr(escapes, map[j])) j++, table[WHITE_TO_BLACK i + offs] += 64*(p - escapes + 1);
+ if(c) partner[WHITE_TO_BLACK i + offs] = table[WHITE_TO_BLACK i + offs], table[WHITE_TO_BLACK i + offs] = c;
}
table[(int) BlackKing] = map[j++];
+
+ if(*escapes) { // set up promotion pairing
+ for( i=0; i<(int) EmptySquare; i++ ) promoPartner[i] = (i%BlackPawn < 11 ? i + 11 : i%BlackPawn < 22 ? i - 11 : i); // default
+ // pieceToChar entirely filled, so we can look up specified partners
+ for(i=0; i<EmptySquare; i++) { // adjust promotion pairing
+ int c = table[i];
+ if(c == '^' || c == '-') { // has specified partner
+ int p;
+ for(p=0; p<EmptySquare; p++) if(table[p] == partner[i]) break;
+ if(c == '^') table[i] = '+';
+ if(p < EmptySquare) promoPartner[p] = i, promoPartner[i] = p; // marry them
+ } else if(c == '*') promoPartner[i] = (i < BlackPawn ? WhiteTokin : BlackTokin); // promotes to Tokin
+ }
+ }
+
result = TRUE;
}
initialPosition[CASTLING][i] = initialRights[i] = NoRights; /* but no rights yet */
initialPosition[EP_STATUS] = EP_NONE;
initialPosition[TOUCHED_W] = initialPosition[TOUCHED_B] = 0;
- SetCharTable(pieceToChar, "PNBRQ...........Kpnbrq...........k");
+ SetCharTableEsc(pieceToChar, "PNBRQ...........Kpnbrq...........k", SUFFIXES);
if(startVariant == gameInfo.variant) // [HGM] nicks: enable nicknames in original variant
SetCharTable(pieceNickName, appData.pieceNickNames);
else SetCharTable(pieceNickName, "............");
gameInfo.boardWidth = 12;
gameInfo.boardHeight = 12;
nrCastlingRights = 0;
- SetCharTableEsc(pieceToChar, "P.BRQSEXOGCATHD.VMLIFN/+.++.++++++++++.+++++K"
- "p.brqsexogcathd.vmlifn/+.++.++++++++++.+++++k", SUFFIXES);
+ SetCharTableEsc(pieceToChar, "P.BRQSEXOGCATHD.VMLIFN/^P.^B^R.^S^E^X^O^G^C^A^T^H^D.^V^M^L^I^FK"
+ "p.brqsexogcathd.vmlifn/^p.^b^r.^s^e^x^o^g^c^a^t^h^d.^v^m^l^i^fk", SUFFIXES);
break;
case VariantCourier:
pieces = CourierArray;
piece = boards[currentMove][fromY][fromX];
if(gameInfo.variant == VariantChu) {
- int p = piece >= BlackPawn ? BLACK_TO_WHITE piece : piece;
promotionZoneSize = BOARD_HEIGHT/3;
- highestPromotingPiece = (p >= WhiteTokin || PieceToChar(piece + WhiteTokin) != '+') ? WhitePawn : WhiteTokin-1;
+ highestPromotingPiece = (PieceToChar(piece) == '+' || PieceToChar(CHUPROMOTED(piece)) != '+') ? WhitePawn : WhiteKing;
} else if(gameInfo.variant == VariantShogi) {
promotionZoneSize = BOARD_HEIGHT/3 +(BOARD_HEIGHT == 8);
highestPromotingPiece = (int)WhiteAlfil;
/* [HGM] some macros that can be used as prefixes to convert piece types */
#define WHITE_TO_BLACK (int)BlackPawn - (int)WhitePawn + (int)
#define BLACK_TO_WHITE (int)WhitePawn - (int)BlackPawn + (int)
-#define PROMOTED (int)WhiteDragon - (int)WhiteRook + (int)
-#define DEMOTED (int)WhiteRook - (int)WhiteDragon + (int)
+#define PROMO (int)WhiteDragon - (int)WhiteRook + (int)
+#define PROMOTED(X) (promoPartner[X])
+#define DEMOTED(X) (promoPartner[X])
#define SHOGI (int)EmptySquare + (int)
-#define CHUPROMOTED ((int)WhitePDragon - (int)WhiteDragon)*(gameInfo.variant == VariantChu) + PROMOTED
-#define CHUDEMOTED ((int)WhiteDragon - (int)WhitePDragon)*(gameInfo.variant == VariantChu) + DEMOTED
+#define CHUPROMOTED(X) (promoPartner[X])
+#define CHUDEMOTED(X) (promoPartner[X])
#define IS_SHOGI(V) ((V) == VariantShogi || (V) == VariantChu)
#define IS_LION(V) ((V) == WhiteLion || (V) == BlackLion)