From 93077be9f3009b8eb6ad64067f31d000aaf284c3 Mon Sep 17 00:00:00 2001 From: H.G. Muller Date: Sun, 19 Apr 2009 09:52:47 -0700 Subject: [PATCH] changes from H.G. Muller; version 4.3.12 --- backend.c | 267 +++++++++++++++++++++++++++++++---------------- config.h | 2 +- moves.c | 32 +++--- parser.l | 8 +- readme_HGM.txt | 97 +++++++++++++++++ shogibitmaps/sa58o.bmp | Bin 0 -> 526 bytes shogibitmaps/sb58o.bmp | Bin 0 -> 526 bytes shogibitmaps/sc58o.bmp | Bin 0 -> 526 bytes shogibitmaps/sf58o.bmp | Bin 0 -> 526 bytes shogibitmaps/sg58o.bmp | Bin 0 -> 526 bytes shogibitmaps/sh58o.bmp | Bin 0 -> 526 bytes shogibitmaps/sk58o.bmp | Bin 0 -> 526 bytes shogibitmaps/sk58w.bmp | Bin 0 -> 526 bytes shogibitmaps/sl58o.bmp | Bin 0 -> 526 bytes shogibitmaps/sl58w.bmp | Bin 0 -> 526 bytes shogibitmaps/sn58o.bmp | Bin 0 -> 526 bytes shogibitmaps/sn58w.bmp | Bin 0 -> 526 bytes shogibitmaps/sp58o.bmp | Bin 0 -> 526 bytes shogibitmaps/sp58w.bmp | Bin 0 -> 526 bytes shogibitmaps/sr58o.bmp | Bin 0 -> 526 bytes shogibitmaps/sr58w.bmp | Bin 0 -> 526 bytes shogibitmaps/ss58o.bmp | Bin 0 -> 526 bytes shogibitmaps/su58o.bmp | Bin 0 -> 526 bytes shogibitmaps/sw58o.bmp | Bin 0 -> 526 bytes shogibitmaps/sw58w.bmp | Bin 0 -> 526 bytes winboard/winboard.c | 90 ++++++++++++++--- winboard/winboard.rc | 23 ++++- winboard/woptions.c | 4 + 28 files changed, 398 insertions(+), 125 deletions(-) create mode 100644 shogibitmaps/sa58o.bmp create mode 100644 shogibitmaps/sb58o.bmp create mode 100644 shogibitmaps/sc58o.bmp create mode 100644 shogibitmaps/sf58o.bmp create mode 100644 shogibitmaps/sg58o.bmp create mode 100644 shogibitmaps/sh58o.bmp create mode 100644 shogibitmaps/sk58o.bmp create mode 100644 shogibitmaps/sk58w.bmp create mode 100644 shogibitmaps/sl58o.bmp create mode 100644 shogibitmaps/sl58w.bmp create mode 100644 shogibitmaps/sn58o.bmp create mode 100644 shogibitmaps/sn58w.bmp create mode 100644 shogibitmaps/sp58o.bmp create mode 100644 shogibitmaps/sp58w.bmp create mode 100644 shogibitmaps/sr58o.bmp create mode 100644 shogibitmaps/sr58w.bmp create mode 100644 shogibitmaps/ss58o.bmp create mode 100644 shogibitmaps/su58o.bmp create mode 100644 shogibitmaps/sw58o.bmp create mode 100644 shogibitmaps/sw58w.bmp diff --git a/backend.c b/backend.c index 79bdc68..e9e1368 100644 --- a/backend.c +++ b/backend.c @@ -1789,6 +1789,9 @@ VariantSwitch(Board board, VariantClass newVariant) gameInfo.holdingsWidth = newHoldingsWidth; gameInfo.variant = newVariant; InitDrawingSizes(-2, 0); + + if(board != boards[0]) InitPosition(FALSE); + } else gameInfo.variant = newVariant; } @@ -3311,6 +3314,10 @@ ParseBoard12(string) fromX = fromY = toX = toY = -1; } else { /* Move from ICS was illegal!? Punt. */ + if (appData.debugMode) { + fprintf(debugFP, "Illegal move from ICS '%s'\n", move_str); + fprintf(debugFP, "board L=%d, R=%d, H=%d, holdings=%d\n", BOARD_LEFT, BOARD_RGHT, BOARD_HEIGHT, gameInfo.holdingsWidth); + } #if 0 if (appData.testLegality && appData.debugMode) { sprintf(str, "Illegal move \"%s\" from ICS", move_str); @@ -3478,11 +3485,6 @@ SendMoveToProgram(moveNum, cps) } else { sprintf(buf, "%s\n", parseList[moveNum]); } - /* [HGM] decrement all digits to code ranks starting from 0 */ - if(BOARD_HEIGHT>9) { - char *p = buf; - while(*p) { if(*p < 'A') (*p)--; p++; } - } SendToProgram(buf, cps); } else { /* Added by Tord: Send castle moves in "O-O" in FRC games if required by @@ -3616,15 +3618,62 @@ ProcessICSInitScript(f) void AlphaRank(char *move, int n) { - char *p = move, c; + char *p = move, c; int x, y; if( !appData.alphaRank ) return; - while(c = *p) { - if(c>='0' && c<='9') *p += AAA-ONE; else - if(c>='a' && c<'x') *p -= AAA-ONE; - p++; - if(--n < 1) break; + if (appData.debugMode) { + fprintf(debugFP, "alphaRank(%s,%d)\n", move, n); + } + + if(move[1]=='*' && + move[2]>='0' && move[2]<='9' && + move[3]>='a' && move[3]<='x' ) { + move[2] = (move[2]-'1')+BOARD_LEFT + AAA; + move[3] = (move[3]-'a') + ONE; + } else + if(move[0]>='0' && move[0]<='9' && + move[1]>='a' && move[1]<='x' && + move[2]>='0' && move[2]<='9' && + move[3]>='a' && move[3]<='x' ) { + /* input move, Shogi -> normal */ +/* + move[0] = BOARD_RGHT -1-(move[0]-'1') + AAA; + move[1] = BOARD_HEIGHT-1-(move[1]-'a') + ONE; + move[2] = BOARD_RGHT -1-(move[2]-'1') + AAA; + move[3] = BOARD_HEIGHT-1-(move[3]-'a') + ONE; +*/ + move[0] = (move[0]-'1')+BOARD_LEFT + AAA; + move[1] = (move[1]-'a') + ONE; + move[2] = (move[2]-'1')+BOARD_LEFT + AAA; + move[3] = (move[3]-'a') + ONE; + } else + if(move[1]=='@' && + move[3]>='0' && move[3]<='9' && + move[2]>='a' && move[2]<='x' ) { + move[1] = '*'; + move[2] = (move[2]-AAA)-BOARD_LEFT + '1'; + move[3] = (move[3]-ONE) + 'a'; + } else + if( + move[0]>='a' && move[0]<='x' && + move[3]>='0' && move[3]<='9' && + move[2]>='a' && move[2]<='x' ) { + /* output move, normal -> Shogi */ +/* + move[0] = BOARD_RGHT -1-(move[0]-AAA) + '1'; + move[1] = BOARD_HEIGHT-1-(move[1]-ONE) + 'a'; + move[2] = BOARD_RGHT -1-(move[2]-AAA) + '1'; + move[3] = BOARD_HEIGHT-1-(move[3]-ONE) + 'a'; +*/ + move[0] = (move[0]-AAA)-BOARD_LEFT + '1'; + move[1] = (move[1]-ONE) + 'a'; + move[2] = (move[2]-AAA)-BOARD_LEFT + '1'; + move[3] = (move[3]-ONE) + 'a'; + if(move[4] == PieceToChar(BlackQueen)) move[4] = '+'; + } + if (appData.debugMode) { + fprintf(debugFP, " out = '%s'\n", move); } } @@ -3640,16 +3689,13 @@ ParseOneMove(move, moveNum, moveType, fromX, fromY, toX, toY, promoChar) if (appData.debugMode) { fprintf(debugFP, "move to parse: %s\n", move); } - AlphaRank(move, 10); *moveType = yylexstr(moveNum, move); switch (*moveType) { -#ifdef FAIRY case WhitePromotionChancellor: case BlackPromotionChancellor: case WhitePromotionArchbishop: case BlackPromotionArchbishop: -#endif case WhitePromotionQueen: case BlackPromotionQueen: case WhitePromotionRook: @@ -3685,6 +3731,9 @@ ParseOneMove(move, moveNum, moveType, fromX, fromY, toX, toY, promoChar) *promoChar = currentMoveString[4]; if (*fromX < BOARD_LEFT || *fromX >= BOARD_RGHT || *fromY < 0 || *fromY >= BOARD_HEIGHT || *toX < BOARD_LEFT || *toX >= BOARD_RGHT || *toY < 0 || *toY >= BOARD_HEIGHT) { + if (appData.debugMode) { + fprintf(debugFP, "Off-board move (%d,%d)-(%d,%d)%c, type = %d\n", *fromX, *fromY, *toX, *toY, *promoChar, *moveType); + } *fromX = *fromY = *toX = *toY = 0; return FALSE; } @@ -3716,6 +3765,9 @@ ParseOneMove(move, moveNum, moveType, fromX, fromY, toX, toY, promoChar) case BlackWins: case GameIsDrawn: default: + if (appData.debugMode) { + fprintf(debugFP, "Impossible move %s, type = %d\n", currentMoveString, *moveType); + } /* bug? */ *fromX = *fromY = *toX = *toY = 0; *promoChar = NULLCHAR; @@ -3855,6 +3907,9 @@ InitPosition(redraw) } initialRulePlies = 0; /* 50-move counter start */ + + castlingRank[0] = castlingRank[1] = castlingRank[2] = 0; + castlingRank[3] = castlingRank[4] = castlingRank[5] = BOARD_HEIGHT-1; } @@ -3887,7 +3942,7 @@ InitPosition(redraw) castlingRights[0][6] = initialRights[2] = 5; castlingRights[0][7] = initialRights[5] = 5; castlingRank[6] = 0; - castlingRank[6] = BOARD_HEIGHT-1; + castlingRank[7] = BOARD_HEIGHT-1; startedFromSetupPosition = TRUE; break; case VariantCapablanca: @@ -3913,7 +3968,7 @@ InitPosition(redraw) gameInfo.boardHeight = 9; gameInfo.holdingsSize = 7; nrCastlingRights = 0; - SetCharTable(pieceToChar, "PNBRLSG.........Kpnbrlsg.........k"); + SetCharTable(pieceToChar, "PNBRLSG...++++++Kpnbrlsg...++++++k"); break; case VariantShowgi: pieces = ShogiArray; @@ -3933,7 +3988,7 @@ InitPosition(redraw) break; case VariantKnightmate: pieces = KnightmateArray; - strcpy(pieceToChar, "P.BRQ...M.K......p.brq...m.k......"); + SetCharTable(pieceToChar, "P.BRQ...M.K......p.brq...m.k......"); break; case VariantFairy: pieces = fairyArray; @@ -3943,6 +3998,7 @@ InitPosition(redraw) case VariantCrazyhouse: case VariantBughouse: pieces = FIDEArray; + SetCharTable(pieceToChar, "PNBRQ......~~~~.Kpnbrq......~~~~.k"); gameInfo.holdingsSize = 5; break; case VariantWildCastle: @@ -4027,9 +4083,6 @@ InitPosition(redraw) castlingRights[0][3] = initialRights[3] = BOARD_RGHT-1; castlingRights[0][4] = initialRights[4] = BOARD_LEFT; castlingRights[0][5] = initialRights[5] = BOARD_WIDTH>>1; - - castlingRank[0] = castlingRank[1] = castlingRank[2] = 0; - castlingRank[3] = castlingRank[4] = castlingRank[5] = BOARD_HEIGHT-1; } if(gameInfo.variant == VariantFischeRandom) { @@ -4283,6 +4336,21 @@ UserMoveTest(fromX, fromY, toX, toY, promoChar) return ImpossibleMove; } + /* [HGM] suppress all moves into holdings area and guard band */ + if( toX < BOARD_LEFT || toX >= BOARD_RGHT || toY < 0 ) + return ImpossibleMove; + + /* [HGM] moved to here from winboard.c */ + /* note: this code seems to exist for filtering out some obviously illegal premoves */ + pdown = boards[currentMove][fromY][fromX]; + pup = boards[currentMove][toY][toX]; + if ( gameMode != EditPosition && + (WhitePawn <= pdown && pdown < BlackPawn && + WhitePawn <= pup && pup < BlackPawn || + BlackPawn <= pdown && pdown < EmptySquare && + BlackPawn <= pup && pup < EmptySquare) ) + return ImpossibleMove; + /* Check if the user is playing in turn. This is complicated because we let the user "pick up" a piece before it is his turn. So the piece he tried to pick up may have been captured by the time he puts it down! @@ -4401,21 +4469,6 @@ UserMoveTest(fromX, fromY, toX, toY, promoChar) return ImpossibleMove; } - /* [HGM] suppress all moves into holdings area and guard band */ - if( toX < BOARD_LEFT || toX >= BOARD_RGHT || toY < 0 ) - return ImpossibleMove; - - /* [HGM] moved to here from winboard.c */ - /* note: EditPosition already filtered out and performed! */ - pdown = boards[currentMove][fromY][fromX]; - pup = boards[currentMove][toY][toX]; - if ( - (WhitePawn <= pdown && pdown < BlackPawn && - WhitePawn <= pup && pup < BlackPawn) || - (BlackPawn <= pdown && pdown < EmptySquare && - BlackPawn <= pup && pup < EmptySquare) ) - return ImpossibleMove; - /* [HGM] If move started in holdings, it means a drop */ if( fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) { if( pup != EmptySquare ) return ImpossibleMove; @@ -4758,6 +4811,7 @@ HandleMachineMove(message, cps) return; } + AlphaRank(machineMove, 4); if (!ParseOneMove(machineMove, forwardMostMove, &moveType, &fromX, &fromY, &toX, &toY, &promoChar)) { /* Machine move could not be parsed; ignore it. */ @@ -4979,7 +5033,8 @@ HandleMachineMove(message, cps) count = 0; for(k = forwardMostMove-2; k>=backwardMostMove && k>=forwardMostMove-100 && - epStatus[k] <= EP_NONE && epStatus[k+1] <= EP_NONE; + epStatus[k] < EP_UNKNOWN && + epStatus[k+2] <= EP_NONE && epStatus[k+1] <= EP_NONE; k-=2) { int rights=0; if (appData.debugMode) { @@ -5418,6 +5473,10 @@ HandleMachineMove(message, cps) } else if (strncmp(message, "Black resign", 12) == 0) { GameEnds(WhiteWins, "Black resigns", GE_ENGINE1 + (cps != &first)); return; + } else if (strncmp(message, "White matches", 13) == 0 || + strncmp(message, "Black matches", 13) == 0 ) { + /* [HGM] ignore GNUShogi noises */ + return; } else if (strncmp(message, "White", 5) == 0 && message[5] != '(' && StrStr(message, "Black") == NULL) { @@ -5818,12 +5877,16 @@ ParseGameHistory(game) yyboardindex = boardIndex; moveType = (ChessMove) yylex(); switch (moveType) { -#ifdef FAIRY + case IllegalMove: /* maybe suicide chess, etc. */ + if (appData.debugMode) { + fprintf(debugFP, "Illegal move from ICS: '%s'\n", yy_text); + fprintf(debugFP, "board L=%d, R=%d, H=%d, holdings=%d\n", BOARD_LEFT, BOARD_RGHT, BOARD_HEIGHT, gameInfo.holdingsWidth); + setbuf(debugFP, NULL); + } case WhitePromotionChancellor: case BlackPromotionChancellor: case WhitePromotionArchbishop: case BlackPromotionArchbishop: -#endif case WhitePromotionQueen: case BlackPromotionQueen: case WhitePromotionRook: @@ -5851,7 +5914,6 @@ ParseGameHistory(game) case BlackHSideCastleFR: case BlackASideCastleFR: /* POP Fabien */ - case IllegalMove: /* maybe suicide chess, etc. */ fromX = currentMoveString[0] - AAA; fromY = currentMoveString[1] - ONE; toX = currentMoveString[2] - AAA; @@ -5871,11 +5933,21 @@ ParseGameHistory(game) case AmbiguousMove: /* bug? */ sprintf(buf, "Ambiguous move in ICS output: \"%s\"", yy_text); + if (appData.debugMode) { + fprintf(debugFP, "Ambiguous move from ICS: '%s'\n", yy_text); + fprintf(debugFP, "board L=%d, R=%d, H=%d, holdings=%d\n", BOARD_LEFT, BOARD_RGHT, BOARD_HEIGHT, gameInfo.holdingsWidth); + setbuf(debugFP, NULL); + } DisplayError(buf, 0); return; case ImpossibleMove: /* bug? */ sprintf(buf, "Illegal move in ICS output: \"%s\"", yy_text); + if (appData.debugMode) { + fprintf(debugFP, "Impossible move from ICS: '%s'\n", yy_text); + fprintf(debugFP, "board L=%d, R=%d, H=%d, holdings=%d\n", BOARD_LEFT, BOARD_RGHT, BOARD_HEIGHT, gameInfo.holdingsWidth); + setbuf(debugFP, NULL); + } DisplayError(buf, 0); return; case (ChessMove) 0: /* end of file */ @@ -6215,14 +6287,14 @@ MakeMove(fromX, fromY, toX, toY, promoChar) if( boards[forwardMostMove][fromY][fromX] == WhitePawn ) { epStatus[forwardMostMove] = EP_PAWN_MOVE; if( toY-fromY==2 && - (toX>BOARD_LEFT+1 && boards[forwardMostMove][toY][toX-1] == BlackPawn || + (toX>BOARD_LEFT && boards[forwardMostMove][toY][toX-1] == BlackPawn || toXBOARD_LEFT+1 && boards[forwardMostMove][toY][toX-1] == WhitePawn || + (toX>BOARD_LEFT && boards[forwardMostMove][toY][toX-1] == WhitePawn || toX */ - if( (int)piece > (int) WhiteCannon && (int)piece < (int) WhiteKing || - (int)piece > (int) BlackCannon && (int)piece < (int) BlackKing ) { - *p++ = '+'; - piece = (ChessSquare)(DEMOTED piece); - } + if(PieceToChar(piece) == '+') { + /* [HGM] write promoted pieces as '+' (Shogi) */ + *p++ = '+'; + piece = (ChessSquare)(DEMOTED piece); } *p++ = PieceToChar(piece); - if(gameInfo.variant == VariantCrazyhouse || gameInfo.variant == VariantBughouse) { - /* [HGM] flag Crazyhouse promoted pieces */ - if( (int)piece > (int) WhiteQueen && (int)piece < (int) WhiteKing || - (int)piece > (int) BlackQueen && (int)piece < (int) BlackKing ) { - p[-1] = PieceToChar((ChessSquare)(DEMOTED piece)); - *p++ = '~'; - } + if(p[-1] == '~') { + /* [HGM] flag promoted pieces as '~' (Crazyhouse) */ + p[-1] = PieceToChar((ChessSquare)(DEMOTED piece)); + *p++ = '~'; } } } @@ -11736,6 +11805,7 @@ PositionToFEN(move, useFEN960) *p++ = whiteToPlay ? 'w' : 'b'; *p++ = ' '; + if(nrCastlingRights) { /* HACK: we don't keep track of castling availability, so fake it! */ /* Tord! please fix with the aid of castlingRights[move][...] */ @@ -11826,7 +11896,10 @@ PositionToFEN(move, useFEN960) } /* POP Fabien & Tord */ + } + if(gameInfo.variant != VariantShogi && gameInfo.variant != VariantXiangqi && + gameInfo.variant != VariantShatranj && gameInfo.variant != VariantCourier ) { /* En passant target square */ if (move > backwardMostMove) { fromX = moveList[move - 1][0] - AAA; @@ -11846,10 +11919,12 @@ PositionToFEN(move, useFEN960) } else { *p++ = '-'; } + *p++ = ' '; + } /* [HGM] print Crazyhouse or Shogi holdings */ if( gameInfo.holdingsWidth ) { - *p++ = ' '; q = p; + q = p; for(i=0; i backwardMostMove && epStatus[j] <= EP_NONE) j--,i++; if( j == backwardMostMove ) i += initialRulePlies; - sprintf(p, " %d", i); - p += i>=100 ? 4 : i >= 10 ? 3 : 2; + sprintf(p, "%d ", i); + p += i>=100 ? 4 : i >= 10 ? 3 : 2; } /* Fullmove number */ - sprintf(p, " %d", (move / 2) + 1); + sprintf(p, "%d", (move / 2) + 1); return StrSave(buf); } @@ -11902,14 +11977,14 @@ ParseFEN(board, blackPlaysFirst, fen) p = fen; /* [HGM] by default clear Crazyhouse holdings, if present */ - if(gameInfo.holdingsWidth) { + if(gameInfo.holdingsWidth) { for(i=0; i= 0; i--) { @@ -11936,10 +12011,17 @@ ParseFEN(board, blackPlaysFirst, fen) board[i][(j++)+gameInfo.holdingsWidth] = EmptySquare; } else if (*p == '+' || isalpha(*p)) { if (j >= gameInfo.boardWidth) return FALSE; - if(*p=='+') { piece = (ChessSquare) (PROMOTED CharToPiece(*++p) ); p++; } - else piece = CharToPiece(*p++); + if(*p=='+') { + piece = CharToPiece(*++p); + if(piece == EmptySquare) return FALSE; /* unknown piece */ + piece = (ChessSquare) (PROMOTED piece ); p++; + if(PieceToChar(piece) != '+') return FALSE; /* unpromotable piece */ + } else piece = CharToPiece(*p++); + + if(piece==EmptySquare) return FALSE; /* unknown piece */ if(*p == '~') { /* [HGM] make it a promoted piece for Crazyhouse */ piece = (ChessSquare) (PROMOTED piece); + if(PieceToChar(piece) != '~') return FALSE; /* cannot be a promoted piece */ p++; } board[i][(j++)+gameInfo.holdingsWidth] = piece; @@ -11964,7 +12046,7 @@ ParseFEN(board, blackPlaysFirst, fen) /* [HGM] We NO LONGER ignore the rest of the FEN notation */ /* return the extra info in global variiables */ - { + /* set defaults in case FEN is incomplete */ FENepStatus = EP_UNKNOWN; for(i=0; i= BOARD_RGHT) return TRUE; - if(*p >= '0' && *p <='9') *p++; - FENepStatus = c; + if(c < BOARD_LEFT || c >= BOARD_RGHT) return TRUE; + if(*p >= '0' && *p <='9') *p++; + FENepStatus = c; + } } /* [HGM] look for Crazyhouse holdings here */ while(*p==' ') p++; - if( !isdigit(*p) ) { + if( gameInfo.holdingsWidth ) { if(*p == '-' ) *p++; /* empty holdings */ else { if( !gameInfo.holdingsWidth ) return FALSE; /* no room to put holdings! */ /* if we would allow FEN reading to set board size, we would */ @@ -12046,12 +12132,11 @@ ParseFEN(board, blackPlaysFirst, fen) } - if(sscanf(p, "%d", &i) == 1) { FENrulePlies = i; /* 50-move ply counter */ /* (The move number is still ignored) */ } - } + return TRUE; } diff --git a/config.h b/config.h index 7b9e8bc..0e5416c 100644 --- a/config.h +++ b/config.h @@ -47,7 +47,7 @@ #define LAST_PTY_LETTER 'q' -#define PATCHLEVEL "8" +#define PATCHLEVEL "12" #define PRODUCT "WinBoard" diff --git a/moves.c b/moves.c index ddf3ee9..deb245f 100644 --- a/moves.c +++ b/moves.c @@ -281,9 +281,7 @@ void GenPseudoLegal(board, flags, epfile, callback, closure) if (!BlackPiece(board[rf][ff])) continue; } m = 0; piece = board[rf][ff]; - if(gameInfo.variant == VariantCrazyhouse && - ( (int) piece > (int) WhiteQueen && (int) piece < (int) WhiteKing - || (int) piece > (int) BlackQueen && (int) piece < (int) BlackKing )) + if(PieceToChar(piece) == '~') piece = (ChessSquare) ( DEMOTED piece ); if(gameInfo.variant == VariantShogi) piece = (ChessSquare) ( SHOGI piece ); @@ -294,7 +292,7 @@ void GenPseudoLegal(board, flags, epfile, callback, closure) /* can't happen ([HGM] except for faries...) */ break; - case WhitePawn: + case WhitePawn: if(gameInfo.variant == VariantXiangqi) { /* [HGM] capture and move straight ahead in Xiangqi */ if (rf < BOARD_HEIGHT-1 && @@ -1099,7 +1097,10 @@ void DisambiguateCallback(board, flags, kind, rf, ff, rt, ft, closure) { register DisambiguateClosure *cl = (DisambiguateClosure *) closure; - if ((cl->pieceIn == EmptySquare || cl->pieceIn == board[rf][ff]) && + if ((cl->pieceIn == EmptySquare || cl->pieceIn == board[rf][ff] + || PieceToChar(board[rf][ff]) == '~' + && cl->pieceIn == (ChessSquare)(DEMOTED board[rf][ff]) + ) && (cl->rfIn == -1 || cl->rfIn == rf) && (cl->ffIn == -1 || cl->ffIn == ff) && (cl->rtIn == -1 || cl->rtIn == rt) && @@ -1245,7 +1246,10 @@ void CoordsToAlgebraicCallback(board, flags, kind, rf, ff, rt, ft, closure) (CoordsToAlgebraicClosure *) closure; if (rt == cl->rt && ft == cl->ft && - board[rf][ff] == cl->piece) { + (board[rf][ff] == cl->piece + || PieceToChar(board[rf][ff]) == '~' && + (ChessSquare) (DEMOTED board[rf][ff]) == cl->piece) + ) { if (rf == cl->rf) { if (ff == cl->ff) { cl->kind = kind; /* this is the move we want */ @@ -1275,7 +1279,7 @@ ChessMove CoordsToAlgebraic(board, flags, epfile, { ChessSquare piece; ChessMove kind; - char *outp = out; + char *outp = out, c; CoordsToAlgebraicClosure cl; if (rf == DROP_RANK) { @@ -1287,20 +1291,18 @@ ChessMove CoordsToAlgebraic(board, flags, epfile, *outp++ = rt + ONE; else { *outp++ = (rt+ONE-'0')/10 + '0';*outp++ = (rt+ONE-'0')%10 + '0'; } *outp = NULLCHAR; - AlphaRank(out, 5); return (flags & F_WHITE_ON_MOVE) ? WhiteDrop : BlackDrop; } if (promoChar == 'x') promoChar = NULLCHAR; piece = board[rf][ff]; + if(PieceToChar(piece)=='~') piece = (ChessSquare)(DEMOTED piece); if (appData.debugMode) fprintf(debugFP, "CoordsToAlgebraic, piece=%d\n", (int)piece); switch (piece) { case WhitePawn: case BlackPawn: - if (appData.debugMode) - fprintf(debugFP, "CoordsToAlgebraic, Pawn\n"); kind = LegalityTest(board, flags, epfile, initialRights, rf, ff, rt, ft, promoChar); if (kind == IllegalMove && !(flags&F_IGNORE_CHECK)) { /* Keep short notation if move is illegal only because it @@ -1338,7 +1340,6 @@ ChessMove CoordsToAlgebraic(board, flags, epfile, } *outp = NULLCHAR; } - AlphaRank(out, 10); return kind; @@ -1404,13 +1405,14 @@ ChessMove CoordsToAlgebraic(board, flags, epfile, else "N1f3" or "N5xf7", else "Ng1f3" or "Ng5xf7". */ - if(PieceToChar(piece) == '.') { + c = PieceToChar(piece) ; + if( c == '~' || c == '+') { /* [HGM] print nonexistent piece as its demoted version */ piece = (ChessSquare) (DEMOTED piece); - if( gameInfo.variant == VariantShogi ) - *outp++ = '+'; } + if(c=='+') *outp++ = c; *outp++ = ToUpper(PieceToChar(piece)); + if (cl.file || (cl.either && !cl.rank)) { *outp++ = ff + AAA; } @@ -1465,7 +1467,6 @@ ChessMove CoordsToAlgebraic(board, flags, epfile, } } } - AlphaRank(out, 10); return cl.kind; /* [HGM] Always long notation for fairies we don't know */ @@ -1506,7 +1507,6 @@ ChessMove CoordsToAlgebraic(board, flags, epfile, } *outp = NULLCHAR; - AlphaRank(out, 0); return IllegalMove; } diff --git a/parser.l b/parser.l index da4cbc7..46de027 100644 --- a/parser.l +++ b/parser.l @@ -172,6 +172,7 @@ extern void CopyBoard P((Board to, Board from)); int skip1 = 0, skip2 = 0, skip3 = 0, promoted = 0; ChessSquare piece; ChessMove result; + char c; if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */ @@ -218,7 +219,9 @@ extern void CopyBoard P((Board to, Board from)); piece = boards[yyboardindex] [currentMoveString[1] - ONE][currentMoveString[0] - AAA]; if(promoted) piece = (ChessSquare) (DEMOTED piece); - if (ToLower(yytext[skip3]) != ToLower(PieceToChar(piece))) + c = PieceToChar(piece); + if(c == '~') c = PieceToChar((ChessSquare) (DEMOTED piece)); + if (ToLower(yytext[skip3]) != ToLower(c)) return (int) IllegalMove; result = LegalityTest(boards[yyboardindex], @@ -240,9 +243,10 @@ extern void CopyBoard P((Board to, Board from)); return (int) result; } -[a-l][0-9][xX:-]?[a-l][0-9]((=?\(?[A-Z]\)?)|=)? { +[a-l][0-9][xX:-]?[a-l][0-9]((=?\(?[A-Za-z]\)?)|=)? { /* * Simple algebraic move, possibly with promotion + * [HGM] Engine moves are received in this format, with lower-case promoChar! */ int skip = 0; ChessMove result; diff --git a/readme_HGM.txt b/readme_HGM.txt index 0845114..e51a8a0 100644 --- a/readme_HGM.txt +++ b/readme_HGM.txt @@ -1,3 +1,100 @@ +Winboard_F.4.3.12 release notes + +This WinBoard (beta-)version is derived from Allessandro Scotti's Winboard_x, and supports the following new options, mainly in the area of adjudication of engine-engine games, improved Crazyhouse support, and allowing variants with non-conventional pieces and or board sizes. (All option are shown here with their default values): + +/variant=normal +This (already existing) option has been expanded with several new variants, involving non-conventional pieces and deviating board sizes. The board size is automatically adapted to the selected variant, unless explicitly overruled (see below). The new variants are (with default board size, files x ranks, in parentheses): + +variant name Game board description +knightmate Knightmate (8x8) Variant where the King moves as a Knight, and vice versa +capablanca Capablanca Chess (10x8) Variant featuring Archbishop and Chancellor as new pieces +gothic Gothic Chess (10x8) Same as Capablanca, with a more interesting opening position +courier Courier Chess (12x8) a Medieval form that combines elements of Shatranj and modern Chess +shogi Shogi (9x9) Japanese Chess +xiangqi Xiangqi (9x10) Chinese Chess +fairy Fairy Chess (8x8) Variant were you can use all pieces of other variants together + +The variant can be set from the newly added "File -> New Variant..." sub-menu. +Extra board files are indicated by the letters i, j, k, l, ... For boards with more than 9 ranks, the counting starts at zero! More than 10 ranks is not tested and unlikely to work in the area of PGN saving / reading. Non-FIDE pieces will be referred to in FENs and PGN by letters that depend on the variant, and might collide with piece designators in other variants. E.g. in Xiangqi 'C' is a Cannon, in Capablanca Chess it is a Chancellor. Pieces that do not belong in a variant cannot be addressed in FEN and PGN either, for as long as that variant is selected, unless the letter assignment is overruled with the aid of the /pieceToCharTable option. The variant is not saved in the winboard.ini file; on start-up we always get variant "normal" unless we use the command-line option, or have added the option to the winboard.ini file manually (in which case it will disappear when this file is overwritten by WinBoard saving its options). +WinBoard_F knows the movement of all pieces occurring in Capablanca Chess (of which FIDE Chess is a subset), Shatranj, Courier, Xiangqi and 9x9 Shogi, so that these games can be played with legality testing enabled. + +/pieceToCharTable="PNBRQFWEMOUHACGSKpnbrqfwemouhacgsk" +Each piece that WinBoard knows (in its legality test) has a letter associated with it, by which it will be referred to in FEN or PGN. The default assignment can be overruled with this option. The value has to be a string of even length, with at least 12 characters. The first half of the string designates the white pieces, the second half the black. +The last letter for each color will be assigned to the King. (This is the piece that moves as an orthodox King; note that Nightmate and Xiangqi have a different royal piece.) All letters before it will be assigned to the other pieces in the order: + +P Pawn (move often depends on variant) +N Knight (move subtly different in Xiangqi (where it is written as H) or Shogi) +B Bishop +R Rook +Q Queen (Lance L in Shogi) +F Ferz/General (The Shatranj 'Queen' and Xiangqi 'Adviser', used for Silver General S in Shogi.) +W Wazir/GrandVizer (Gold General G in Shogi, in Xiangqi it is royal and denoted by K) +E Alfil/Elephant (Moves subtly different in Xiangqi vs Shatranj/Courier) +M Commoner/Man +O Cannon/Pao +U Unicorn (representation of Royal Knight in Knightmate, used as promoted Pawn in Shogi) +H Nightrider (Promoted Knight in Shogi and CrazyHouse) +A Archbishop/Cardinal (Promoted Bishop in Shogi and CrazyHouse) +C Chancellor/Marshall (Promoted Rook in Shogi and CrazyHouse) +G Grasshopper (Promoted Queen in Crazyhouse, promoted Lance in Shogi) +S (Promoted Silver in Shogi) +K King + +Pieces that are not mentioned (because the argument has less than 34 characters) will remain disabled. Mentioned pieces can be disabled by assigning them a '.' (period). They are then not recognized in FEN or PGN input. Non-FIDE pieces that are not assigned a letter will also not appear on the promotion menu. It is not advisable to disable a piece that is present in the opening position of the selected variant, though. +Promoted pieces that need to be distinguished from original pieces of the same type (because of demotion on capture and transfer to the holdings) will be indicated by the letter for the unpromoted piece with a '+' in front of it (Shogi), or by the letter of the promoted piece with a '~' after it (Crazyhouse, Bughouse, in general everything with holdings that is not Shogi). To achieve this, they should be assigned the characters '+' or '~', respectively. +All the new pieces have a native bitmap representation in the board sizes 'bulky' and 'middling'. For all window sizes that do not support such fairy bitmaps, promoted NBRQ are represented as a 2-sizes-smaller normal piece symbol, so that Crazyhouse can be played at any size. People disliking the fairy representations might even prefer this. +There is an enhanced 'Edit Position' menu popup (right-clicking on the squares after selecting this mode in the main menu), featuring some common non-FIDE pieces, and 'promote' and 'demote' options to make those not directly in the menu. The promotion popup shows ArchBishop and Chancellor in Capablanca and Gothic, (or in fact in any game where this piece is not disabled or a promoted version of a normal piece), and leaves only the options YES / NO in Shogi. In Xiangqi there are no promotions. + +/fontPieceToCharTable="PNBRQFWEMOUHACGSKpnbrqfwemouhacgsk" +This option is similar to /pieceToCharTable, but sets the font character that is used to display the piece on the screen (when font-based rendering is in use), rather than in the FEN or PGN. The default setting should work with George Tsavdaris' WinboardF font, which uses the 'intuitive' mapping of font characters to symbols. With font-based rendering the fairy pieces can be used at any board size. +Note that UHACGS are also used to represent the promoted versions of PNBRQF, in games like Crazyhouse and Shogi, where the promotion has to be undone on capture. In such games you are likely to prefer a different representation of those pieces then when they represent true fairy pieces. + +/boardWidth=-1 /boardHeight=-1 +Set a number of files and ranks of the playing board to a value that will override the defaults for the variant that is selected. A value of -1 means the variant default board size will be used for the corresponding parameter (and is itself the default value of these options). These parameters can be set in the "Files -> New Variant..." sub-menu, where they are reset to the default -1 if you OK the chosen variant without typing something to overrule it. These parameters are saved in the winboard.ini file. (But unless you saved while a variant with board-size override was selected, they will always be saved as -1.) +A variant with a non-standard board size will be communicated to the engine(s) with the board size prefixed to the variant name, e.g. "variant 12x8_capablanca". In protocol 2 the engine must first enable this feature by sending "boardsizeFxR" amongst the accepted variants, where F is the maximum number of files, and R the maximum number of ranks, as decimal numbers. + +/holdingsSize=-1 +Set the size of the holdings for dropable pieces to a value that will override the default for the variant that is selected. A value of -1 means the variant default holdings size will be used for that parameter (and is itself the default value of this options). This parameter can be set in the Files -> New Variant... sub-menu, where it is reset to the default -1 if you OK the chosen variant without typing something to overrule it. This parameters is saved in the winboard.ini file. +To disable holdings, set their size to 0. They will then not be displayed. For non-zero holding size N, the holdings are displayed left and right of the board, and piece drops can be effected by dragging pieces from the holdings to the drop square. In bughouse, the holdings will be filled by the ICS. In all other variants, captured pieces will go into the holdings (after reversing their color). Only the first N pieces of the /pieceToCharTable argument will go into the holdings. All other pieces will be converted to Pawns. (In Shogi, however they will be demoted in the regular way before determining if they fit.) Pieces that are disabled (per default and per /pieceToCharTable option) might not be counted when determining what are the first N pieces. +Non-standard holdingsize will be communicated to the engine by prefixing it (together with the board size, even if this is standard) to the variant name, e.g. "variant 7x7+5_shogi". In protocol 2 the engine should enable this feature by sending "holdingsH" amongst the variant names, where H is the maximum acceptable holdings size as a decimal number. + +/alphaRank=FALSE +When this parameter is true, a-h are converted to 1-9, and vice versa, in all move output and input (to PGN files or SAN move display as well as in communication with the engine). This might be useful for Shogi, where conventionally one uses letters to designate ranks, and digits to designate files. Engines that want to use this option must make sure pieces are never represented by lower case! This option can be set from the Files -> New Variant... menu, where it defaults to FALSE unless you explicitly set it. It is not saved in the winboard.ini file. +This kludge does not seem to work for reading PGN files. Saving works fine. For now, using it is not recommended. In the future it might be redefined as only affecting engine-engine communication, . +Note that the PGN format in Shogi also leaves out the trailing '+' as check indicator: In Shogi such a trailing '+' means promotion, while a trailing '=' means defer promotion. Prefix '+' signs are used on moves with promoted pieces, disambiguation is done western SAN style. + +/allWhite=FALSE +Causes the outline of the 'white' pieces to be superimposed onto the 'black' piece symbols as well (as a black outline) when native bitmaps are used (as opposed to font-based rendering). This is useful if we choose a very light color to represent the 'black' pieces. It might be particularly useful in Shogi, where the conventional representation of the 'black' pieces is as upside-down white pieces, so that both colors would be white. This option is saved in the winboard.ini file, and can be set in the "Options -> Board..." sub-menu. + +/flipBlack=FALSE +Setting this option will cause upside-down display of the native piece bitmaps used to represent the pieces of the side that plays black, as would be needed for a traditional representation of Shogi pieces. It can be set from the "Options -> Board..." sub-menu, and it is saved in the winboard.ini file. For now, traditional Shogi bitmaps are only included for size "moderate". For other sizes you must depend on font-based rendering. + +/detectMate=TRUE +/testClaim=TRUE +/materialDraws=TRUE +/trivialDraws=FALSE +/ruleMoves=51 +/repeatsToDraw=6 +These are all options that only affect engine-engine play, and can be set from the "Options -> Engine..." sub-menu. They are all related to adjudication of games by the GUI. Legality checking must be switched on for them to work. +If /detectMate is TRUE, the GUI recognizes checkmate and stalemate (but not in games with holdings!), and ends the game accordingly before the engines can claim. This is convenient for play with engines that fail to claim, and just exit. +With /testClaim set, all result and illegal-move claims by engines that claim more than their own loss are scrutinized for validity, and false claims result in forfeit of the game. Useful with buggy engines. +The option /materialDraws=TRUE causes games with insufficient mating material to be adjudicated immediately as draws, in case the engines would not claim these draws. This applies to KK, KNK and KBK. +The option /trivialDraws adjudicates KNNK, KBKB, KNKN, KBKN, KRKR and KQKQ to draws after 3 moves (to allow for a quick tactical win). Note that in KQKQ this might not be sound, but that problem would disappear once bitbase probing is implemented. +The /ruleMoves determine after how many reversible moves the game is adjudicated as a draw. Setting this to 0 turns this option off. Draw claims by the engine are still accepted (with /testClaim=TRUE) after 50 reversible moves, even if /ruleMoves species a larger number. Note that it is perfectly legal according to FIDE rules to play on after 50 reversible moves, but in tournaments having two engines that want to play on forever is a nuisance in endings like KBNKR, where one of the engines thinks it is ahead and can avoids repeats virtually forever. +The option /repeatsToDraw makes the GUI adjudicate a game as draw after the same position has occurred the specified number of times. If it is set to a value > 3, engines can still claim the draw after 3-fold repeat. +All these options are saved in the winboard.ini file. + +/matchPause=10000 +Determines the number of milliseconds that is paused between two games of a match. In the old WinBoard this was always 10 sec, which was inconveniently long in fast games. If you make the pause too short, tardy engines might get into trouble, though. Saved in the Winboard.ini. + +Clocks +There is an "Options -> swap clocks" command, that swaps the position of white and black clocks (convenient in over-the-board matches, where the display is standing next to the board, and you want your own time to be displayed on your side of the screen). The clocks can be adjusted in "edit game" mode: right-clicking them adds one minute, left-clicking subtracts one minute. (Also for OTB matches, to keep them synchronized with the official match clock.) The flag-fell condition is now indicated as '(!)' behind the displayed time, to eliminate the necessity for overwriting the message in the title bar (which might contain indispensible information in match mode). + +Other improvements / changes +Castling rights and e.p. rights are now fully maintained, and considered in legality testing. They are imported from and written to FEN, as is the 50-move counter. (When reading an incomplete FEN they are still guessed, though.) +The time (in sec, or min:sec) is now always stored together with the PV information to the PGN, if storing the latter was requested (through ticking "extended PGN info" in "Options -> General..."). The saved time is the WinBoard clock time (as opposed to the time reported by the engine). + +---------------------------------------------------------------- Winboard_F.4.3.8 release notes This Winboard supports the following new options (shown here with their default values): diff --git a/shogibitmaps/sa58o.bmp b/shogibitmaps/sa58o.bmp new file mode 100644 index 0000000000000000000000000000000000000000..fcae346bfd3d5edbc73ebf5be98370b9569c03d3 GIT binary patch literal 526 zcmajbu};G<5C&j}o%8`HV&xTJz!IGi&%)RRcjpDz`XZoO6%q@Qc>nYEh6ekgQ4)0`76(W1oEJ z5TSpY(@7*t)mfZ~_u*Mw&$r@Md$C(O_M>pi5xy%gHg4y*Z~WlJE?kSdI6dZk6U#%` zS8;X+zg4_Bf?vw$J?CC0KXX5j^!qXB9`ithaS&U=105o^nS4 Fe*xD(h-d%+ literal 0 HcmV?d00001 diff --git a/shogibitmaps/sb58o.bmp b/shogibitmaps/sb58o.bmp new file mode 100644 index 0000000000000000000000000000000000000000..75b2be29ef458cd0ab9af4ed27117c138444e392 GIT binary patch literal 526 zcmajbu}Z}-6b9g2AK>N%gpN8oi&$_MAH~5*yqHlZ`v|^?H>ltu)Hk?7hm39M&`Q(( z{^z7_!VR2!`A< z&SRVLez92m7_8>1F=~rO+;zYVS}*drX1+ezmueRZvF?JM#5R=bkGWC@v*iE#{TRxT z-}R%()Y;@J?^9!yoKMsdhpy-Oh)0wZd5K&spQHZw4tzOt literal 0 HcmV?d00001 diff --git a/shogibitmaps/sc58o.bmp b/shogibitmaps/sc58o.bmp new file mode 100644 index 0000000000000000000000000000000000000000..84bef21207470ffe2944d4b88fd145796ab9d6c5 GIT binary patch literal 526 zcmajbF-yZh6bJCDi;J{43Z+>c9YsP8T%7zAehG(|j5_oS6#7-9Cpb#$H)tW9ZAykl za=pLr{V$t>2k(A)|9f0WZtsUDhAWf(QtGC!ff+FW6yAri81x$eBc;nl;5^Sp?#N*G z%fNi?#Ek_tNwh;$?qdE@iYPHJu~4Uoy1w7^!ZHtLM7`W6^9y}Z`G+M=nZE`@=i$-H z+UnpuHv9LG$0~6_zt2^P_h&(q)r`u00m#dQEern4#oHc zCZ%ALMax2WMDf z<()sI5Y2!!Y!NFsP?4k%j#Kz7?oon==^aQ+6WDoXI`TY8tWnG=Rozt|pNDKBQJi bK8#88zvq;*+BWFP_e)3ijcnJf<$wPG)I5Tb literal 0 HcmV?d00001 diff --git a/shogibitmaps/sg58o.bmp b/shogibitmaps/sg58o.bmp new file mode 100644 index 0000000000000000000000000000000000000000..580814cf755025e60fb227c172f4f7518e97fc12 GIT binary patch literal 526 zcmbWyyA8rH5C&ie`pm%yfr3c%%w&oz!8Eyo1_=o^0EvPUP>KZQas2n73lumyfAN2| zWUtogBRTDcc@ zA1&Xyb2rm|%NfoR{)1b%-KafxxD(-SsW}8+H;Lu-)T}fg_=PtT-nelo+WPA2r`vq` kD#r(xILDEHTgn#fJK|zug-`5|h@9u<0spc_TLu671{5r+u>b%7 literal 0 HcmV?d00001 diff --git a/shogibitmaps/sh58o.bmp b/shogibitmaps/sh58o.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8b906ebc9dd1cf54eade7e73d62c610e64cfb127 GIT binary patch literal 526 zcmbWzKWf7;6b5j+2S{!Ztv!MXp@Qx`OfOLR23b1i>4UK=va$B0Nus LpDdBFO8)OJCRm;g literal 0 HcmV?d00001 diff --git a/shogibitmaps/sk58o.bmp b/shogibitmaps/sk58o.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8b57f9e831776ddaa8ffe8b2cf4b689e6cfcd45f GIT binary patch literal 526 zcmZwDu}Z{15C-6hSERdpgljA;t>rMFm7p)7psiqYpqRr4u(t3~gxlhu75UXAyA~V?|`K$GF4xC1-0h)au-{_y;`K&Z;yRK zmk%dMQtD36&F!V6dfr||^) zXcZ)>`CL`X)a2Z-mF2aUNyYhkBeBW%{x$HNv5!P=n(+^-U%b@7L`A|0bYV5JM9v=wJj|X7~k2^vndKUGWF_Bm5DNXebbeZPFrzNWPcEK1I24s*9l2 zqju0IDTb)~AMmYj=^_<(4-l8#a69BRk38kKmP=QDu-9DJIGg9vn8!bI`A0k=|CTHI mO7!J&N4`S-i5z$Xp9305!#Btk&yWXf(qW6-Q(GdSvv>h^RoBq~ literal 0 HcmV?d00001 diff --git a/shogibitmaps/sl58o.bmp b/shogibitmaps/sl58o.bmp new file mode 100644 index 0000000000000000000000000000000000000000..799b21aec42a6af35f4d803fdd64860b2ec74a35 GIT binary patch literal 526 zcmbWzF;2r!3yU*{K}0vZ1=yWQ2W`VIwSq z=1rBzyQ%9l^=EdbH|v=j%$erqiHms;xpwKsE!-o2qi^XFe$mwIYnGEKMe0)K{^f@_ z7dS{>Ho89urEq+R=BwDdp@3tM)n50<4@%*NZs9?Wu&vkd{CEY!GxlWJNvZE7rzw1; k6fR$49_M8ux$SMMAZFKgFz^;imbst$)As*5hRXl_1+9jSlmGw# literal 0 HcmV?d00001 diff --git a/shogibitmaps/sl58w.bmp b/shogibitmaps/sl58w.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dc1ce99d0aa9297557772154a799e22669f3bd0d GIT binary patch literal 526 zcmbV|F%E+;3`LzXu)z^nIYS33v2!LkT818=N9YldSQrrQv&jshmcCzNe@Bt~p?Zi% zM{dzGDM;}82fV98UPwt*1zE%cFk173U)q6wE@%7&{<~b6E1ApXhQG$2%N>7%|1Ooe g7ju`KL`L&P)@htsgK^`VM&%i&olQ$3@cUo<0eUtVoB#j- literal 0 HcmV?d00001 diff --git a/shogibitmaps/sn58o.bmp b/shogibitmaps/sn58o.bmp new file mode 100644 index 0000000000000000000000000000000000000000..387e28f2ce29f6d0a873bcf3cce644f2ad716741 GIT binary patch literal 526 zcmbWzziPrz6bA65fo2PiI=Oc3T8cMx?>iKH38&n}v4f)pA&;V*wJ}(oxedG|>pz~P zU*E8W7Y|?R`SYq?hI_Sro_m>NT8Kwbs386%q?V~ll{aU(Sw<~yXqNYUzM(Q&`PgS_ z_^>oTnIdjkV((_nl{_hST5Jl}!q=OOCG6O}B(q|?znhOSC1V%tglLB$Pf4D_5vGo1yyZat>pUZ22NAM!$;%q$>{bO3ssi4AtUZ6`K(Gm(cR`-GPh3lIZA%U4*8>H-F8N2}Kl3$Y-tPm-+mV|9 literal 0 HcmV?d00001 diff --git a/shogibitmaps/sp58w.bmp b/shogibitmaps/sp58w.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2e623c8421c09ff6b78585e1d7669052c934a7e6 GIT binary patch literal 526 zcmZ?rh(X{0gaXnZfRfC3=pR6N zcAz}5^dF#lexQ0%>3=|d@<4sW(*J?#?SblvrW+U->OtyBr4KLw0}ZGToqoW;2p0bU e3_g(jAE38E^nakUz%+;r!k?iukOK3mN&^5u-!bU` literal 0 HcmV?d00001 diff --git a/shogibitmaps/sr58o.bmp b/shogibitmaps/sr58o.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6f6d142885283f3e76e53bfe8c5715d69016e960 GIT binary patch literal 526 zcmajaF-yZh6bJB&7TuaroZQ5{lOhIOocs`?q@y1|A(0M#tR5uLMW~K~P+c0GQn(>0 zz2^CU|I6U!k#|4xfA7NO@_M*qxGu1tpw9Y=OvL;Zl*3RA`b|U(N|z0Y_3XuV%b@n3zEaIO(_`eV=|Q6<5I`hrr?rr>{n E0UsWQJ^%m! literal 0 HcmV?d00001 diff --git a/shogibitmaps/sr58w.bmp b/shogibitmaps/sr58w.bmp new file mode 100644 index 0000000000000000000000000000000000000000..87469d3bac5edfd49949d114cc76267288a8d401 GIT binary patch literal 526 zcmb7=F%H5o3`G+d*xDm>?HL$aiJddS(LD43JpxCl#L}U{yzgcOrIEg0Vt+@8Z};Yu zVhzL|U5j$ck)OfT?21GQ?w*jA?Qq+o*8b!t>Ydfn!#~<#KGpazucgV)KWh2Hp79^$ mLf@IbTCVsn_%+xTY7nDnJXc(}PTVMqPC2N(^ezN({>v{)0OQ2~ literal 0 HcmV?d00001 diff --git a/shogibitmaps/ss58o.bmp b/shogibitmaps/ss58o.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e1aa7ad07a4d0fff6fac87215b4ba3d6e1371d12 GIT binary patch literal 526 zcma*jF%AJi6b9g-(NU|m)hdY?(L04>DAo-e!A+P#Xe8?fsFWmIAjbaw_ui^RnCzP` z`@fgj%?wBNs?*iy-ePsjsDS0fY2;W;60St8pi`Rxlr C1D&-1 literal 0 HcmV?d00001 diff --git a/shogibitmaps/su58o.bmp b/shogibitmaps/su58o.bmp new file mode 100644 index 0000000000000000000000000000000000000000..9bdce8585df0dc37888ae1e62fcf1d6dd4cf94ec GIT binary patch literal 526 zcmb`@K?=e!5Czay_dSPaaACl`XUfs)Lg+@&8&rtkvXLyhX!ZMNGAM`@7p6=e`ID9= z>rFK)bgVcpSWBz2C^bKlU6o4%n*bCn8QTnvY|d%VWcc8~yk|b`=yN|h@rDyRHJHs$ z-qE1tdoP2nuVysQUiQIXP=7U8KV|C#FZ-YNw&tfapRnaGN&nrBN0mJB5l0+UIG5e? L=9o)cCI9yU94D|} literal 0 HcmV?d00001 diff --git a/shogibitmaps/sw58o.bmp b/shogibitmaps/sw58o.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cb6029f1eeed53bec004a07d5781371a97047e4e GIT binary patch literal 526 zcmajcy-LGS6bJAd6^bA&?!_W5j=C9+Y73HKcq@alQ%1IMV+jW?ciMyFAx>dz`ZZ5`W#th*jemCZTbx^eA+>|{wZX%;T zruSU$ytM4<;dM4*!_ch7;8aZ@J{M|#(c!u%)9sqg0FjQb`klXOzeY1HXn&2pNNg{A z;{0YHCVhx`s&%!v;CkKMl`FPA*%x7s)JdQQ6LmRYTm0BqOu@qDuxykx^6q(*iwzYUv_nS`{#$=^T@-z1=XWAltrCjh=_)Gc5f5m^6 m8+|wWO8LQm$N!}k+>vV`zW0T1E8iF^8fB;M(wYf8|H~b~C;VXm literal 0 HcmV?d00001 diff --git a/winboard/winboard.c b/winboard/winboard.c index 7302223..a96aeb6 100644 --- a/winboard/winboard.c +++ b/winboard/winboard.c @@ -1168,7 +1168,7 @@ ArgDescriptor argDescriptors[] = { { "holdingsSize", ArgInt, (LPVOID) &appData.holdingsSize, TRUE }, { "matchPause", ArgInt, (LPVOID) &appData.matchPause, TRUE }, { "pieceToCharTable", ArgString, (LPVOID) &appData.pieceToCharTable, FALSE }, - { "flipBlack", ArgBoolean, (LPVOID) &appData.allWhite, TRUE }, + { "flipBlack", ArgBoolean, (LPVOID) &appData.upsideDown, TRUE }, { "allWhite", ArgBoolean, (LPVOID) &appData.allWhite, TRUE }, { "alphaRank", ArgBoolean, (LPVOID) &appData.alphaRank, FALSE }, { "testClaims", ArgBoolean, (LPVOID) &appData.testClaims, TRUE }, @@ -3171,6 +3171,60 @@ InitDrawingSizes(BoardSize boardSize, int flags) pieceBitmap[1][WhiteGrasshopper] = DoLoadBitmap(hInst, "q", minorSize, "o"); pieceBitmap[2][WhiteGrasshopper] = DoLoadBitmap(hInst, "q", minorSize, "w"); } + if(gameInfo.variant == VariantShogi && squareSize == 58) + /* special Shogi support in this size */ + { for (i=0; i<=2; i++) { /* replace all bitmaps */ + for (piece = WhitePawn; + (int) piece < (int) BlackPawn; + piece = (ChessSquare) ((int) piece + 1)) { + if (pieceBitmap[i][piece] != NULL) + DeleteObject(pieceBitmap[i][piece]); + } + } + pieceBitmap[0][WhitePawn] = DoLoadBitmap(hInst, "sp", squareSize, "o"); + pieceBitmap[0][WhiteKnight] = DoLoadBitmap(hInst, "sn", squareSize, "o"); + pieceBitmap[0][WhiteBishop] = DoLoadBitmap(hInst, "sb", squareSize, "o"); + pieceBitmap[0][WhiteRook] = DoLoadBitmap(hInst, "sr", squareSize, "o"); + pieceBitmap[0][WhiteQueen] = DoLoadBitmap(hInst, "sl", squareSize, "o"); + pieceBitmap[0][WhiteKing] = DoLoadBitmap(hInst, "sk", squareSize, "o"); + pieceBitmap[0][WhiteFerz] = DoLoadBitmap(hInst, "sf", squareSize, "o"); + pieceBitmap[0][WhiteWazir] = DoLoadBitmap(hInst, "sw", squareSize, "o"); + pieceBitmap[0][WhiteUnicorn] = DoLoadBitmap(hInst, "su", squareSize, "o"); + pieceBitmap[0][WhiteNightrider] = DoLoadBitmap(hInst, "sh", squareSize, "o"); + pieceBitmap[0][WhiteCardinal] = DoLoadBitmap(hInst, "sa", squareSize, "o"); + pieceBitmap[0][WhiteMarshall] = DoLoadBitmap(hInst, "sc", squareSize, "o"); + pieceBitmap[0][WhiteGrasshopper] = DoLoadBitmap(hInst, "sg", squareSize, "o"); + pieceBitmap[0][WhiteSilver] = DoLoadBitmap(hInst, "ss", squareSize, "o"); + pieceBitmap[1][WhitePawn] = DoLoadBitmap(hInst, "sp", squareSize, "o"); + pieceBitmap[1][WhiteKnight] = DoLoadBitmap(hInst, "sn", squareSize, "o"); + pieceBitmap[1][WhiteBishop] = DoLoadBitmap(hInst, "sb", squareSize, "o"); + pieceBitmap[1][WhiteRook] = DoLoadBitmap(hInst, "sr", squareSize, "o"); + pieceBitmap[1][WhiteQueen] = DoLoadBitmap(hInst, "sl", squareSize, "o"); + pieceBitmap[1][WhiteKing] = DoLoadBitmap(hInst, "sk", squareSize, "o"); + pieceBitmap[1][WhiteFerz] = DoLoadBitmap(hInst, "sf", squareSize, "o"); + pieceBitmap[1][WhiteWazir] = DoLoadBitmap(hInst, "sw", squareSize, "o"); + pieceBitmap[1][WhiteUnicorn] = DoLoadBitmap(hInst, "su", squareSize, "o"); + pieceBitmap[1][WhiteNightrider] = DoLoadBitmap(hInst, "sh", squareSize, "o"); + pieceBitmap[1][WhiteCardinal] = DoLoadBitmap(hInst, "sa", squareSize, "o"); + pieceBitmap[1][WhiteMarshall] = DoLoadBitmap(hInst, "sc", squareSize, "o"); + pieceBitmap[1][WhiteGrasshopper] = DoLoadBitmap(hInst, "sg", squareSize, "o"); + pieceBitmap[1][WhiteSilver] = DoLoadBitmap(hInst, "ss", squareSize, "o"); + pieceBitmap[2][WhitePawn] = DoLoadBitmap(hInst, "sp", squareSize, "w"); + pieceBitmap[2][WhiteKnight] = DoLoadBitmap(hInst, "sn", squareSize, "w"); + pieceBitmap[2][WhiteBishop] = DoLoadBitmap(hInst, "sr", squareSize, "w"); + pieceBitmap[2][WhiteRook] = DoLoadBitmap(hInst, "sr", squareSize, "w"); + pieceBitmap[2][WhiteQueen] = DoLoadBitmap(hInst, "sl", squareSize, "w"); + pieceBitmap[2][WhiteKing] = DoLoadBitmap(hInst, "sk", squareSize, "w"); + pieceBitmap[2][WhiteFerz] = DoLoadBitmap(hInst, "sw", squareSize, "w"); + pieceBitmap[2][WhiteWazir] = DoLoadBitmap(hInst, "sw", squareSize, "w"); + pieceBitmap[2][WhiteUnicorn] = DoLoadBitmap(hInst, "sp", squareSize, "w"); + pieceBitmap[2][WhiteNightrider] = DoLoadBitmap(hInst, "sn", squareSize, "w"); + pieceBitmap[2][WhiteCardinal] = DoLoadBitmap(hInst, "sr", squareSize, "w"); + pieceBitmap[2][WhiteMarshall] = DoLoadBitmap(hInst, "sr", squareSize, "w"); + pieceBitmap[2][WhiteGrasshopper] = DoLoadBitmap(hInst, "sl", squareSize, "w"); + pieceBitmap[2][WhiteSilver] = DoLoadBitmap(hInst, "sw", squareSize, "w"); + minorSize = 0; + } } HBITMAP @@ -3224,7 +3278,7 @@ DrawCoordsOnDC(HDC hdc) oldFont = SelectObject(hdc, font[boardSize][COORD_FONT]->hf); y = boardRect.top + lineGap; - x = boardRect.left + lineGap; + x = boardRect.left + lineGap + gameInfo.holdingsWidth*(squareSize + lineGap); SetTextAlign(hdc, TA_LEFT|TA_TOP); for (i = 0; i < BOARD_HEIGHT; i++) { @@ -3236,7 +3290,7 @@ DrawCoordsOnDC(HDC hdc) start = flipView ? 12-BOARD_WIDTH : 12; SetTextAlign(hdc, TA_RIGHT|TA_BOTTOM); - for (i = 0; i < BOARD_WIDTH; i++) { + for (i = 0; i < BOARD_RGHT - BOARD_LEFT; i++) { str[0] = ranks[start + i]; ExtTextOut(hdc, x + squareSize - 2, y - 1, 0, NULL, str, 1, NULL); x += squareSize + lineGap; @@ -3375,7 +3429,7 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, oldBrush = SelectObject(hdc, whitePieceBrush); else oldBrush = SelectObject(hdc, blackPieceBrush); if(appData.upsideDown && !color) - StretchBlt(hdc, x, y+tmpSize, tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, 0x00B8074A); + StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, 0x00B8074A); else BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A); #if 0 @@ -3389,7 +3443,7 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, /* Use black for outline of white pieces */ SelectObject(tmphdc, PieceBitmap(piece, OUTLINE_PIECE)); if(appData.upsideDown && !color) - StretchBlt(hdc, x, y+tmpSize, tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, SRCAND); + StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, SRCAND); else BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, SRCAND); #endif @@ -3411,7 +3465,7 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, SOLID_PIECE)); oldBrush = SelectObject(hdc, blackPieceBrush); if(appData.upsideDown) - StretchBlt(hdc, x, y+tmpSize, tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, 0x00B8074A); + StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, 0x00B8074A); else BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A); #endif @@ -4443,10 +4497,14 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) DrawPosition(forceFullRepaint || FALSE, NULL); } } + break; + } + if (gotPremove) { + /* [HGM] it seemed that braces were missing here */ + SetPremoveHighlights(fromX, fromY, toX, toY); + fromX = fromY = -1; + break; } - if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY); - fromX = fromY = -1; - break; } ClearHighlights(); DrawPosition(forceFullRepaint || FALSE, NULL); @@ -4472,6 +4530,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ReleaseCapture(); if (fromX == -1) break; if (x == fromX && y == fromY) { + dragInfo.from.x = dragInfo.from.y = -1; /* Upclick on same square */ if (sameAgain) { /* Clicked same square twice: abort click-click move */ @@ -4482,7 +4541,6 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* First square clicked: start click-click move */ SetHighlights(fromX, fromY, -1, -1); } - dragInfo.from.x = dragInfo.from.y = -1; DrawPosition(forceFullRepaint || FALSE, NULL); } else if (dragInfo.from.x < 0 || dragInfo.from.y < 0) { /* Errant click; ignore */ @@ -4704,12 +4762,16 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) SW_SHOW : SW_HIDE); /* [HGM] Only allow C & A promotions if these pieces are defined */ ShowWindow(GetDlgItem(hDlg, PB_Archbishop), - (PieceToChar(WhiteCardinal) != '.' || - PieceToChar(BlackCardinal) != '.' ) ? + (PieceToChar(WhiteCardinal) >= 'A' && + PieceToChar(WhiteCardinal) != '~' || + PieceToChar(BlackCardinal) >= 'A' && + PieceToChar(BlackCardinal) != '~' ) ? SW_SHOW : SW_HIDE); ShowWindow(GetDlgItem(hDlg, PB_Chancellor), - (PieceToChar(WhiteMarshall) != '.' || - PieceToChar(BlackMarshall) != '.' ) ? + (PieceToChar(WhiteMarshall) >= 'A' && + PieceToChar(WhiteMarshall) != '~' || + PieceToChar(BlackMarshall) >= 'A' && + PieceToChar(BlackMarshall) != '~' ) ? SW_SHOW : SW_HIDE); /* [HGM] Hide B & R button in Shogi, use Q as promote, N as defer */ ShowWindow(GetDlgItem(hDlg, PB_Rook), diff --git a/winboard/winboard.rc b/winboard/winboard.rc index baf18bd..6682aab 100644 --- a/winboard/winboard.rc +++ b/winboard/winboard.rc @@ -1067,7 +1067,7 @@ BEGIN POPUP "&Options" BEGIN MENUITEM "Flip &View\tF2", IDM_FlipView - MENUITEM "Flip &Clocks", IDM_FlipClock + MENUITEM "Swap &Clocks", IDM_FlipClock MENUITEM SEPARATOR MENUITEM "&General...", IDM_GeneralOptions MENUITEM "&Board...", IDM_BoardOptions @@ -1744,6 +1744,27 @@ G49W BITMAP MOVEABLE PURE "bitmaps\\g49w.bmp" L49W BITMAP MOVEABLE PURE "bitmaps\\l49w.bmp" DK49W BITMAP MOVEABLE PURE "bitmaps\\dk49w.bmp" +SP58O BITMAP MOVEABLE PURE "shogibitmaps\\sp58o.bmp" +SN58O BITMAP MOVEABLE PURE "shogibitmaps\\sn58o.bmp" +SB58O BITMAP MOVEABLE PURE "shogibitmaps\\sb58o.bmp" +SR58O BITMAP MOVEABLE PURE "shogibitmaps\\sr58o.bmp" +SL58O BITMAP MOVEABLE PURE "shogibitmaps\\sl58o.bmp" +SK58O BITMAP MOVEABLE PURE "shogibitmaps\\sk58o.bmp" +SF58O BITMAP MOVEABLE PURE "shogibitmaps\\sf58o.bmp" +SW58O BITMAP MOVEABLE PURE "shogibitmaps\\sw58o.bmp" +SU58O BITMAP MOVEABLE PURE "shogibitmaps\\su58o.bmp" +SH58O BITMAP MOVEABLE PURE "shogibitmaps\\sh58o.bmp" +SA58O BITMAP MOVEABLE PURE "shogibitmaps\\sa58o.bmp" +SC58O BITMAP MOVEABLE PURE "shogibitmaps\\sc58o.bmp" +SG58O BITMAP MOVEABLE PURE "shogibitmaps\\sg58o.bmp" +SS58O BITMAP MOVEABLE PURE "shogibitmaps\\ss58o.bmp" +SP58W BITMAP MOVEABLE PURE "shogibitmaps\\sp58w.bmp" +SN58W BITMAP MOVEABLE PURE "shogibitmaps\\sn58w.bmp" +SR58W BITMAP MOVEABLE PURE "shogibitmaps\\sr58w.bmp" +SL58W BITMAP MOVEABLE PURE "shogibitmaps\\sl58w.bmp" +SK58W BITMAP MOVEABLE PURE "shogibitmaps\\sk58w.bmp" +SW58W BITMAP MOVEABLE PURE "shogibitmaps\\sw58w.bmp" + #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// diff --git a/winboard/woptions.c b/winboard/woptions.c index 4f91822..df3c699 100644 --- a/winboard/woptions.c +++ b/winboard/woptions.c @@ -707,7 +707,11 @@ BoardOptionsDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) hsc = ParseColorName(HIGHLIGHT_SQUARE_COLOR); phc = ParseColorName(PREMOVE_HIGHLIGHT_COLOR); mono = FALSE; + white= FALSE; + flip = FALSE; CheckDlgButton(hDlg, OPT_Monochrome, FALSE); + CheckDlgButton(hDlg, OPT_AllWhite, FALSE); + CheckDlgButton(hDlg, OPT_UpsideDown, FALSE); PaintColorBlock(hDlg, OPT_LightSquareColor, lsc); PaintColorBlock(hDlg, OPT_DarkSquareColor, dsc); PaintColorBlock(hDlg, OPT_WhitePieceColor, wpc); -- 1.7.0.4