From 7693c7936daeb938298191577545323f382ef3a4 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Sat, 30 Jan 2016 09:09:03 +0100 Subject: [PATCH] Use flexible promotion assignment The promoted partner now comes from an array, rather than by adding a constant (11, or 27 in chu) to the base type. The array is initialized so the first 11 pieces (the old 'base pieces') point to the second 11 (the old 'promoted series'), and the latter point back (so the array also contains the demotions!). The pieces above 21 (= Lion) point to themselves. Parsing of the pieceToChar string now considers ^, - and * prefixes rather than independent IDs. Nevertheless it is the - and ^ that get stored in the pieceToCharTable (the latter as '+') for the corresponding piece. But the ID that follows them specifies what other piece they are the demoted or promoted partner of, rather than their own ID, and is thus used to update the promoPartner array for both of them. A * prefix does mean the following ID is the ID assigned to the piece, but that the piece promotes to Tokin (if the latter is assigned a '+'). The default pieceToChar string for varaint chu is adapted to use this new assignment mechanism of promotion partner. (Chu is so far the only variant that needed other pairing than the default.) --- backend.c | 39 ++++++++++++++++++++++++++++----------- common.h | 9 +++++---- moves.c | 1 + moves.h | 1 + 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/backend.c b/backend.c index 8a47479..58905cb 100644 --- a/backend.c +++ b/backend.c @@ -5383,9 +5383,7 @@ static ClickType lastClickType; 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; @@ -5994,7 +5992,7 @@ ptclen (const char *s, char *escapes) { 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; } @@ -6004,6 +6002,7 @@ SetCharTableEsc (unsigned char *table, const char * map, char * escapes) /* 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)) { @@ -6011,20 +6010,39 @@ SetCharTableEsc (unsigned char *table, const char * map, char * escapes) for( i=0; i<(int) EmptySquare; i++ ) table[i] = '.'; for( i=offs=0; i= 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; diff --git a/common.h b/common.h index 498bf38..6ba5774 100644 --- a/common.h +++ b/common.h @@ -320,11 +320,12 @@ typedef enum { /* [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) diff --git a/moves.c b/moves.c index d0cc65c..68bf107 100644 --- a/moves.c +++ b/moves.c @@ -121,6 +121,7 @@ unsigned char pieceToChar[EmptySquare+1] = { 'o', 'h', 'i', 'j', 'g', 'd', 'v', 'l', 's', 'u', 'k', 'x' }; unsigned char pieceNickName[EmptySquare]; +int promoPartner[EmptySquare]; char PieceToChar (ChessSquare p) diff --git a/moves.h b/moves.h index aeb6307..674d56e 100644 --- a/moves.h +++ b/moves.h @@ -63,6 +63,7 @@ extern void CopyBoard P((Board to, Board from)); extern int CompareBoards P((Board board1, Board board2)); extern unsigned char pieceToChar[(int)EmptySquare+1]; extern unsigned char pieceNickName[(int)EmptySquare]; +extern int promoPartner[(int)EmptySquare]; extern char *pieceDesc[(int)EmptySquare]; extern Board initialPosition; extern Boolean pieceDefs; -- 1.7.0.4