From e8ee92700cdae0637fdce80b013bd76aba7a730d Mon Sep 17 00:00:00 2001 From: H.G. Muller Date: Wed, 3 Jul 2013 15:28:38 +0200 Subject: [PATCH] Implement board-marker protocol The commands 'lift SQ' and 'put SQ' are sent to the engine to indicate the user selects or puts down pieces, so the engine can respond with 'highlight FEN' to put markers on the board. This implements an externally driven -showTargetSquares feature. The engine has to enable this by 'feature highight=1' The highlight command is further ignored when native showTargetSquares is on. A comma suffix on the square is used to indicate the user kept Ctrl down during the to-square event reported by the put command. --- backend.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++------ backend.h | 1 + 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/backend.c b/backend.c index 12c847d..15c3e42 100644 --- a/backend.c +++ b/backend.c @@ -825,6 +825,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) @@ -7014,6 +7015,29 @@ 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 BOARD_LEFT) f = BOARD_LEFT, r--; else + if(*fen == 'Y') marker[r][f++] = 1; 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]; @@ -7028,13 +7052,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++; @@ -7076,6 +7101,14 @@ CanPromote (ChessSquare piece, int y) piece == WhiteLance && y == BOARD_HEIGHT-2 ); } +void ReportClick(char *action, int x, int y) +{ + char buf[MSG_SIZ]; // Inform engine of what user does + if(!first.highlight || gameMode == EditPosition) return; + snprintf(buf, MSG_SIZ, "%s %c%d%s\n", action, x+AAA, y+ONE-'0', controlKey && action[0]=='p' ? "," : ""); + SendToProgram(buf, &first); +} + void LeftClick (ClickType clickType, int xPix, int yPix) { @@ -7175,6 +7208,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) /* First square */ if (OKToStartUserMove(fromX, fromY)) { second = 0; + ReportClick("lift", x, y); MarkTargetSquares(0); if(gameMode == EditPosition && controlKey) gatingPiece = boards[currentMove][fromY][fromX]; DragPieceBegin(xPix, yPix, FALSE); dragging = 1; @@ -7237,6 +7271,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) else gatingPiece = doubleClick ? fromP : EmptySquare; fromX = x; fromY = y; dragging = 1; + ReportClick("lift", x, y); MarkTargetSquares(0); DragPieceBegin(xPix, yPix, FALSE); if(appData.sweepSelect && CanPromote(piece = boards[currentMove][y][x], y)) { @@ -7365,6 +7400,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)); @@ -8581,6 +8617,11 @@ 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 the move is illegal, cancel it and redraw the board. * Also deal with other error cases. Matching is rather loose @@ -16177,6 +16218,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; diff --git a/backend.h b/backend.h index 201d5b4..edb615c 100644 --- a/backend.h +++ b/backend.h @@ -399,6 +399,7 @@ typedef struct XB_CPS { char *egtFormats; /* [HGM] EGT: supported tablebase formats */ int bookSuspend; /* [HGM] book: go was deferred because of book hit */ int pause; /* [HGM] pause: 1=supports it, 2=actually paused */ + int highlight; /* [HGM] engine wants to get lift and put commands */ int nrOptions; /* [HGM] options: remembered option="..." features */ #define MAX_OPTIONS 200 Option option[MAX_OPTIONS]; -- 1.7.0.4