X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=257a8061f1812bde62987a1c4013e7f77711f6e9;hb=c2bda090d29b9dd0af53185424281e6c10f05d10;hp=170b9c3b92881bbc8cd15f2efcce92b37b5f82fc;hpb=3830e6aea9b487049e7e1ca9961a848f64ba98eb;p=xboard.git diff --git a/backend.c b/backend.c index 170b9c3..257a806 100644 --- a/backend.c +++ b/backend.c @@ -449,7 +449,11 @@ int adjudicateLossPlies = 6; char white_holding[64], black_holding[64]; TimeMark lastNodeCountTime; long lastNodeCount=0; + int have_sent_ICS_logon = 0; +int sending_ICS_login = 0; +int sending_ICS_password = 0; + int movesPerSession; int suddenDeath, whiteStartMove, blackStartMove; /* [HGM] for implementation of 'any per time' sessions, as in first part of byoyomi TC */ long whiteTimeRemaining, blackTimeRemaining, timeControl, timeIncrement, lastWhite, lastBlack; @@ -1023,6 +1027,13 @@ int NextSessionFromString( char ** str, int *moves, long * tc, long *inc, int *i if(**str == '!') type = *(*str)++; // Bronstein TC if(result = NextIntegerFromString( str, &temp2)) return -1; *inc = temp2 * 1000; + if(**str == '.') { // read fraction of increment + char *start = ++(*str); + if(result = NextIntegerFromString( str, &temp2)) return -1; + temp2 *= 1000; + while(start++ < *str) temp2 /= 10; + *inc += temp2; + } } else *inc = 0; *moves = 0; *tc = temp * 1000; *incType = type; return 0; @@ -1065,7 +1076,7 @@ int GetTimeQuota(int movenr, int lastUsed, char *tcString) int ParseTimeControl(tc, ti, mps) char *tc; - int ti; + float ti; int mps; { long tc1; @@ -1080,17 +1091,17 @@ ParseTimeControl(tc, ti, mps) if(ti > 0) { if(mps) - snprintf(buf, MSG_SIZ, ":%d/%s+%d", mps, mytc, ti); - else - snprintf(buf, MSG_SIZ, ":%s+%d", mytc, ti); + snprintf(buf, MSG_SIZ, ":%d/%s+%g", mps, mytc, ti); + else + snprintf(buf, MSG_SIZ, ":%s+%g", mytc, ti); } else { if(mps) snprintf(buf, MSG_SIZ, ":%d/%s", mps, mytc); - else + else snprintf(buf, MSG_SIZ, ":%s", mytc); } fullTimeControlString = StrSave(buf); // this should now be in PGN format - + if( NextTimeControlFromString( &tc, &tc1 ) != 0 ) { return FALSE; } @@ -3108,8 +3119,23 @@ read_from_ics(isr, closure, data, count, error) if (!have_sent_ICS_logon && looking_at(buf, &i, "login:")) { ICSInitScript(); have_sent_ICS_logon = 1; + /* if we don't send the login/password via icsLogon, use special readline + code for it */ + if (strlen(appData.icsLogon)==0) + { + sending_ICS_password = 0; // in case we come back to login + sending_ICS_login = 1; + }; continue; } + /* need to shadow the password */ + if (!sending_ICS_password && looking_at(buf, &i, "password:")) { + /* if we don't send the login/password via icsLogon, use special readline + code for it */ + if (strlen(appData.icsLogon)==0) + sending_ICS_password = 1; + continue; + } if (ics_getting_history != H_GETTING_MOVES /*smpos kludge*/ && (looking_at(buf, &i, "\n<12> ") || @@ -3538,7 +3564,7 @@ read_from_ics(isr, closure, data, count, error) /* [4] is " *" or empty (don't care). */ int gamenum = atoi(star_match[0]); char *whitename, *blackname, *why, *endtoken; - ChessMove endtype = (ChessMove) 0; + ChessMove endtype = EndOfFile; if (tkind == 0) { whitename = star_match[1]; @@ -4899,7 +4925,7 @@ ParseOneMove(move, moveNum, moveType, fromX, fromY, toX, toY, promoChar) case AmbiguousMove: case ImpossibleMove: - case (ChessMove) 0: /* end of file */ + case EndOfFile: case ElapsedTime: case Comment: case PGNTag: @@ -5875,7 +5901,7 @@ FILE *lastLoadGameFP = NULL, *lastLoadPositionFP = NULL; int lastLoadGameNumber = 0, lastLoadPositionNumber = 0; int lastLoadGameUseList = FALSE; char lastLoadGameTitle[MSG_SIZ], lastLoadPositionTitle[MSG_SIZ]; -ChessMove lastLoadGameStart = (ChessMove) 0; +ChessMove lastLoadGameStart = EndOfFile; void UserMoveEvent(fromX, fromY, toX, toY, promoChar) @@ -6022,15 +6048,15 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar) pup = boards[currentMove][toY][toX]; /* [HGM] If move started in holdings, it means a drop. Convert to standard form */ - if( fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) { + if( fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) { if( pup != EmptySquare ) return; moveType = WhiteOnMove(currentMove) ? WhiteDrop : BlackDrop; - if(appData.debugMode) fprintf(debugFP, "Drop move %d, curr=%d, x=%d,y=%d, p=%d\n", + if(appData.debugMode) fprintf(debugFP, "Drop move %d, curr=%d, x=%d,y=%d, p=%d\n", moveType, currentMove, fromX, fromY, boards[currentMove][fromY][fromX]); // holdings might not be sent yet in ICS play; we have to figure out which piece belongs here if(fromX == 0) fromY = BOARD_HEIGHT-1 - fromY; // black holdings upside-down fromX = fromX ? WhitePawn : BlackPawn; // first piece type in selected holdings - while(PieceToChar(fromX) == '.' || PieceToNumber(fromX) != fromY && fromX != (int) EmptySquare) fromX++; + while(PieceToChar(fromX) == '.' || PieceToNumber(fromX) != fromY && fromX != (int) EmptySquare) fromX++; fromY = DROP_RANK; } @@ -6803,7 +6829,7 @@ Adjudicate(ChessProgramState *cps) case EP_WINS: result = WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins; break; default: - result = (ChessMove) 0; + result = EndOfFile; } if(canAdjudicate && appData.checkMates && result) { // [HGM] mates: adjudicate finished games if requested if(engineOpponent) @@ -8208,7 +8234,7 @@ ParseGameHistory(game) } DisplayError(buf, 0); return; - case (ChessMove) 0: /* end of file */ + case EndOfFile: if (boardIndex < backwardMostMove) { /* Oops, gap. How did that happen? */ DisplayError(_("Gap in move list"), 0); @@ -8312,7 +8338,7 @@ ApplyMove(fromX, fromY, toX, toY, promoChar, board) /* [HGM] In Shatranj and Courier all promotions are to Ferz */ if((gameInfo.variant==VariantShatranj || gameInfo.variant==VariantCourier || gameInfo.variant == VariantMakruk) && promoChar != 0) promoChar = PieceToChar(WhiteFerz); - + if (fromY == DROP_RANK) { /* must be first */ piece = board[toY][toX] = (ChessSquare) fromX; @@ -8578,8 +8604,8 @@ ApplyMove(fromX, fromY, toX, toY, promoChar, board) } else if(!appData.testLegality) { // without legality testing, unconditionally believe promoChar board[toY][toX] = CharToPiece(promoChar); } - if((gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) - && promoChar != NULLCHAR && gameInfo.holdingsSize) { + if((gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) + && promoChar != NULLCHAR && gameInfo.holdingsSize) { // [HGM] superchess: take promotion piece out of holdings int k = PieceToNumber(CharToPiece(ToUpper(promoChar))); if((int)piece < (int)BlackPawn) { // determine stm from piece color @@ -9466,7 +9492,7 @@ Reset(redraw, init) gotPremove = FALSE; alarmSounded = FALSE; - GameEnds((ChessMove) 0, NULL, GE_PLAYER); + GameEnds(EndOfFile, NULL, GE_PLAYER); if(appData.serverMovesName != NULL) { /* [HGM] prepare to make moves file for broadcasting */ clock_t t = clock(); @@ -9591,7 +9617,7 @@ LoadGameOneMove(readAhead) } yyboardindex = forwardMostMove; - if (readAhead != (ChessMove)0) { + if (readAhead != EndOfFile) { moveType = readAhead; } else { if (gameFileFP == NULL) @@ -9679,7 +9705,7 @@ LoadGameOneMove(readAhead) } break; - case (ChessMove) 0: /* end of file */ + case EndOfFile: if (appData.debugMode) fprintf(debugFP, "Parser hit end of file\n"); switch (MateTest(boards[currentMove], PosFlags(currentMove)) ) { @@ -9707,7 +9733,7 @@ LoadGameOneMove(readAhead) if (appData.debugMode) fprintf(debugFP, "Parser ignoring: '%s' (%d)\n", yy_text, (int) moveType); - return LoadGameOneMove((ChessMove)0); /* tail recursion */ + return LoadGameOneMove(EndOfFile); /* tail recursion */ } /* else fall thru */ @@ -9742,7 +9768,7 @@ LoadGameOneMove(readAhead) if (appData.debugMode) fprintf(debugFP, "Parser ignoring: '%s' (%d)\n", yy_text, (int) moveType); - return LoadGameOneMove((ChessMove)0); /* tail recursion */ + return LoadGameOneMove(EndOfFile); /* tail recursion */ case IllegalMove: if (appData.testLegality) { @@ -10088,12 +10114,12 @@ LoadGame(f, gameNumber, title, useList) * 5-4-02: Let's try being more lenient and allowing a game to * start with an unnumbered move. Does that break anything? */ - cm = lastLoadGameStart = (ChessMove) 0; + cm = lastLoadGameStart = EndOfFile; while (gn > 0) { yyboardindex = forwardMostMove; cm = (ChessMove) yylex(); switch (cm) { - case (ChessMove) 0: + case EndOfFile: if (cmailMsgLoaded) { nCmailGames = CMAIL_MAX_GAMES - gn; } else { @@ -10115,7 +10141,7 @@ LoadGame(f, gameNumber, title, useList) case PGNTag: break; case MoveNumberOne: - case (ChessMove) 0: + case EndOfFile: gn--; /* count this game */ lastLoadGameStart = cm; break; @@ -10130,7 +10156,7 @@ LoadGame(f, gameNumber, title, useList) case GNUChessGame: case PGNTag: case MoveNumberOne: - case (ChessMove) 0: + case EndOfFile: gn--; /* count this game */ lastLoadGameStart = cm; break; @@ -10165,7 +10191,7 @@ LoadGame(f, gameNumber, title, useList) case NormalMove: /* Only a NormalMove can be at the start of a game * without a position diagram. */ - if (lastLoadGameStart == (ChessMove) 0) { + if (lastLoadGameStart == EndOfFile ) { gn--; lastLoadGameStart = MoveNumberOne; } @@ -10185,10 +10211,10 @@ LoadGame(f, gameNumber, title, useList) yyboardindex = forwardMostMove; cm = (ChessMove) yylex(); - if (cm == (ChessMove) 0 || + if (cm == EndOfFile || cm == GNUChessGame || cm == XBoardGame) { /* Empty game; pretend end-of-file and handle later */ - cm = (ChessMove) 0; + cm = EndOfFile; break; } @@ -10372,7 +10398,7 @@ LoadGame(f, gameNumber, title, useList) cm = (ChessMove) yylex(); } - if ((cm == (ChessMove) 0 && lastLoadGameStart != (ChessMove) 0) || + if ((cm == EndOfFile && lastLoadGameStart != EndOfFile ) || cm == WhiteWins || cm == BlackWins || cm == GameIsDrawn || cm == GameUnfinished) { DisplayMessage("", _("No moves in game")); @@ -10409,7 +10435,7 @@ LoadGame(f, gameNumber, title, useList) LoadGameOneMove(cm); /* load the remaining moves from the file */ - while (LoadGameOneMove((ChessMove)0)) { + while (LoadGameOneMove(EndOfFile)) { timeRemaining[0][forwardMostMove] = whiteTimeRemaining; timeRemaining[1][forwardMostMove] = blackTimeRemaining; } @@ -11992,7 +12018,7 @@ EditGameEvent() SendToProgram("force\n", &first); break; case TwoMachinesPlay: - GameEnds((ChessMove) 0, NULL, GE_PLAYER); + GameEnds(EndOfFile, NULL, GE_PLAYER); ResurrectChessProgram(); SetUserThinkingEnables(); break; @@ -13528,9 +13554,9 @@ SendTimeControl(cps, mps, tc, inc, sd, st) /* Note old gnuchess bug -- minutes:seconds used to not work. Fixed in later versions, but still avoid :seconds when seconds is 0. */ - snprintf(buf, MSG_SIZ, "level %d %ld %d\n", mps, tc/60000, inc/1000); + snprintf(buf, MSG_SIZ, "level %d %ld %g\n", mps, tc/60000, inc/1000); } else { - snprintf(buf, MSG_SIZ, "level %d %ld:%02d %d\n", mps, tc/60000, + snprintf(buf, MSG_SIZ, "level %d %ld:%02d %g\n", mps, tc/60000, seconds, inc/1000); } } @@ -14287,7 +14313,7 @@ DecrementClocks() if (WhiteOnMove(forwardMostMove)) { if(whiteNPS >= 0) lastTickLength = 0; timeRemaining = whiteTimeRemaining -= lastTickLength; - if(timeRemaining < 0) { + if(timeRemaining < 0 && !appData.icsActive) { GetTimeQuota((forwardMostMove-whiteStartMove-1)/2, 0, whiteTC); // sets suddenDeath & nextSession; if(suddenDeath) { // [HGM] if we run out of a non-last incremental session, go to the next whiteStartMove = forwardMostMove; whiteTC = nextSession; @@ -14299,7 +14325,7 @@ DecrementClocks() } else { if(blackNPS >= 0) lastTickLength = 0; timeRemaining = blackTimeRemaining -= lastTickLength; - if(timeRemaining < 0) { // [HGM] if we run out of a non-last incremental session, go to the next + if(timeRemaining < 0 && !appData.icsActive) { // [HGM] if we run out of a non-last incremental session, go to the next GetTimeQuota((forwardMostMove-blackStartMove-1)/2, 0, blackTC); if(suddenDeath) { blackStartMove = forwardMostMove;