X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=b8ebf8fcad7048d5977cf23eee7090174e5dab12;hb=d0dd56ea50571359ce9cf8d368aff29e5d5b25c5;hp=0c555f983768d3e3907ac9a2b6ec019fea73c86a;hpb=b41c7cb49ab2482d484a87d18a330f10db4e5cb4;p=xboard.git diff --git a/backend.c b/backend.c index 0c555f9..b8ebf8f 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; @@ -388,6 +389,7 @@ PosFlags (index) case VariantShatranj: case VariantCourier: case VariantMakruk: + case VariantASEAN: case VariantGrand: flags &= ~F_ALL_CASTLE_OK; break; @@ -557,6 +559,13 @@ ChessSquare makrukArray[2][BOARD_FILES] = { /* [HGM] (movGen knows about Shatran BlackKing, BlackMan, BlackKnight, BlackRook } }; +ChessSquare aseanArray[2][BOARD_FILES] = { /* [HGM] (movGen knows about Shatranj Q and P) */ + { WhiteRook, WhiteKnight, WhiteMan, WhiteFerz, + WhiteKing, WhiteMan, WhiteKnight, WhiteRook }, + { BlackRook, BlackKnight, BlackMan, BlackFerz, + BlackKing, BlackMan, BlackKnight, BlackRook } +}; + #if (BOARD_FILES>=10) ChessSquare ShogiArray[2][BOARD_FILES] = { @@ -817,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) @@ -1158,6 +1168,7 @@ InitBackEnd1 () case Variant3Check: /* should work except for win condition */ case VariantShatranj: /* should work except for all win conditions */ case VariantMakruk: /* should work except for draw countdown */ + case VariantASEAN : /* should work except for draw countdown */ case VariantBerolina: /* might work if TestLegality is off */ case VariantCapaRandom: /* should work */ case VariantJanus: /* should work */ @@ -5090,7 +5101,8 @@ SendMoveToICS (ChessMove moveType, int fromX, int fromY, int toX, int toY, char break; case WhitePromotion: case BlackPromotion: - if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || gameInfo.variant == VariantMakruk) + if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || + gameInfo.variant == VariantMakruk || gameInfo.variant == VariantASEAN) snprintf(user_move, MSG_SIZ, "%c%c%c%c=%c\n", AAA + fromX, ONE + fromY, AAA + toX, ONE + toY, PieceToChar(WhiteFerz)); @@ -5154,7 +5166,7 @@ UploadGameEvent () SendToICS(ics_prefix); SendToICS(buf); if(startedFromSetupPosition || backwardMostMove != 0) { - fen = PositionToFEN(backwardMostMove, NULL); + fen = PositionToFEN(backwardMostMove, NULL, 1); if(ics_type == ICS_ICC) { // on ICC we can simply send a complete FEN to set everything snprintf(buf, MSG_SIZ,"loadfen %s\n", fen); SendToICS(buf); @@ -5899,9 +5911,13 @@ 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; + SetCharTable(pieceToChar, "PN.R.Q....BKpn.r.q....bk"); + break; case VariantTwoKings: pieces = twoKingsArray; break; @@ -6030,7 +6046,7 @@ InitPosition (int redraw) pawnRow = gameInfo.boardHeight - 7; /* seems to work in all common variants */ if(pawnRow < 1) pawnRow = 1; - if(gameInfo.variant == VariantMakruk || gameInfo.variant == VariantGrand) pawnRow = 2; + if(gameInfo.variant == VariantMakruk || gameInfo.variant == VariantASEAN || gameInfo.variant == VariantGrand) pawnRow = 2; /* User pieceToChar list overrules defaults */ if(appData.pieceToCharTable != NULL) @@ -6139,7 +6155,7 @@ SendBoard (ChessProgramState *cps, int moveNum) char message[MSG_SIZ]; if (cps->useSetboard) { - char* fen = PositionToFEN(moveNum, cps->fenOverride); + char* fen = PositionToFEN(moveNum, cps->fenOverride, 1); snprintf(message, MSG_SIZ,"setboard %s\n", fen); SendToProgram(message, cps); free(fen); @@ -6322,7 +6338,8 @@ ChessSquare DefaultPromoChoice (int white) { ChessSquare result; - if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || gameInfo.variant == VariantMakruk) + if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || + gameInfo.variant == VariantMakruk || gameInfo.variant == VariantASEAN) result = WhiteFerz; // no choice else if(gameInfo.variant == VariantSuicide || gameInfo.variant == VariantGiveaway) result= WhiteKing; // in Suicide Q is the last thing we want @@ -6407,7 +6424,8 @@ HasPromotionChoice (int fromX, int fromY, int toX, int toY, char *promoChoice, i } // we either have a choice what to promote to, or (in Shogi) whether to promote - if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || gameInfo.variant == VariantMakruk) { + if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || + gameInfo.variant == VariantMakruk || gameInfo.variant == VariantASEAN) { *promoChoice = PieceToChar(BlackFerz); // no choice return FALSE; } @@ -6998,6 +7016,32 @@ 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 == '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]; @@ -7012,13 +7056,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++; @@ -7053,13 +7098,24 @@ CanPromote (ChessSquare piece, int y) if(gameInfo.variant == VariantShogi || gameInfo.variant == VariantXiangqi || gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat || gameInfo.variant == VariantShatranj || gameInfo.variant == VariantCourier || - gameInfo.variant == VariantMakruk) return FALSE; + gameInfo.variant == VariantMakruk || gameInfo.variant == VariantASEAN) return FALSE; return (piece == BlackPawn && y == 1 || piece == WhitePawn && y == BOARD_HEIGHT-2 || piece == BlackLance && y == 1 || piece == WhiteLance && y == BOARD_HEIGHT-2 ); } +void ReportClick(char *action, int x, int y) +{ + char buf[MSG_SIZ]; // Inform engine of what user does + int r, f; + if(action[0] == 'l') // mark any target square of a lifted piece as legal to-square + for(r=0; rbookSuspend = 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) { @@ -8289,6 +8357,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; @@ -8436,6 +8515,7 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats. if(appData.icsActive || forwardMostMove != 0 || cps != &first) return; if(sscanf(message, "setup (%s", buf) == 1) s = 8 + strlen(buf), buf[s-9] = NULLCHAR, SetCharTable(pieceToChar, buf); if(startedFromSetupPosition) return; + if(sscanf(message+s, "%dx%d+%d", &dummy, &dummy, &dummy) == 3) while(message[s] && message[s++] != ' '); // for compatibility with Alien Edition ParseFEN(boards[0], &dummy, message+s); DrawPosition(TRUE, boards[0]); startedFromSetupPosition = TRUE; @@ -8551,6 +8631,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 @@ -10132,7 +10217,7 @@ WriteTourneyFile (char *results, FILE *f) fprintf(f, "-loadPositionIndex %d\n", appData.loadPositionIndex); fprintf(f, "-rewindIndex %d\n", appData.rewindIndex); fprintf(f, "-usePolyglotBook %s\n", appData.usePolyglotBook ? "true" : "false"); - fprintf(f, "-polyglotBook %s\n", appData.polyglotBook); + fprintf(f, "-polyglotBook \"%s\"\n", appData.polyglotBook); fprintf(f, "-bookDepth %d\n", appData.bookDepth); fprintf(f, "-bookVariation %d\n", appData.bookStrength); fprintf(f, "-discourageOwnBooks %s\n", appData.defNoBook ? "true" : "false"); @@ -10833,6 +10918,7 @@ GameEnds (ChessMove result, char *resultDetails, int whosays) PlayIcsUnfinishedSound(); } } + if(appData.quitNext) { ExitEvent(0); return; } } else if (gameMode == EditGame || gameMode == PlayFromGameFile || gameMode == AnalyzeMode || @@ -11183,17 +11269,23 @@ AutoPlayOneMove () if (gameMode != PlayFromGameFile && gameMode != AnalyzeFile) return FALSE; - if (gameMode == AnalyzeFile && currentMove > backwardMostMove) { + if (gameMode == AnalyzeFile && currentMove > backwardMostMove && programStats.depth) { pvInfoList[currentMove].depth = programStats.depth; pvInfoList[currentMove].score = programStats.score; pvInfoList[currentMove].time = 0; if(currentMove < forwardMostMove) AppendComment(currentMove+1, lastPV[0], 2); + else { // append analysis of final position as comment + char buf[MSG_SIZ]; + snprintf(buf, MSG_SIZ, "{final score %+4.2f/%d}", programStats.score/100., programStats.depth); + AppendComment(currentMove, buf, 3); // the 3 prevents stripping of the score/depth! + } + programStats.depth = 0; } if (currentMove >= forwardMostMove) { if(gameMode == AnalyzeFile) { if(appData.loadGameIndex == -1) { - GameEnds(EndOfFile, NULL, GE_FILE); + GameEnds(gameInfo.result, gameInfo.resultDetails ? gameInfo.resultDetails : "", GE_FILE); ScheduleDelayedEvent(AnalyzeNextGame, 10); } else { ExitAnalyzeMode(); SendToProgram("force\n", &first); @@ -12439,10 +12531,12 @@ LoadGame (FILE *f, int gameNumber, char *title, int useList) HistorySet(parseList, backwardMostMove, forwardMostMove, currentMove-1); - if (oldGameMode == AnalyzeFile || - oldGameMode == AnalyzeMode) { + if (oldGameMode == AnalyzeFile) { appData.loadGameIndex = -1; // [HGM] order auto-stepping through games AnalyzeFileEvent(); + } else + if (oldGameMode == AnalyzeMode) { + AnalyzeFileEvent(); } if(creatingBook) return TRUE; @@ -12809,7 +12903,7 @@ SaveGamePGN (FILE *f) if(appData.numberTag && matchMode) fprintf(f, "[Number \"%d\"]\n", nextGame+1); // [HGM] number tag if (backwardMostMove > 0 || startedFromSetupPosition) { - char *fen = PositionToFEN(backwardMostMove, NULL); + char *fen = PositionToFEN(backwardMostMove, NULL, 1); fprintf(f, "[FEN \"%s\"]\n[SetUp \"1\"]\n", fen); fprintf(f, "\n{--------------\n"); PrintPosition(f, backwardMostMove); @@ -13078,7 +13172,7 @@ SavePosition (FILE *f, int dummy, char *dummy2) PrintPosition(f, currentMove); fprintf(f, "--------------]\n"); } else { - fen = PositionToFEN(currentMove, NULL); + fen = PositionToFEN(currentMove, NULL, 1); fprintf(f, "%s\n", fen); free(fen); } @@ -14499,6 +14593,7 @@ EditPositionMenuEvent (ChessSquare selection, int x, int y) if(gameInfo.variant == VariantShatranj || gameInfo.variant == VariantXiangqi || gameInfo.variant == VariantCourier || + gameInfo.variant == VariantASEAN || gameInfo.variant == VariantMakruk ) selection = (ChessSquare)((int)selection - (int)WhiteQueen + (int)WhiteFerz); goto defaultlabel; @@ -15215,7 +15310,7 @@ void CreateBookEvent () { ListGame * lg = (ListGame *) gameList.head; - FILE *f; + FILE *f, *g; int nItem; static int secondTime = FALSE; @@ -15224,8 +15319,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; @@ -15523,7 +15618,8 @@ AppendComment (int index, char *text, Boolean addBraces) int oldlen, len; char *old; -if(appData.debugMode) fprintf(debugFP, "Append: in='%s' %d\n", text, addBraces); fflush(debugFP); +if(appData.debugMode) fprintf(debugFP, "Append: in='%s' %d\n", text, addBraces); + if(addBraces == 3) addBraces = 0; else // force appending literally text = GetInfoFromComment( index, text ); /* [HGM] PV time: strip PV info from comment */ CrushCRs(text); @@ -15590,8 +15686,11 @@ GetInfoFromComment (int index, char * text) int time = -1, sec = 0, deci; char * s_eval = FindStr( text, "[%eval " ); char * s_emt = FindStr( text, "[%emt " ); - +#if 0 if( s_eval != NULL || s_emt != NULL ) { +#else + if(0) { // [HGM] this code is not finished, and could actually be detrimental +#endif /* New style */ char delim; @@ -15621,6 +15720,7 @@ GetInfoFromComment (int index, char * text) } p = text; + if(!strncmp(p+1, "final score ", 12)) p += 12, index++; else if(p[1] == '(') { // comment starts with PV p = strchr(p, ')'); // locate end of PV if(p == NULL || sep < p+5) return text; @@ -15644,7 +15744,7 @@ GetInfoFromComment (int index, char * text) if(sec >= 0) time = 600*time + 10*sec; else if(deci >= 0) time = 10*time + deci; else time *= 10; // deci-sec - score = score >= 0 ? score*100 + score_lo : score*100 - score_lo; + score = score > 0 || !score & p[1] != '-' ? score*100 + score_lo : score*100 - score_lo; /* [HGM] PV time: now locate end of PV info */ while( *++sep >= '0' && *sep <= '9'); // strip depth @@ -16132,6 +16232,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; @@ -16987,7 +17088,7 @@ PGNDate () char * -PositionToFEN (int move, char *overrideCastling) +PositionToFEN (int move, char *overrideCastling, int moveCounts) { int i, j, fromX, fromY, toX, toY; int whiteToPlay; @@ -17117,7 +17218,8 @@ PositionToFEN (int move, char *overrideCastling) } if(gameInfo.variant != VariantShogi && gameInfo.variant != VariantXiangqi && - gameInfo.variant != VariantShatranj && gameInfo.variant != VariantCourier && gameInfo.variant != VariantMakruk ) { + gameInfo.variant != VariantShatranj && gameInfo.variant != VariantCourier && + gameInfo.variant != VariantMakruk && gameInfo.variant != VariantASEAN ) { /* En passant target square */ if (move > backwardMostMove) { fromX = moveList[move - 1][0] - AAA; @@ -17149,9 +17251,10 @@ PositionToFEN (int move, char *overrideCastling) } } - /* [HGM] find reversible plies */ + if(moveCounts) { int i = 0, j=move; + /* [HGM] find reversible plies */ if (appData.debugMode) { int k; fprintf(debugFP, "write FEN 50-move: %d %d %d\n", initialRulePlies, forwardMostMove, backwardMostMove); for(k=backwardMostMove; k<=forwardMostMove; k++) @@ -17163,9 +17266,10 @@ PositionToFEN (int move, char *overrideCastling) if( j == backwardMostMove ) i += initialRulePlies; sprintf(p, "%d ", i); p += i>=100 ? 4 : i >= 10 ? 3 : 2; - } - /* Fullmove number */ - sprintf(p, "%d", (move / 2) + 1); + + /* Fullmove number */ + sprintf(p, "%d", (move / 2) + 1); + } else *--p = NULLCHAR; return StrSave(buf); } @@ -17401,7 +17505,8 @@ ParseFEN (Board board, int *blackPlaysFirst, char *fen) /* read e.p. field in games that know e.p. capture */ if(gameInfo.variant != VariantShogi && gameInfo.variant != VariantXiangqi && - gameInfo.variant != VariantShatranj && gameInfo.variant != VariantCourier && gameInfo.variant != VariantMakruk ) { + gameInfo.variant != VariantShatranj && gameInfo.variant != VariantCourier && + gameInfo.variant != VariantMakruk && gameInfo.variant != VariantASEAN ) { if(*p=='-') { p++; board[EP_STATUS] = EP_NONE; } else {