Add final piece count to search criteria
authorH.G.Muller <hgm@hgm-xboard.(none)>
Mon, 1 Sep 2014 10:03:58 +0000 (12:03 +0200)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Mon, 1 Sep 2014 12:13:23 +0000 (14:13 +0200)
The Load Options dialog now has a text field in which a range can be
entered (like 8-10). Position search will then only select games that
had their final number of pieces in this range.

backend.c
common.h
dialogs.c
winboard/resource.h
winboard/winboard.c
winboard/winboard.rc
winboard/woptions.c

index f05359c..c81e0fd 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -12364,12 +12364,26 @@ QuickCompare (Board board, int *minCounts, int *maxCounts)
 int
 QuickScan (Board board, Move *move)
 {   // reconstruct game,and compare all positions in it
-    int cnt=0, stretch=0, total = MakePieceList(board, counts);
+    int cnt=0, stretch=0, found = -1, total = MakePieceList(board, counts);
     do {
        int piece = move->piece;
        int to = move->to, from = pieceList[piece];
+       if(!found) { // if already found just scan to game end for final piece count
+         if(QuickCompare(soughtBoard, minSought, maxSought) ||
+          appData.ignoreColors && QuickCompare(reverseBoard, minReverse, maxReverse) ||
+          flipSearch && (QuickCompare(flipBoard, minSought, maxSought) ||
+                               appData.ignoreColors && QuickCompare(rotateBoard, minReverse, maxReverse))
+           ) {
+           static int lastCounts[EmptySquare+1];
+           int i;
+           if(stretch) for(i=0; i<EmptySquare; i++) if(lastCounts[i] != counts[i]) { stretch = 0; break; } // reset if material changes
+           if(stretch++ == 0) for(i=0; i<EmptySquare; i++) lastCounts[i] = counts[i]; // remember actual material
+         } else stretch = 0;
+         if(stretch && (appData.searchMode == 1 || stretch >= appData.stretch)) found = cnt + 1 - stretch;
+         if(found && !appData.minPieces) return found;
+       }
        if(piece <= Q_PROMO) { // special moves encoded by otherwise invalid piece numbers 1-4
-         if(!piece) return -1;
+         if(!piece) return (appData.minPieces && (total < appData.minPieces || total > appData.maxPieces) ? -1 : found);
          if(piece == Q_PROMO) { // promotion, encoded as (Q_PROMO, to) + (piece, promoType)
            piece = (++move)->piece;
            from = pieceList[piece];
@@ -12400,17 +12414,6 @@ QuickScan (Board board, Move *move)
        quickBoard[to] = piece;
        pieceList[piece] = to;
        cnt++; turn ^= 3;
-       if(QuickCompare(soughtBoard, minSought, maxSought) ||
-          appData.ignoreColors && QuickCompare(reverseBoard, minReverse, maxReverse) ||
-          flipSearch && (QuickCompare(flipBoard, minSought, maxSought) ||
-                               appData.ignoreColors && QuickCompare(rotateBoard, minReverse, maxReverse))
-         ) {
-           static int lastCounts[EmptySquare+1];
-           int i;
-           if(stretch) for(i=0; i<EmptySquare; i++) if(lastCounts[i] != counts[i]) { stretch = 0; break; } // reset if material changes
-           if(stretch++ == 0) for(i=0; i<EmptySquare; i++) lastCounts[i] = counts[i]; // remember actual material
-       } else stretch = 0;
-       if(stretch && (appData.searchMode == 1 || stretch >= appData.stretch)) return cnt + 1 - stretch;
        move++;
     } while(1);
 }
index 132c48d..6340c50 100644 (file)
--- a/common.h
+++ b/common.h
@@ -736,6 +736,8 @@ typedef struct {
     int dateThreshold;
     int searchMode;
     int stretch;
+    int minPieces;
+    int maxPieces;
     Boolean ignoreColors;
     Boolean findMirror;
     char *userName;
index 23f8633..badad64 100644 (file)
--- a/dialogs.c
+++ b/dialogs.c
@@ -697,11 +697,14 @@ IcsOptionsProc ()
 static char *modeNames[] = { N_("Exact position match"), N_("Shown position is subset"), N_("Same material with exactly same Pawn chain"),
                      N_("Same material"), N_("Material range (top board half optional)"), N_("Material difference (optional stuff balanced)"), NULL };
 static char *modeValues[] = { "1", "2", "3", "4", "5", "6" };
-static char *searchMode;
+static char *searchMode, *countRange;
 
 static int
 LoadOptionsOK ()
 {
+    appData.minPieces = appData.maxPieces = 0;
+    sscanf(countRange, "%d-%d", &appData.minPieces, &appData.maxPieces);
+    if(appData.maxPieces < appData.minPieces) appData.maxPieces = appData.minPieces;
     appData.searchMode = atoi(searchMode);
     return 1;
 }
@@ -718,6 +721,7 @@ static Option loadOptions[] = {
 { 0, 0,5000,    NULL, (void*) &appData.eloThreshold2, "", NULL, Spin, N_("Elo of weakest player at least:") },
 { 0, 0,5000,    NULL, (void*) &appData.dateThreshold, "", NULL, Spin, N_("No games before year:") },
 { 0, 1,50,      NULL, (void*) &appData.stretch, "", NULL, Spin, N_("Minimum nr consecutive positions:") },
+{ 0, 0,197,     NULL, (void*) &countRange, "", NULL, TextBox,  "Final nr of pieces" },
 { 0, 0,205,     NULL, (void*) &searchMode, (char*) modeValues, modeNames, ComboBox, N_("Search mode:") },
 { 0, 0, 0,      NULL, (void*) &appData.ignoreColors, "", NULL, CheckBox, N_("Also match reversed colors") },
 { 0, 0, 0,      NULL, (void*) &appData.findMirror, "", NULL, CheckBox, N_("Also match left-right flipped position") },
@@ -727,6 +731,7 @@ static Option loadOptions[] = {
 void
 LoadOptionsPopUp (DialogClass parent)
 {
+   ASSIGN(countRange, "");
    ASSIGN(searchMode, modeValues[appData.searchMode-1]);
    GenericPopUp(loadOptions, _("Load Game Options"), TransientDlg, parent, MODAL, 0);
 }
index 785bc84..1634a3d 100644 (file)
 #define OPT_GameListFind                1981\r
 #define OPT_Grid                        1983\r
 #define IDM_LoadProg2                   1984\r
+#define OPT_Range                       1985\r
+#define OPT_Ranget                      1986\r
 \r
 \r
 // Next default values for new objects\r
index 3738ddc..a31fa7c 100644 (file)
@@ -260,7 +260,8 @@ int dialogItems[][42] = {
 { DLG_TimeControl, IDC_Babble, OPT_TCUseMoves, OPT_TCUseInc, OPT_TCUseFixed, \r
   OPT_TCtext1, OPT_TCtext2, OPT_TCitext1, OPT_TCitext2, OPT_TCftext, GPB_Factors,   IDC_Factor1, IDC_Factor2, IDOK, IDCANCEL }, \r
 { DLG_LoadOptions, OPT_Autostep, OPT_AStext1, OPT_Exact, OPT_Subset, OPT_Struct, OPT_Material, OPT_Range, OPT_Difference,\r
-  OPT_elo1t, OPT_elo2t, OPT_datet, OPT_Stretch, OPT_Stretcht, OPT_Reversed, OPT_SearchMode, OPT_Mirror, OPT_thresholds, IDOK, IDCANCEL }, \r
+  OPT_elo1t, OPT_elo2t, OPT_datet, OPT_Stretch, OPT_Stretcht, OPT_Reversed, OPT_SearchMode, OPT_Mirror, OPT_thresholds,\r
+  OPT_Ranget, IDOK, IDCANCEL }, \r
 { DLG_SaveOptions, OPT_Autosave, OPT_AVPrompt, OPT_AVToFile, OPT_AVBrowse,\r
   801, OPT_PGN, OPT_Old, OPT_OutOfBookInfo, IDOK, IDCANCEL }, \r
 { 1536, 1090, IDC_Directories, 1089, 1091, IDOK, IDCANCEL, 1038, IDC_IndexNr, 1037 }, \r
@@ -1811,6 +1812,7 @@ static void CreatePieceMaskFromFont( HDC hdc_window, HDC hdc, int index )
     RECT rc;\r
     SIZE sz;\r
 \r
+\r
     POINT pt;\r
     int backColor = whitePieceColor; \r
     int foreColor = blackPieceColor;\r
index 4455d32..7e06085 100644 (file)
@@ -90,7 +90,7 @@ BEGIN
     PUSHBUTTON      "Cancel",IDCANCEL,195,190,40,14\r
 END\r
 \r
-DLG_LoadOptions DIALOG DISCARDABLE  10, 18, 170, 261\r
+DLG_LoadOptions DIALOG DISCARDABLE  10, 18, 170, 281\r
 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU\r
 CAPTION "Load Game Options"\r
 FONT 8, "MS Sans Serif"\r
@@ -125,8 +125,10 @@ BEGIN
                     BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,4,214,160,10\r
     CONTROL         "Also match &left-right mirror image",OPT_Mirror,"Button",\r
                     BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,4,227,160,10\r
-    PUSHBUTTON      "OK",IDOK,56,242,50,14,WS_GROUP\r
-    PUSHBUTTON      "Cancel",IDCANCEL,112,242,50,14\r
+    LTEXT           "final piece count",OPT_Ranget,46,242,94,8,NOT WS_GROUP\r
+    EDITTEXT        OPT_Range,16,242,28,14,ES_AUTOHSCROLL\r
+    PUSHBUTTON      "OK",IDOK,56,262,50,14,WS_GROUP\r
+    PUSHBUTTON      "Cancel",IDCANCEL,112,262,50,14\r
 END\r
 \r
 DLG_SaveOptions DIALOG DISCARDABLE  6, 17, 218, 119\r
index 977c0c6..2c92e4d 100644 (file)
@@ -2535,6 +2535,7 @@ LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
     SetDlgItemInt(hDlg, OPT_Stretch, appData.stretch, FALSE);\r
     CheckDlgButton(hDlg, OPT_Reversed, appData.ignoreColors);\r
     CheckDlgButton(hDlg, OPT_Mirror, appData.findMirror);\r
+    SetDlgItemText(hDlg, OPT_Range,  "");\r
     switch (appData.searchMode) {\r
     case 1:\r
       CheckDlgButton(hDlg, OPT_Exact, TRUE);\r
@@ -2579,6 +2580,10 @@ LoadOptions(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       appData.searchMode = LoadOptionsWhichRadio(hDlg);\r
       appData.ignoreColors = IsDlgButtonChecked(hDlg, OPT_Reversed);\r
       appData.findMirror   = IsDlgButtonChecked(hDlg, OPT_Mirror);\r
+      appData.eloThreshold1 = GetDlgItemText(hDlg, OPT_Range, buf, MSG_SIZ);\r
+      appData.minPieces = appData.maxPieces = 0;\r
+      sscanf(buf, "%d-%d", appData.minPieces, appData.maxPieces);\r
+      if(appData.maxPieces < appData.minPieces) appData.maxPieces = appData.minPieces;\r
       EndDialog(hDlg, TRUE);\r
       return TRUE;\r
 \r