X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=94d715d06b6c41cac3ad6254ca95f7d7b01ac358;hb=988cc3c7cdc6ad6f0441e6dfa93881fae2119caa;hp=f6bbefb3e996470b203eaa20377c8764fde8a214;hpb=5ec02fef40c35757bf05a91600ada714f0fb799b;p=xboard.git diff --git a/backend.c b/backend.c index f6bbefb..94d715d 100644 --- a/backend.c +++ b/backend.c @@ -269,6 +269,7 @@ char chatPartner[MAX_CHAT][MSG_SIZ]; /* [HGM] chat: list of chatting partners */ extern int chatCount; int chattingPartner; char marker[BOARD_RANKS][BOARD_FILES]; /* [HGM] marks for target squares */ +char legal[BOARD_RANKS][BOARD_FILES]; /* [HGM] legal target squares */ char lastMsg[MSG_SIZ]; ChessSquare pieceSweep = EmptySquare; ChessSquare promoSweep = EmptySquare, defaultPromoChoice; @@ -825,6 +826,7 @@ InitEngine (ChessProgramState *cps, int n) cps->scoreIsAbsolute = appData.scoreIsAbsolute[n]; /* [AS] */ cps->isUCI = appData.isUCI[n]; /* [AS] */ cps->hasOwnBookUCI = appData.hasOwnBookUCI[n]; /* [AS] */ + cps->highlight = 0; if (appData.protocolVersion[n] > PROTOVER || appData.protocolVersion[n] < 1) @@ -5237,7 +5239,8 @@ ProcessICSInitScript (FILE *f) } -static int lastX, lastY, selectFlag, dragging; +static int lastX, lastY, lastLeftX, lastLeftY, selectFlag, dragging; +static ClickType lastClickType; void Sweep (int step) @@ -5909,13 +5912,11 @@ InitPosition (int redraw) case VariantMakruk: pieces = makrukArray; nrCastlingRights = 0; - startedFromSetupPosition = TRUE; SetCharTable(pieceToChar, "PN.R.M....SKpn.r.m....sk"); break; case VariantASEAN: pieces = aseanArray; nrCastlingRights = 0; - startedFromSetupPosition = TRUE; SetCharTable(pieceToChar, "PN.R.Q....BKpn.r.q....bk"); break; case VariantTwoKings: @@ -7016,6 +7017,39 @@ FinishMove (ChessMove moveType, int fromX, int fromY, int toX, int toY, int prom } void +MarkByFEN(char *fen) +{ + int r, f; + if(!appData.markers || !appData.highlightDragging) return; + for(r=0; r= 'A' && *fen <= 'Z') legal[r][f] = 1; else + if(*fen >= 'a' && *fen <= 'z') *fen += 'A' - 'a'; + if(*fen == '/' && f > BOARD_LEFT) f = BOARD_LEFT, r--; else + if(*fen == 'T') marker[r][f++] = 0; else + if(*fen == 'Y') marker[r][f++] = 1; else + if(*fen == 'G') marker[r][f++] = 3; else + if(*fen == 'B') marker[r][f++] = 4; else + if(*fen == 'C') marker[r][f++] = 5; else + if(*fen == 'M') marker[r][f++] = 6; else + if(*fen == 'W') marker[r][f++] = 7; else + if(*fen == 'D') marker[r][f++] = 8; else + if(*fen == 'R') marker[r][f++] = 2; else { + while(*fen <= '9' && *fen >= '0') s = 10*s + *fen++ - '0'; + f += s; fen -= s>0; + } + while(f >= BOARD_RGHT) f -= BOARD_RGHT - BOARD_LEFT, r--; + if(r < 0) break; + fen++; + } + DrawPosition(TRUE, NULL); +} + +void Mark (Board board, int flags, ChessMove kind, int rf, int ff, int rt, int ft, VOIDSTAR closure) { typedef char Markers[BOARD_RANKS][BOARD_FILES]; @@ -7030,13 +7064,14 @@ Mark (Board board, int flags, ChessMove kind, int rf, int ff, int rt, int ft, VO void MarkTargetSquares (int clear) { - int x, y; - if(clear) // no reason to ever suppress clearing - for(x=0; x1) capt++; @@ -7079,6 +7114,39 @@ CanPromote (ChessSquare piece, int y) } void +HoverEvent (int hiX, int hiY, int x, int y) +{ + static char baseMarker[BOARD_RANKS][BOARD_FILES], baseLegal[BOARD_RANKS][BOARD_FILES]; + int r, f; + if(!first.highlight) return; + if(hiX == -1 && hiY == -1 && x == fromX && y == fromY) // record markings + for(r=0; r= BOARD_LEFT && x < BOARD_RGHT) clearFlag = 1; // and defer click-click move of empty-square to up-click return; } - if(HasPromotionChoice(fromX, fromY, toX, toY, &promoChoice, FALSE)) { + if(legal[y][x] == 2 || HasPromotionChoice(fromX, fromY, toX, toY, &promoChoice, FALSE)) { if(appData.sweepSelect) { ChessSquare piece = boards[currentMove][fromY][fromX]; promoSweep = defaultPromoChoice; @@ -7366,6 +7445,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) // off-board moves should not be highlighted if(x < 0 || y < 0) ClearHighlights(); + else ReportClick("put", x, y); if(gatingPiece != EmptySquare && gameInfo.variant == VariantSChess) promoChoice = ToLower(PieceToChar(gatingPiece)); @@ -8031,6 +8111,7 @@ SendMoveToBookUser (int moveNr, ChessProgramState *cps, int initial) SendToProgram("force\n", cps); cps->bookSuspend = TRUE; // flag indicating it has to be restarted } + if(bookHit) setboardSpoiledMachineBlack = FALSE; // suppress 'go' in SendMoveToProgram if(!initial) SendMoveToProgram(moveNr, cps); // with hit on initial position there is no move // now arrange restart after book miss if(bookHit) { @@ -8307,6 +8388,17 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h MakeMove(fromX, fromY, toX, toY, promoChar);/*updates forwardMostMove*/ + /* Test suites abort the 'game' after one move */ + if(*appData.finger) { + static FILE *f; + char *fen = PositionToFEN(backwardMostMove, NULL, 0); // no counts in EPD + if(!f) f = fopen(appData.finger, "w"); + if(f) fprintf(f, "%s bm %s;\n", fen, parseList[backwardMostMove]), fflush(f); + else { DisplayFatalError("Bad output file", errno, 0); return; } + free(fen); + GameEnds(GameUnfinished, NULL, GE_XBOARD); + } + /* [AS] Adjudicate game if needed (note: remember that forwardMostMove now points past the last move) */ if( gameMode == TwoMachinesPlay && adjudicateLossThreshold != 0 && forwardMostMove >= adjudicateLossPlies ) { int count = 0; @@ -8570,6 +8662,28 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats. if (sscanf(message, "pong %d", &cps->lastPong) == 1) { return; } + if(!strncmp(message, "highlight ", 10)) { + if(appData.testLegality && appData.markers) return; + MarkByFEN(message+10); // [HGM] alien: allow engine to mark board squares + return; + } + if(!strncmp(message, "click ", 6)) { + char f, c=0; int x, y; // [HGM] alien: allow engine to finish user moves (i.e. engine-driven one-click moving) + if(appData.testLegality || !appData.oneClick) return; + sscanf(message+6, "%c%d%c", &f, &y, &c); + x = f - 'a' + BOARD_LEFT, y -= ONE - '0'; + if(flipView) x = BOARD_WIDTH-1 - x; else y = BOARD_HEIGHT-1 - y; + x = x*squareSize + (x+1)*lineGap + squareSize/2; + y = y*squareSize + (y+1)*lineGap + squareSize/2; + f = first.highlight; first.highlight = 0; // kludge to suppress lift/put in response to own clicks + if(lastClickType == Press) // if button still down, fake release on same square, to be ready for next click + LeftClick(Release, lastLeftX, lastLeftY); + controlKey = (c == ','); + LeftClick(Press, x, y); + LeftClick(Release, x, y); + first.highlight = f; + return; + } /* * If the move is illegal, cancel it and redraw the board. * Also deal with other error cases. Matching is rather loose @@ -10852,6 +10966,7 @@ GameEnds (ChessMove result, char *resultDetails, int whosays) PlayIcsUnfinishedSound(); } } + if(appData.quitNext) { ExitEvent(0); return; } } else if (gameMode == EditGame || gameMode == PlayFromGameFile || gameMode == AnalyzeMode || @@ -15243,7 +15358,7 @@ void CreateBookEvent () { ListGame * lg = (ListGame *) gameList.head; - FILE *f; + FILE *f, *g; int nItem; static int secondTime = FALSE; @@ -15252,8 +15367,8 @@ CreateBookEvent () return; } - if(!secondTime && (f = fopen(appData.polyglotBook, "r"))) { - fclose(f); + if(!secondTime && (g = fopen(appData.polyglotBook, "r"))) { + fclose(g); secondTime++; DisplayNote(_("Book file exists! Try again for overwrite.")); return; @@ -16165,6 +16280,7 @@ ParseFeatures (char *args, ChessProgramState *cps) /* End of additions by Tord */ /* [HGM] added features: */ + if (BoolFeature(&p, "highlight", &cps->highlight, cps)) continue; if (BoolFeature(&p, "debug", &cps->debug, cps)) continue; if (BoolFeature(&p, "nps", &cps->supportsNPS, cps)) continue; if (IntFeature(&p, "level", &cps->maxNrOfSessions, cps)) continue;