X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=e314d4237858347838c92b2b8a960d84984a1705;hb=c082824a507c0fb577beb908ed5615a161c6c6fa;hp=b1d35a9cb92eda05831ba54bdbdef4a4dd9a4c28;hpb=95772c234f0afaf88ef01854868c93ff2e8a20fb;p=xboard.git diff --git a/backend.c b/backend.c index b1d35a9..e314d42 100644 --- a/backend.c +++ b/backend.c @@ -5426,6 +5426,9 @@ LoadMultiPV (int x, int y, char *buf, int index, int *start, int *end) first.option[multi].value = n; *start = *end = 0; return FALSE; + } else if(strstr(buf+lineStart, "exclude:") == buf+lineStart) { // exclude moves clicked + DisplayNote("Yes!"); + return; } ParsePV(buf+startPV, FALSE, gameMode != AnalyzeMode); *start = startPV; *end = index-1; @@ -6104,6 +6107,45 @@ SendBoard (ChessProgramState *cps, int moveNum) setboardSpoiledMachineBlack = 0; /* [HGM] assume WB 4.2.7 already solves this after sending setboard */ } +char exclusionHeader[MSG_SIZ]; +int exCnt, excludePtr, mappedMove = -1; +typedef struct { int ff, fr, tf, tr, pc, mark; } Exclusion; +static Exclusion excluTab[200]; +static char excludeMap[(BOARD_RANKS*BOARD_FILES*BOARD_RANKS*BOARD_FILES+7)/8]; // [HGM] exclude: bitmap for excluced moves + +void +ClearMap () +{ + int j; + mappedMove = -1; + for(j=0; j<(BOARD_RANKS*BOARD_FILES*BOARD_RANKS*BOARD_FILES+7)/8; j++) excludeMap[j] = 0; + safeStrCpy(exclusionHeader, "exclude: none best tail \n", MSG_SIZ); + excludePtr = 24; exCnt = 0; +} + +void +UpdateExcludeHeader (int fromY, int fromX, int toY, int toX, char promoChar, int incl) +{ + char buf[2*MOVE_LEN], *p, c = incl ? '+' : '-'; + Exclusion *e = excluTab; + int i; + for(i=0; i>= 3; + snprintf(buf, MSG_SIZ, "%sclude ", excludeMap[i] & 1<= 200) fromX = fromY = -1; // second click on piece after altering default promo piece treated as first click if(!promoDefaultAltered) { // determine default promotion piece, based on the side the user is moving for @@ -6914,6 +6992,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) } return; } + doubleClick = FALSE; fromX = x; fromY = y; toX = toY = -1; if(!appData.oneClick || !OnlyMove(&x, &y, FALSE) || // even if only move, we treat as normal when this would trigger a promotion popup, to allow sweep selection @@ -6960,6 +7039,10 @@ LeftClick (ClickType clickType, int xPix, int yPix) !(fromP == BlackKing && toP == BlackRook && frc))) { /* Clicked again on same color piece -- changed his mind */ second = (x == fromX && y == fromY); + if(second && gameMode == AnalyzeMode && SubtractTimeMarks(&lastClickTime, &prevClickTime) < 200) { + second = FALSE; // first double-click rather than scond click + doubleClick = first.excludeMoves; // used by UserMoveEvent to recognize exclude moves + } promoDefaultAltered = FALSE; MarkTargetSquares(1); if(!second || appData.oneClick && !OnlyMove(&x, &y, TRUE)) { @@ -6973,7 +7056,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) (fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) && y == (toP < BlackPawn ? 0 : BOARD_HEIGHT-1)) gatingPiece = boards[currentMove][fromY][fromX]; - else gatingPiece = EmptySquare; + else gatingPiece = doubleClick ? fromP : EmptySquare; fromX = x; fromY = y; dragging = 1; MarkTargetSquares(0); @@ -7095,7 +7178,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) // off-board moves should not be highlighted if(x < 0 || y < 0) ClearHighlights(); - if(gatingPiece != EmptySquare) promoChoice = ToLower(PieceToChar(gatingPiece)); + if(gatingPiece != EmptySquare && gameInfo.variant == VariantSChess) promoChoice = ToLower(PieceToChar(gatingPiece)); if (HasPromotionChoice(fromX, fromY, toX, toY, &promoChoice, appData.sweepSelect)) { SetHighlights(fromX, fromY, toX, toY); @@ -8378,6 +8461,9 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats. _(cps->which), cps->program, cps->host, message); RemoveInputSource(cps->isr); if(appData.icsActive) DisplayFatalError(buf1, 0, 1); else { + cps->isr = NULL; + DestroyChildProcess(cps->pr, 9 ); // just to be sure + cps->pr = NoProc; if(cps == &first) { appData.noChessProgram = TRUE; gameMode = MachinePlaysBlack; ModeHighlight(); // kludge to unmark Machine Black menu @@ -10711,6 +10797,7 @@ Reset (int redraw, int init) DisplayMessage("", ""); HistorySet(parseList, backwardMostMove, forwardMostMove, currentMove-1); lastSavedGame = 0; // [HGM] save: make sure next game counts as unsaved + ClearMap(); // [HGM] exclude: invalidate map } void @@ -13694,7 +13781,7 @@ EditPositionEvent () currentMove = forwardMostMove = backwardMostMove = 0; HistorySet(parseList, backwardMostMove, forwardMostMove, currentMove-1); DisplayMove(-1); - if(!appData.pieceMenu) DisplayMessage("Click clock to clear board", ""); + if(!appData.pieceMenu) DisplayMessage(_("Click clock to clear board"), ""); } void @@ -14301,6 +14388,7 @@ ForwardInner (int target) if ( !matchMode && gameMode != Training) { // [HGM] PV info: routine tests if empty DisplayComment(currentMove - 1, commentList[currentMove]); } + ClearMap(); // [HGM] exclude: invalidate map } @@ -14414,6 +14502,7 @@ BackwardInner (int target) HistorySet(parseList,backwardMostMove,forwardMostMove,currentMove-1); // [HGM] PV info: routine tests if comment empty DisplayComment(currentMove - 1, commentList[currentMove]); + ClearMap(); // [HGM] exclude: invalidate map } void @@ -15480,6 +15569,7 @@ ParseFeatures (char *args, ChessProgramState *cps) if (BoolFeature(&p, "playother", &cps->usePlayother, cps)) continue; if (BoolFeature(&p, "colors", &cps->useColors, cps)) continue; if (BoolFeature(&p, "usermove", &cps->useUsermove, cps)) continue; + if (BoolFeature(&p, "exclude", &cps->excludeMoves, cps)) continue; if (BoolFeature(&p, "ics", &cps->sendICS, cps)) continue; if (BoolFeature(&p, "name", &cps->sendName, cps)) continue; if (BoolFeature(&p, "pause", &val, cps)) continue; /* unused at present */