improve thinking-output for mulit-variant
authorH.G. Muller <h.g.muller@hccnet.nl>
Sun, 15 Nov 2009 06:06:58 +0000 (22:06 -0800)
committerArun Persaud <arun@nubati.net>
Sun, 15 Nov 2009 06:11:09 +0000 (22:11 -0800)
Improve multi-variant support by sorting the Thinking-Output lines of the most recent depth by score in the Engine-Output window.

winboard/wengineo.c
xengineoutput.c

index 4876a70..936fcd8 100644 (file)
@@ -286,9 +286,9 @@ static void ResizeWindowControls( HWND hDlg, int mode )
 }\r
 \r
 // front end. Actual printing of PV lines into the output field\r
-static void InsertIntoMemo( int which, char * text )\r
+static void InsertIntoMemo( int which, char * text, int where )\r
 {\r
-    SendMessage( outputField[which][nMemo], EM_SETSEL, 0, 0 );\r
+    SendMessage( outputField[which][nMemo], EM_SETSEL, where, where ); // [HGM] multivar: choose insertion point\r
 \r
     SendMessage( outputField[which][nMemo], EM_REPLACESEL, (WPARAM) FALSE, (LPARAM) text );\r
 }\r
@@ -434,6 +434,8 @@ void DoClearMemo(int which)
 \r
 //------------------------ pure back-end routines -------------------------------\r
 \r
+#define MAX_VAR 400\r
+static int scores[MAX_VAR], textEnd[MAX_VAR], curDepth[2], nrVariations[2];\r
 \r
 // back end, due to front-end wrapper for SetWindowText, and new SetIcon arguments\r
 static void SetEngineState( int which, int state, char * state_data )\r
@@ -524,7 +526,7 @@ void EngineOutputUpdate( FrontEndProgramStats * stats )
         clearMemo = TRUE;\r
     }\r
 \r
-    if( clearMemo ) DoClearMemo(which);\r
+    if( clearMemo ) { DoClearMemo(which); nrVariations[which] = 0; }\r
 \r
     /* Update */\r
     lastDepth[which] = depth == 1 && ed.nodes == 0 ? 0 : depth; // [HGM] info-line kudge\r
@@ -671,6 +673,38 @@ static void SetEngineColorIcon( int which )
 \r
 #define MAX_NAME_LENGTH 32\r
 \r
+// [HGM] multivar: sort Thinking Output within one depth on score\r
+\r
+static int InsertionPoint( int len, EngineOutputData * ed )\r
+{\r
+       int i, offs = 0, newScore = ed->score, n = ed->which;\r
+\r
+       if(ed->nodes == 0 && ed->score == 0 && ed->time == 0)\r
+               newScore = 1e6; // info lines inserted on top\r
+       if(ed->depth != curDepth[n]) { // depth has changed\r
+               curDepth[n] = ed->depth;\r
+               nrVariations[n] = 0; // throw away everything we had\r
+       }\r
+       // loop through all lines. Note even / odd used for different panes\r
+       for(i=nrVariations[n]-2; i>=0; i-=2) {\r
+               // put new item behind those we haven't looked at\r
+               offs = textEnd[i+n];\r
+               textEnd[i+n+2] = offs + len;\r
+               scores[i+n+2] = newScore;\r
+               if(newScore < scores[i+n]) break;\r
+               // if it had higher score as previous, move previous in stead\r
+               scores[i+n+2] = scores[i+n];\r
+               textEnd[i+n+2] = textEnd[i+n] + len;\r
+       }\r
+       if(i<0) {\r
+               offs = 0;\r
+               textEnd[n] = offs + len;\r
+               scores[n] = newScore;\r
+       }\r
+       nrVariations[n] += 2;\r
+      return offs;\r
+}\r
+\r
 // pure back end, now SetWindowText is called via wrapper DoSetWindowText\r
 static void UpdateControls( EngineOutputData * ed )\r
 {\r
@@ -800,7 +834,7 @@ static void UpdateControls( EngineOutputData * ed )
         strcat( buf + buflen, "\r\n" );\r
 \r
         /* Update memo */\r
-        InsertIntoMemo( ed->which, buf );\r
+        InsertIntoMemo( ed->which, buf, InsertionPoint(strlen(buf), ed) );\r
     }\r
 \r
     /* Colors */\r
@@ -831,5 +865,5 @@ void OutputKibitz(int window, char *text)
        DoSetWindowText(1, nLabel, gameMode == IcsPlayingBlack ? gameInfo.white : gameInfo.black); // opponent name\r
        SetIcon( 1, nColorIcon,  gameMode == IcsPlayingBlack ? nColorWhite : nColorBlack);\r
        SetIcon( 1, nStateIcon,  nClear);\r
-       InsertIntoMemo(window-1, text);\r
+       InsertIntoMemo(window-1, text, 0); // [HGM] multivar: always at top\r
 }\r
index 2df13d3..8ba8a7e 100644 (file)
@@ -226,13 +226,13 @@ void DoSetWindowText(int which, int field, char *s_label)
        XtSetValues(outputField[which][field], &arg, 1);
 }
 
-static void InsertIntoMemo( int which, char * text )
+static void InsertIntoMemo( int which, char * text, int where )
 {
        Arg arg; XawTextBlock t; Widget edit;
 
        t.ptr = text; t.firstPos = 0; t.length = strlen(text); t.format = XawFmt8Bit;
        edit = XtNameToWidget(engineOutputShell, which ? "*form2.text" : "*form.text");
-       XawTextReplace(edit, 0, 0, &t);
+       XawTextReplace(edit, where, where, &t);
 //     XtSetArg(arg, XtNstring, (XtArgVal) text);
 //     XtSetValues(outputField[which][nMemo], &arg, 1);
 }
@@ -558,6 +558,9 @@ void EngineOutputPopDown()
 //------------------------ pure back-end routines -------------------------------
 
 
+#define MAX_VAR 400
+static int scores[MAX_VAR], textEnd[MAX_VAR], curDepth[2], nrVariations[2];
+
 // back end, due to front-end wrapper for SetWindowText, and new SetIcon arguments
 static void SetEngineState( int which, int state, char * state_data )
 {
@@ -792,6 +795,38 @@ static void SetEngineColorIcon( int which )
 
 #define MAX_NAME_LENGTH 32
 
+// [HGM] multivar: sort Thinking Output within one depth on score
+
+static int InsertionPoint( int len, EngineOutputData * ed )
+{
+       int i, offs = 0, newScore = ed->score, n = ed->which;
+
+       if(ed->nodes == 0 && ed->score == 0 && ed->time == 0)
+               newScore = 1e6; // info lines inserted on top
+       if(ed->depth != curDepth[n]) { // depth has changed
+               curDepth[n] = ed->depth;
+               nrVariations[n] = 0; // throw away everything we had
+       }
+       // loop through all lines. Note even / odd used for different panes
+       for(i=nrVariations[n]-2; i>=0; i-=2) {
+               // put new item behind those we haven't looked at
+               offs = textEnd[i+n];
+               textEnd[i+n+2] = offs + len;
+               scores[i+n+2] = newScore;
+               if(newScore < scores[i+n]) break;
+               // if it had higher score as previous, move previous in stead
+               scores[i+n+2] = scores[i+n];
+               textEnd[i+n+2] = textEnd[i+n] + len;
+       }
+       if(i<0) {
+               offs = 0;
+               textEnd[n] = offs + len;
+               scores[n] = newScore;
+       }
+       nrVariations[n] += 2;
+      return offs;
+}
+
 // pure back end, now SetWindowText is called via wrapper DoSetWindowText
 static void UpdateControls( EngineOutputData * ed )
 {
@@ -920,7 +955,7 @@ static void UpdateControls( EngineOutputData * ed )
         strcat( buf + buflen, "\n" );
 
         /* Update memo */
-        InsertIntoMemo( ed->which, buf );
+        InsertIntoMemo( ed->which, buf, InsertionPoint(strlen(buf), ed) );
     }
 
     /* Colors */
@@ -966,5 +1001,5 @@ void OutputKibitz(int window, char *text)
        DoSetWindowText(1, nLabel, gameMode == IcsPlayingBlack ? gameInfo.white : gameInfo.black); // opponent name
        SetIcon( 1, nColorIcon,  gameMode == IcsPlayingBlack ? nColorWhite : nColorBlack);
        SetIcon( 1, nStateIcon,  nClear);
-       InsertIntoMemo(window-1, text);
+       InsertIntoMemo(window-1, text, 0);
 }