BlackUnicorn, BlackBishop, BlackMan, BlackRook }
};
+ChessSquare SpartanArray[2][BOARD_FILES] = {
+ { WhiteRook, WhiteKnight, WhiteBishop, WhiteQueen,
+ WhiteKing, WhiteBishop, WhiteKnight, WhiteRook },
+ { BlackAlfil, BlackMarshall, BlackKing, BlackDragon,
+ BlackDragon, BlackKing, BlackAngel, BlackAlfil }
+};
+
ChessSquare fairyArray[2][BOARD_FILES] = { /* [HGM] Queen side differs from King side */
{ WhiteRook, WhiteKnight, WhiteBishop, WhiteQueen,
WhiteKing, WhiteBishop, WhiteKnight, WhiteRook },
case VariantSuper: /* experimental */
case VariantGreat: /* experimental, requires legality testing to be off */
case VariantSChess: /* S-Chess, should work */
+ case VariantSpartan: /* should work */
break;
}
}
moveList[endPV-1][1] = fromY + ONE;
moveList[endPV-1][2] = toX + AAA;
moveList[endPV-1][3] = toY + ONE;
+ moveList[endPV-1][4] = promoChar;
+ moveList[endPV-1][5] = NULLCHAR;
+ strncat(moveList[endPV-1], "\n", MOVE_LEN);
if(storeComments)
CoordsToAlgebraic(boards[endPV - 1],
PosFlags(endPV - 1),
int i, j, pawnRow, overrule,
oldx = gameInfo.boardWidth,
oldy = gameInfo.boardHeight,
- oldh = gameInfo.holdingsWidth,
- oldv = gameInfo.variant;
+ oldh = gameInfo.holdingsWidth;
+ static int oldv;
if(appData.icsActive) shuffleOpenings = FALSE; // [HGM] shuffle: in ICS mode, only shuffle on ICS request
pieces = KnightmateArray;
SetCharTable(pieceToChar, "P.BRQ.....M.........K.p.brq.....m.........k.");
break;
+ case VariantSpartan:
+ pieces = SpartanArray;
+ SetCharTable(pieceToChar, "PNBRQ................K......lwg.....c...h..k");
+ break;
case VariantFairy:
pieces = fairyArray;
SetCharTable(pieceToChar, "PNBRQFEACWMOHIJGDVLSUKpnbrqfeacwmohijgdvlsuk");
if(j < BOARD_LEFT || j >= BOARD_RGHT || overrule) continue;
initialPosition[0][j] = pieces[0][j-gameInfo.holdingsWidth];
initialPosition[pawnRow][j] = WhitePawn;
- initialPosition[BOARD_HEIGHT-pawnRow-1][j] = BlackPawn;
+ initialPosition[BOARD_HEIGHT-pawnRow-1][j] = gameInfo.variant == VariantSpartan ? BlackLance : BlackPawn;
if(gameInfo.variant == VariantXiangqi) {
if(j&1) {
initialPosition[pawnRow][j] =
if(oldx != gameInfo.boardWidth ||
oldy != gameInfo.boardHeight ||
+ oldv != gameInfo.variant ||
oldh != gameInfo.holdingsWidth
-#ifdef GOTHIC
- || oldv == VariantGothic || // For licensing popups
- gameInfo.variant == VariantGothic
-#endif
-#ifdef FALCON
- || oldv == VariantFalcon ||
- gameInfo.variant == VariantFalcon
-#endif
)
InitDrawingSizes(-2 ,0);
+ oldv = gameInfo.variant;
if (redraw)
DrawPosition(TRUE, boards[currentMove]);
}
promotionZoneSize = 3;
}
+ // Treat Lance as Pawn when it is not representing Amazon
+ if(gameInfo.variant != VariantSuper) {
+ if(piece == WhiteLance) piece = WhitePawn; else
+ if(piece == BlackLance) piece = BlackPawn;
+ }
+
// next weed out all moves that do not touch the promotion zone at all
if((int)piece >= BlackPawn) {
if(toY >= promotionZoneSize && fromY >= promotionZoneSize)
}
}
- if(Adjudicate(cps)) return; // [HGM] adjudicate: for all automatic game ends
+ if(Adjudicate(cps)) {
+ DrawPosition(FALSE, boards[currentMove = forwardMostMove-1]);
+ ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
+ return; // [HGM] adjudicate: for all automatic game ends
+ }
#if ZIPPY
if ((gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack) &&
gameMode = EditGame;
ModeHighlight();
}
+ /* [HGM] illegal-move claim should forfeit game when Xboard */
+ /* only passes fully legal moves */
+ if( appData.testLegality && gameMode == TwoMachinesPlay ) {
+ GameEnds( cps->twoMachinesColor[0] == 'w' ? BlackWins : WhiteWins,
+ "False illegal-move claim", GE_XBOARD );
+ return; // do not take back move we tested as valid
+ }
currentMove = forwardMostMove-1;
DisplayMove(currentMove-1); /* before DisplayMoveError */
SwitchClocks(forwardMostMove-1); // [HGM] race
parseList[currentMove], cps->which);
DisplayMoveError(buf1);
DrawPosition(FALSE, boards[currentMove]);
-
- /* [HGM] illegal-move claim should forfeit game when Xboard */
- /* only passes fully legal moves */
- if( appData.testLegality && gameMode == TwoMachinesPlay ) {
- GameEnds( cps->twoMachinesColor[0] == 'w' ? BlackWins : WhiteWins,
- "False illegal-move claim", GE_XBOARD );
- }
return;
}
if (strncmp(message, "time", 4) == 0 && StrStr(message, "Illegal")) {
if (q != NULL) *q = NULLCHAR;
p++;
}
+ while(q = strchr(p, '\n')) *q = ' '; // [HGM] crush linefeeds in result message
gameInfo.resultDetails = StrSave(p);
continue;
}
board[toY][toX] = king;
board[toY][toX+1] = board[fromY][BOARD_LEFT];
board[fromY][BOARD_LEFT] = EmptySquare;
- } else if (board[fromY][fromX] == WhitePawn
+ } else if ((board[fromY][fromX] == WhitePawn && gameInfo.variant != VariantXiangqi ||
+ board[fromY][fromX] == WhiteLance && gameInfo.variant != VariantSuper && gameInfo.variant != VariantShogi)
&& toY >= BOARD_HEIGHT-promoRank
- && gameInfo.variant != VariantXiangqi
) {
/* white pawn promotion */
board[toY][toX] = CharToPiece(ToUpper(promoChar));
board[toY][toX] = BlackKing;
board[fromY][0] = EmptySquare;
board[toY][2] = BlackRook;
- } else if (board[fromY][fromX] == BlackPawn
+ } else if ((board[fromY][fromX] == BlackPawn && gameInfo.variant != VariantXiangqi ||
+ board[fromY][fromX] == BlackLance && gameInfo.variant != VariantSuper && gameInfo.variant != VariantShogi)
&& toY < promoRank
- && gameInfo.variant != VariantXiangqi
) {
/* black pawn promotion */
board[toY][toX] = CharToPiece(ToLower(promoChar));
first.matchWins, second.matchWins,
appData.matchGames - (first.matchWins + second.matchWins));
popupRequested++; // [HGM] crash: postpone to after resetting endingGame
+ if (appData.firstPlaysBlack) { // [HGM] match: back to original for next match
+ first.twoMachinesColor = "black\n";
+ second.twoMachinesColor = "white\n";
+ } else {
+ first.twoMachinesColor = "white\n";
+ second.twoMachinesColor = "black\n";
+ }
}
}
if ((gameMode == AnalyzeMode || gameMode == AnalyzeFile) &&
return;
if (matchMode || appData.timeDelay == 0)
continue;
- if (appData.timeDelay < 0 || gameMode == AnalyzeFile)
+ if (appData.timeDelay < 0)
return;
StartLoadGameTimer((long)(1000.0 * appData.timeDelay));
break;
fprintf(debugFP, "AutoPlayOneMove(): current %d\n", currentMove);
}
- if (gameMode != PlayFromGameFile)
+ if (gameMode != PlayFromGameFile && gameMode != AnalyzeFile)
return FALSE;
+ if (gameMode == AnalyzeFile && currentMove > backwardMostMove) {
+ pvInfoList[currentMove].depth = programStats.depth;
+ pvInfoList[currentMove].score = programStats.score;
+ pvInfoList[currentMove].time = 0;
+ if(currentMove < forwardMostMove) AppendComment(currentMove+1, lastPV[0], 2);
+ }
+
if (currentMove >= forwardMostMove) {
+ if(gameMode == AnalyzeFile) { ExitAnalyzeMode(); SendToProgram("force\n", &first); }
gameMode = EditGame;
ModeHighlight();
if (q != NULL) *q = NULLCHAR;
p++;
}
+ while(q = strchr(p, '\n')) *q = ' '; // [HGM] crush linefeeds in result message
GameEnds(moveType, p, GE_FILE);
done = TRUE;
if (cmailMsgLoaded) {
EditTagsEvent()
{
char *tags = PGNTags(&gameInfo);
- EditTagsPopUp(tags);
+ EditTagsPopUp(tags, NULL);
free(tags);
}
char *text;
{
int len;
+ char *p;
+ float score;
+ if(index && sscanf(text, "%f/%d", &score, &len) == 2 &&
+ pvInfoList[index-1].depth == len &&
+ fabs(pvInfoList[index-1].score - score*100.) < 0.5 &&
+ (p = strchr(text, '\n'))) text = p; // [HGM] strip off first line with PV info, if any
while (*text == '\n') text++;
len = strlen(text);
while (len > 0 && text[len - 1] == '\n') len--;
safeStrCpy(commentList[index], old, oldlen + len + 6);
free(old);
// [HGM] braces: join "{A\n}\n" + "{\nB}" as "{A\nB\n}"
- if(commentList[index][oldlen-1] == '}' && (text[0] == '{' || addBraces)) {
- if(addBraces) addBraces = FALSE; else { text++; len--; }
+ if(commentList[index][oldlen-1] == '}' && (text[0] == '{' || addBraces == TRUE)) {
+ if(addBraces == TRUE) addBraces = FALSE; else { text++; len--; }
while (*text == '\n') { text++; len--; }
commentList[index][--oldlen] = NULLCHAR;
}
- if(addBraces) strcat(commentList[index], "\n{\n");
+ if(addBraces) strcat(commentList[index], addBraces == 2 ? "\n(" : "\n{\n");
else strcat(commentList[index], "\n");
strcat(commentList[index], text);
- if(addBraces) strcat(commentList[index], "\n}\n");
+ if(addBraces) strcat(commentList[index], addBraces == 2 ? ")\n" : "\n}\n");
else strcat(commentList[index], "\n");
} else {
commentList[index] = (char *) malloc(len + 6); // perhaps wastes 4...
if(addBraces)
- safeStrCpy(commentList[index], "{\n", 3);
+ safeStrCpy(commentList[index], addBraces == 2 ? "(" : "{\n", 3);
else commentList[index][0] = NULLCHAR;
strcat(commentList[index], text);
- strcat(commentList[index], "\n");
- if(addBraces) strcat(commentList[index], "}\n");
+ strcat(commentList[index], addBraces == 2 ? ")\n" : "\n");
+ if(addBraces == TRUE) strcat(commentList[index], "}\n");
}
}
/* [HGM] PV time: and then remove it, to prevent it appearing twice */
char *GetInfoFromComment( int index, char * text )
{
- char * sep = text;
+ char * sep = text, *p;
if( text != NULL && index > 0 ) {
int score = 0;
return text;
}
+ p = text;
+ if(p[1] == '(') { // comment starts with PV
+ p = strchr(p, ')'); // locate end of PV
+ if(p == NULL || sep < p+5) return text;
+ // at this point we have something like "{(.*) +0.23/6 ..."
+ p = text; while(*++p != ')') p[-1] = *p; p[-1] = ')';
+ *p = '\n'; while(*p == ' ' || *p == '\n') p++; *--p = '{';
+ // we now moved the brace to behind the PV: "(.*) {+0.23/6 ..."
+ }
time = -1; sec = -1; deci = -1;
- if( sscanf( text+1, "%d.%d/%d %d:%d", &score, &score_lo, &depth, &time, &sec ) != 5 &&
- sscanf( text+1, "%d.%d/%d %d.%d", &score, &score_lo, &depth, &time, &deci ) != 5 &&
- sscanf( text+1, "%d.%d/%d %d", &score, &score_lo, &depth, &time ) != 4 &&
- sscanf( text+1, "%d.%d/%d", &score, &score_lo, &depth ) != 3 ) {
+ if( sscanf( p+1, "%d.%d/%d %d:%d", &score, &score_lo, &depth, &time, &sec ) != 5 &&
+ sscanf( p+1, "%d.%d/%d %d.%d", &score, &score_lo, &depth, &time, &deci ) != 5 &&
+ sscanf( p+1, "%d.%d/%d %d", &score, &score_lo, &depth, &time ) != 4 &&
+ sscanf( p+1, "%d.%d/%d", &score, &score_lo, &depth ) != 3 ) {
return text;
}
/* [HGM] PV time: now locate end of PV info */
while( *++sep >= '0' && *sep <= '9'); // strip depth
if(time >= 0)
- while( *++sep >= '0' && *sep <= '9'); // strip time
+ while( *++sep >= '0' && *sep <= '9' || *sep == '\n'); // strip time
if(sec >= 0)
while( *++sep >= '0' && *sep <= '9'); // strip seconds
if(deci >= 0)
pvInfoList[index-1].score = score;
pvInfoList[index-1].time = 10*time; // centi-sec
if(*sep == '}') *sep = 0; else *--sep = '{';
+ if(p != text) { while(*p++ = *sep++); sep = text; } // squeeze out space between PV and comment, and return both
}
return sep;
}