X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=ed803ffadb7af792a18ce92281456548dcaee666;hb=2c21cc66515e6b4bf3fa4d6970fc5eea9a2344db;hp=7ffbd84199037dc318bff5b448feda98816b20eb;hpb=1f070c3ba500547459ad3df71fbdbad1e5b4b4a0;p=xboard.git diff --git a/backend.c b/backend.c index 7ffbd84..ed803ff 100644 --- a/backend.c +++ b/backend.c @@ -168,8 +168,6 @@ int LoadGameOneMove P((ChessMove readAhead)); int LoadGameFromFile P((char *filename, int n, char *title, int useList)); int LoadPositionFromFile P((char *filename, int n, char *title)); int SavePositionToFile P((char *filename)); -void ApplyMove P((int fromX, int fromY, int toX, int toY, int promoChar, - Board board)); void MakeMove P((int fromX, int fromY, int toX, int toY, int promoChar)); void ShowMove P((int fromX, int fromY, int toX, int toY)); int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY, @@ -204,7 +202,6 @@ void StopClocks P((void)); void ResetClocks P((void)); char *PGNDate P((void)); void SetGameInfo P((void)); -Boolean ParseFEN P((Board board, int *blackPlaysFirst, char *fen)); int RegisterMove P((void)); void MakeRegisteredMove P((void)); void TruncateGame P((void)); @@ -11182,19 +11179,22 @@ int pieceList[256], quickBoard[256]; ChessSquare pieceType[256] = { EmptySquare }; Board soughtBoard, reverseBoard, flipBoard, rotateBoard; int counts[EmptySquare], minSought[EmptySquare], minReverse[EmptySquare], maxSought[EmptySquare], maxReverse[EmptySquare]; +int soughtTotal, turn; Boolean epOK, flipSearch; typedef struct { unsigned char piece, to; } Move; -#define DATABASESIZE 10000000 /* good for 100k games */ -Move moveDatabase[DATABASESIZE]; -int movePtr; +#define DSIZE (250000) -void MakePieceList(Board board, int *counts) +Move initialSpace[DSIZE+1000]; // gamble on that game will not be more than 500 moves +Move *moveDatabase = initialSpace; +unsigned int movePtr, dataSize = DSIZE; + +int MakePieceList(Board board, int *counts) { - int r, f, n=Q_PROMO; + int r, f, n=Q_PROMO, total=0; for(r=0;r DATABASESIZE - 500) return 0; // gamble on that game will not be more than 250 moves + if(movePtr > dataSize) { + if(appData.debugMode) fprintf(debugFP, "move-cache overflow, enlarge to %d MB\n", dataSize/128); + dataSize *= 8; // increase size by factor 8 (512KB -> 4MB -> 32MB -> 256MB -> 2GB) + if(dataSize) newSpace = (Move*) calloc(8*dataSize + 1000, sizeof(Move)); + if(newSpace) { + int i; + Move *p = moveDatabase, *q = newSpace; + for(i=0; i 8*DSIZE) free(moveDatabase); // and free old space (if it was allocated) + moveDatabase = newSpace; + } else { // calloc failed, we must be out of memory. Too bad... + dataSize = 0; // prevent calloc events for all subsequent games + return 0; // and signal this one isn't cached + } + } movePtr++; MakePieceList(board, counts); return movePtr; @@ -11260,6 +11277,7 @@ int QuickCompare(Board board, int *minCounts, int *maxCounts) switch(appData.searchMode) { case 1: // exact position match + if(!(turn & board[EP_STATUS-1])) return FALSE; // wrong side to move for(r=0; rpiece; int to = move->to, from = pieceList[piece]; @@ -11304,7 +11321,7 @@ int QuickScan(Board board, Move *move) counts[move->to]++; } else if(piece == Q_EP) { // e.p. capture, encoded as (Q_EP, ep-sqr) + (piece, to) counts[pieceType[quickBoard[to]]]--; - quickBoard[to] = 0; + quickBoard[to] = 0; total--; move++; continue; } else if(piece <= Q_BCASTL) { // castling, encoded as (Q_XCASTL, king-to) + (rook, rook-to) @@ -11318,10 +11335,11 @@ int QuickScan(Board board, Move *move) } } if(appData.searchMode > 2) counts[pieceType[quickBoard[to]]]--; // account capture + if((total -= (quickBoard[to] != 0)) < soughtTotal) return -1; // piece count dropped below what we search for quickBoard[from] = 0; quickBoard[to] = piece; pieceList[piece] = to; - cnt++; + cnt++; turn ^= 3; if(QuickCompare(soughtBoard, minSought, maxSought) || appData.ignoreColors && QuickCompare(reverseBoard, minReverse, maxReverse) || flipSearch && (QuickCompare(flipBoard, minSought, maxSought) || @@ -11337,18 +11355,21 @@ int QuickScan(Board board, Move *move) } while(1); } -InitSearch() +void InitSearch() { int r, f; flipSearch = FALSE; CopyBoard(soughtBoard, boards[currentMove]); - MakePieceList(soughtBoard, maxSought); + soughtTotal = MakePieceList(soughtBoard, maxSought); + soughtBoard[EP_STATUS-1] = (currentMove & 1) + 1; + if(currentMove == 0 && gameMode == EditPosition) soughtBoard[EP_STATUS-1] = blackPlaysFirst + 1; // (!) CopyBoard(reverseBoard, boards[currentMove]); for(r=0; rgameInfo.fen) ParseFEN(boards[scratch], &btm, lg->gameInfo.fen); else CopyBoard(boards[scratch], initialPosition); // default start position if(lg->moves) { + turn = btm + 1; if((next = QuickScan( boards[scratch], &moveDatabase[lg->moves] )) < 0) return -1; // quick scan rules out it is there if(appData.searchMode >= 4) return next; // for material searches, trust QuickScan. }