X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=857dcca1edfc3ff759372907a4fea78c06a5d746;hb=a8217398f6ed66bbc0a2e989552710242e5e5598;hp=315bd8efa6c90b6c5899af58fdfa3cf93d67b24f;hpb=7a9e8a6260d9b6be62e80f2250d211f30a1e50fb;p=xboard.git diff --git a/backend.c b/backend.c index 315bd8e..857dcca 100644 --- a/backend.c +++ b/backend.c @@ -848,7 +848,7 @@ InitEngine (ChessProgramState *cps, int n) if(cps->tidy == NULL) cps->tidy = (char*) malloc(MSG_SIZ); TidyProgramName(cps->program, cps->host, cps->tidy); cps->matchWins = 0; - ASSIGN(cps->variants, appData.variant); + ASSIGN(cps->variants, appData.noChessProgram ? "" : appData.variant); cps->analysisSupport = 2; /* detect */ cps->analyzing = FALSE; cps->initDone = FALSE; @@ -1201,6 +1201,11 @@ InitBackEnd1 () DisplayFatalError(buf, 0, 2); return; + case VariantNormal: /* definitely works! */ + if(strcmp(appData.variant, "normal") && !appData.noChessProgram) { // [HGM] hope this is an engine-defined variant + safeStrCpy(engineVariant, appData.variant, MSG_SIZ); + return; + } case VariantXiangqi: /* [HGM] repetition rules not implemented */ case VariantFairy: /* [HGM] TestLegality definitely off! */ case VariantGothic: /* [HGM] should work */ @@ -1213,7 +1218,6 @@ InitBackEnd1 () case VariantFalcon: /* [HGM] untested */ case VariantCrazyhouse: /* holdings not shown, ([HGM] fixed that!) offboard interposition not understood */ - case VariantNormal: /* definitely works! */ case VariantWildCastle: /* pieces not automatically shuffled */ case VariantNoCastle: /* pieces not automatically shuffled */ case VariantFischeRandom: /* [HGM] works and shuffles pieces */ @@ -2104,14 +2108,14 @@ StringToVariant (char *e) int wnum = -1; VariantClass v = VariantNormal; int i, found = FALSE; - char buf[MSG_SIZ]; + char buf[MSG_SIZ], c; int len; if (!e) return v; /* [HGM] skip over optional board-size prefixes */ - if( sscanf(e, "%dx%d_", &i, &i) == 2 || - sscanf(e, "%dx%d+%d_", &i, &i, &i) == 3 ) { + if( sscanf(e, "%dx%d_%c", &i, &i, &c) == 3 || + sscanf(e, "%dx%d+%d_%c", &i, &i, &i, &c) == 4 ) { while( *e++ != '_'); } @@ -2121,7 +2125,7 @@ StringToVariant (char *e) } else for (i=0; i= VariantShogi && isalpha(p[strlen(variantNames[i])])) continue; + if(p && i >= VariantShogi && (p != e || isalpha(p[strlen(variantNames[i])]))) continue; v = (VariantClass) i; found = TRUE; break; @@ -5324,6 +5328,7 @@ UploadGameEvent () } int killX = -1, killY = -1; // [HGM] lion: used for passing e.p. capture square to MakeMove +int legNr = 1; void CoordsToComputerAlgebraic (int rf, int ff, int rt, int ft, char promoChar, char move[7]) @@ -6103,7 +6108,7 @@ InitPosition (int redraw) case VariantFalcon: pieces = FalconArray; gameInfo.boardWidth = 10; - SetCharTable(pieceToChar, "PNBRQ.............FKpnbrq.............fk"); + SetCharTable(pieceToChar, "PNBRQ............FKpnbrq............fk"); break; case VariantXiangqi: pieces = XiangqiArray; @@ -7259,7 +7264,7 @@ Mark (Board board, int flags, ChessMove kind, int rf, int ff, int rt, int ft, VO { typedef char Markers[BOARD_RANKS][BOARD_FILES]; Markers *m = (Markers *) closure; - if(rf == fromY && ff == fromX && (killX < 0 && !(rt == rf && ft == ff) || abs(ft-killX) < 2 && abs(rt-killY) < 2)) + if(rf == fromY && ff == fromX && (killX < 0 ? !(rt == rf && ft == ff) && legNr & 1 : rt == killY && ft == killX || legNr & 2)) (*m)[rt][ft] = 1 + (board[rt][ft] != EmptySquare || kind == WhiteCapturesEnPassant || kind == BlackCapturesEnPassant) + 3*(kind == FirstLeg && killX < 0), legal[rt][ft] = 1; @@ -8873,7 +8878,6 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h s = 8 + strlen(buf), buf[s-9] = NULLCHAR, SetCharTable(pieceToChar, buf); ASSIGN(appData.pieceToCharTable, buf); } - if(startedFromSetupPosition) return; dummy = sscanf(message+s, "%dx%d+%d_%s", &w, &h, &hand, varName); if(dummy >= 3) { while(message[s] && message[s++] != ' '); @@ -8883,23 +8887,29 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h if(dummy == 4) gameInfo.variant = StringToVariant(varName); // parent variant InitPosition(1); // calls InitDrawingSizes to let new parameters take effect if(*buf) SetCharTable(pieceToChar, buf); // do again, for it was spoiled by InitPosition + startedFromSetupPosition = FALSE; } } + if(startedFromSetupPosition) return; ParseFEN(boards[0], &dummy, message+s, FALSE); DrawPosition(TRUE, boards[0]); + CopyBoard(initialPosition, boards[0]); startedFromSetupPosition = TRUE; return; } if(sscanf(message, "piece %s %s", buf2, buf1) == 2) { ChessSquare piece = WhitePawn; char *p=buf2; + if(*p == '+') piece = CHUPROMOTED WhitePawn, p++; + piece += CharToPiece(*p) - WhitePawn; if(cps != &first || appData.testLegality && *engineVariant == NULLCHAR + /* always accept definition of */ && piece != WhiteFalcon && piece != BlackFalcon + /* wild-card pieces. */ && piece != WhiteCobra && piece != BlackCobra /* For variants we don't have */ && gameInfo.variant != VariantBerolina /* correct rules for, we cannot */ && gameInfo.variant != VariantCylinder /* enforce legality on our own! */ && gameInfo.variant != VariantUnknown + && gameInfo.variant != VariantGreat && gameInfo.variant != VariantFairy ) return; - if(*p == '+') piece = CHUPROMOTED WhitePawn, p++; - piece += CharToPiece(*p) - WhitePawn; if(piece < EmptySquare) { pieceDefs = TRUE; ASSIGN(pieceDesc[piece], buf1); @@ -9879,7 +9889,7 @@ ParseGameHistory (char *game) void ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) { - ChessSquare captured = board[toY][toX], piece, king; int p, oldEP = EP_NONE, berolina = 0; + ChessSquare captured = board[toY][toX], piece, king; int p, rookX, oldEP = EP_NONE, berolina = 0; int promoRank = gameInfo.variant == VariantMakruk || gameInfo.variant == VariantGrand || gameInfo.variant == VariantChuChess ? 3 : 1; /* [HGM] compute & store e.p. status and castling rights for new position */ @@ -10000,15 +10010,17 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) && toY == fromY && toX > fromX+1) { board[fromY][fromX] = EmptySquare; board[toY][toX] = king; - board[toY][toX-1] = board[fromY][BOARD_RGHT-1]; - board[fromY][BOARD_RGHT-1] = EmptySquare; + for(rookX=BOARD_RGHT-1; board[toY][rookX] == DarkSquare && rookX > toX + 1; rookX--); + board[toY][toX-1] = board[fromY][rookX]; + board[fromY][rookX] = EmptySquare; } else if (board[fromY][fromX] == king && fromX != BOARD_LEFT && fromX != BOARD_RGHT-1 // [HGM] cylinder */ && toY == fromY && toX < fromX-1) { board[fromY][fromX] = EmptySquare; board[toY][toX] = king; - board[toY][toX+1] = board[fromY][BOARD_LEFT]; - board[fromY][BOARD_LEFT] = EmptySquare; + for(rookX=BOARD_LEFT; board[toY][rookX] == DarkSquare && rookX < toX - 1; rookX++); + board[toY][toX+1] = board[fromY][rookX]; + board[fromY][rookX] = EmptySquare; } else if ((board[fromY][fromX] == WhitePawn && gameInfo.variant != VariantXiangqi || board[fromY][fromX] == WhiteLance && gameInfo.variant != VariantSuper && gameInfo.variant != VariantChu) && toY >= BOARD_HEIGHT-promoRank && promoChar // defaulting to Q is done elsewhere @@ -10047,15 +10059,17 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board) && toY == fromY && toX > fromX+1) { board[fromY][fromX] = EmptySquare; board[toY][toX] = king; - board[toY][toX-1] = board[fromY][BOARD_RGHT-1]; - board[fromY][BOARD_RGHT-1] = EmptySquare; + for(rookX=BOARD_RGHT-1; board[toY][rookX] == DarkSquare && rookX > toX + 1; rookX--); + board[toY][toX-1] = board[fromY][rookX]; + board[fromY][rookX] = EmptySquare; } else if (board[fromY][fromX] == king && fromX != BOARD_LEFT && fromX != BOARD_RGHT-1 // [HGM] cylinder */ && toY == fromY && toX < fromX-1) { board[fromY][fromX] = EmptySquare; board[toY][toX] = king; - board[toY][toX+1] = board[fromY][BOARD_LEFT]; - board[fromY][BOARD_LEFT] = EmptySquare; + for(rookX=BOARD_LEFT; board[toY][rookX] == DarkSquare && rookX < toX - 1; rookX++); + board[toY][toX+1] = board[fromY][rookX]; + board[fromY][rookX] = EmptySquare; } else if (fromY == 7 && fromX == 3 && board[fromY][fromX] == BlackKing && toY == 7 && toX == 5) { @@ -12848,7 +12862,7 @@ LoadGame (FILE *f, int gameNumber, char *title, int useList) if (!err) numPGNTags++; /* [HGM] PGNvariant: automatically switch to variant given in PGN tag */ - if(gameInfo.variant != oldVariant) { + if(gameInfo.variant != oldVariant && (gameInfo.variant != VariantNormal || gameInfo.variantName == NULL || *gameInfo.variantName == NULLCHAR)) { startedFromPositionFile = FALSE; /* [HGM] loadPos: variant switch likely makes position invalid */ ResetFrontEnd(); // [HGM] might need other bitmaps. Cannot use Reset() because it clears gameInfo :-( InitPosition(TRUE); @@ -12867,6 +12881,8 @@ LoadGame (FILE *f, int gameNumber, char *title, int useList) return FALSE; } CopyBoard(boards[0], initial_position); + if(*engineVariant) // [HGM] for now, assume FEN in engine-defined variant game is default initial position + CopyBoard(initialPosition, initial_position); if (blackPlaysFirst) { currentMove = forwardMostMove = backwardMostMove = 1; CopyBoard(boards[1], initial_position); @@ -15069,6 +15085,8 @@ EditPositionMenuEvent (ChessSquare selection, int x, int y) switch (selection) { case ClearBoard: + fromX = fromY = killX = killY = -1; // [HGM] abort any move entry in progress + MarkTargetSquares(1); CopyBoard(currentBoard, boards[0]); CopyBoard(menuBoard, initialPosition); if (gameMode == IcsExamining && ics_type == ICS_FICS) { @@ -15520,6 +15538,7 @@ ForwardInner (int target) seekGraphUp = FALSE; MarkTargetSquares(1); + fromX = fromY = killX = killY = -1; // [HGM] abort any move entry in progress if (gameMode == PlayFromGameFile && !pausing) PauseEvent(); @@ -15638,6 +15657,7 @@ BackwardInner (int target) if (gameMode == EditPosition) return; seekGraphUp = FALSE; MarkTargetSquares(1); + fromX = fromY = killX = killY = -1; // [HGM] abort any move entry in progress if (currentMove <= backwardMostMove) { ClearHighlights(); DrawPosition(full_redraw, boards[currentMove]); @@ -17857,7 +17877,7 @@ PositionToFEN (int move, char *overrideCastling, int moveCounts) q = (boards[move][CASTLING][1] == BOARD_LEFT && boards[move][CASTLING][2] != NoRights ); if(handW) { // for S-Chess with pieces in hand, list virgin pieces between K and Q - for(i=BOARD_RGHT-1-k; i>=BOARD_LEFT+q && j; i--) + for(i=BOARD_RGHT-1-k; i>=BOARD_LEFT+q; i--) if((boards[move][0][i] != WhiteKing || k+q == 0) && boards[move][VIRGIN][i] & VIRGIN_W) *p++ = i + AAA + 'A' - 'a'; } @@ -17868,7 +17888,7 @@ PositionToFEN (int move, char *overrideCastling, int moveCounts) q = (boards[move][CASTLING][4] == BOARD_LEFT && boards[move][CASTLING][5] != NoRights ); if(handB) { - for(i=BOARD_RGHT-1-k; i>=BOARD_LEFT+q && j; i--) + for(i=BOARD_RGHT-1-k; i>=BOARD_LEFT+q; i--) if((boards[move][BOARD_HEIGHT-1][i] != BlackKing || k+q == 0) && boards[move][VIRGIN][i] & VIRGIN_B) *p++ = i + AAA; }