Dynamic Seek Graph
authorH.G. Muller <h.g.muller@hccnet.nl>
Thu, 4 Feb 2010 21:45:01 +0000 (22:45 +0100)
committerArun Persaud <arun@nubati.net>
Sat, 6 Feb 2010 21:04:17 +0000 (13:04 -0800)
The new option -autoRefresh sets FICS and ICC to report removal of seek
ads, and then removes those from the Seek Graph. New seek ads are added
to the graph, as soon as the ICS reports them.

args.h
backend.c
common.h

diff --git a/args.h b/args.h
index 305906e..1c6053e 100644 (file)
--- a/args.h
+++ b/args.h
@@ -243,6 +243,7 @@ ArgDescriptor argDescriptors[] = {
   { "icshelper", ArgFilename, (void *) &appData.icsHelper, FALSE, (ArgIniType) "" },
   { "seekGraph", ArgBoolean, (void *) &appData.seekGraph, TRUE, (ArgIniType) FALSE },
   { "sg", ArgTrue, (void *) &appData.seekGraph, FALSE, INVALID },
+  { "autoRefresh", ArgBoolean, (void *) &appData.autoRefresh, TRUE, (ArgIniType) FALSE },
   { "gateway", ArgString, (void *) &appData.gateway, FALSE, (ArgIniType) "" },
   { "loadGameFile", ArgFilename, (void *) &appData.loadGameFile, FALSE, (ArgIniType) "" },
   { "lgf", ArgFilename, (void *) &appData.loadGameFile, FALSE, INVALID },
index caa8e19..dedf333 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -2071,6 +2071,7 @@ Boolean seekGraphUp;
 char *seekAdList[MAX_SEEK_ADS];
 int ratingList[MAX_SEEK_ADS], xList[MAX_SEEK_ADS], yList[MAX_SEEK_ADS], seekNrList[MAX_SEEK_ADS], zList[MAX_SEEK_ADS];
 float tcList[MAX_SEEK_ADS];
+char colorList[MAX_SEEK_ADS];
 int nrOfSeekAds = 0;
 int minRating = 1010, maxRating = 2800;
 int hMargin = 10, vMargin = 20, h, w;
@@ -2088,14 +2089,14 @@ PlotSeekAd(int i)
        if(tc > 95.) tc = 95.;
        x = (w-hMargin)* log(tc)/log(100.) + hMargin;
        y = ((double)r - minRating)/(maxRating - minRating)
-           * (h-vMargin-squareSize/8) + vMargin;
+           * (h-vMargin-squareSize/8-1) + vMargin;
        if(ratingList[i] < 0) y = vMargin + squareSize/4;
        if(strstr(seekAdList[i], " u ")) color = 1;
        if(!strstr(seekAdList[i], "lightning") && // for now all wilds same color
           !strstr(seekAdList[i], "bullet") &&
           !strstr(seekAdList[i], "blitz") &&
           !strstr(seekAdList[i], "standard") ) color = 2;
-       DrawSeekDot(xList[i]=x+3*color, yList[i]=h-1-y, color);
+       DrawSeekDot(xList[i]=x+3*color, yList[i]=h-1-y, colorList[i]=color);
 }
 
 void
@@ -2121,6 +2122,40 @@ AddAd(char *handle, char *rating, int base, int inc,  char rated, char *type, in
        }
 }
 
+void
+EraseSeekDot(int i)
+{
+    int x = xList[i], y = yList[i], d=squareSize/4, k;
+    DrawSeekBackground(x-squareSize/8, y-squareSize/8, x+squareSize/8+1, y+squareSize/8+1);
+    if(x < hMargin+d) DrawSeekAxis(hMargin, y-squareSize/8, hMargin, y+squareSize/8+1);
+    // now replot every dot that overlapped
+    for(k=0; k<nrOfSeekAds; k++) if(k != i) {
+       int xx = xList[k], yy = yList[k];
+       if(xx <= x+d && xx > x-d && yy <= y+d && yy > y-d)
+           DrawSeekDot(xx, yy, colorList[k]);
+    }
+}
+
+void
+RemoveSeekAd(int nr)
+{
+       int i;
+       for(i=0; i<nrOfSeekAds; i++) if(seekNrList[i] == nr) {
+           EraseSeekDot(i);
+           if(seekAdList[i]) free(seekAdList[i]);
+           seekAdList[i] = seekAdList[--nrOfSeekAds];
+           seekNrList[i] = seekNrList[nrOfSeekAds];
+           ratingList[i] = ratingList[nrOfSeekAds];
+           colorList[i]  = colorList[nrOfSeekAds];
+           tcList[i] = tcList[nrOfSeekAds];
+           xList[i]  = xList[nrOfSeekAds];
+           yList[i]  = yList[nrOfSeekAds];
+           zList[i]  = zList[nrOfSeekAds];
+           seekAdList[nrOfSeekAds] = NULL;
+           break;
+       }
+}
+
 Boolean
 MatchSoughtLine(char *line)
 {
@@ -2151,7 +2186,7 @@ DrawSeekGraph()
     DrawSeekAxis(hMargin, h-1-vMargin, w-5, h-1-vMargin);
     DrawSeekAxis(hMargin, h-1-vMargin, hMargin, 5);
     for(i=0; i<4000; i+= 100) if(i>=minRating && i<maxRating) {
-       int yy =((double)i - minRating)/(maxRating - minRating)*(h-vMargin-squareSize/8) + vMargin;
+       int yy =((double)i - minRating)/(maxRating - minRating)*(h-vMargin-squareSize/8-1) + vMargin;
        yy = h-1-yy;
        DrawSeekAxis(hMargin+5*(i%500==0), yy, hMargin-5, yy); // rating ticks
        if(i%500 == 0) {
@@ -2456,12 +2491,16 @@ read_from_ics(isr, closure, data, count, error)
                  sprintf(str,
                          "/set-quietly interface %s\n/set-quietly style 12\n",
                          programVersion);
+                 if(appData.seekGraph && appData.autoRefresh) // [HGM] seekgraph
+                     strcat(str, "/set-2 51 1\n/set seek 1\n");
                } else if (ics_type == ICS_CHESSNET) {
                  sprintf(str, "/style 12\n");
                } else {
                  strcpy(str, "alias $ @\n$set interface ");
                  strcat(str, programVersion);
                  strcat(str, "\n$iset startpos 1\n$iset ms 1\n");
+                 if(appData.seekGraph && appData.autoRefresh) // [HGM] seekgraph
+                     strcat(str, "$iset seekremove 1\n$set seek 1\n");
 #ifdef WIN32
                  strcat(str, "$iset nohighlight 1\n");
 #endif
@@ -2590,6 +2629,7 @@ read_from_ics(isr, closure, data, count, error)
                    next_out = leftover_start = i;
                    started = STARTED_CHATTER;
                    suppressKibitz = TRUE;
+                   continue;
                }
                if((gameMode == IcsIdle || gameMode == BeginningOfGame)
                        && looking_at(buf, &i, "* ads displayed")) {
@@ -2598,6 +2638,27 @@ read_from_ics(isr, closure, data, count, error)
                    DrawSeekGraph();
                    continue;
                }
+               if(appData.autoRefresh) {
+                   if(looking_at(buf, &i, "* (*) seeking * * * * *\"play *\" to respond)\n")) {
+                       int s = (ics_type == ICS_ICC); // ICC format differs
+                       if(seekGraphUp)
+                       AddAd(star_match[0], star_match[1], atoi(star_match[2+s]), atoi(star_match[3+s]), 
+                             star_match[4+s][0], star_match[5-3*s], atoi(star_match[7]), TRUE);
+                       looking_at(buf, &i, "*% "); // eat prompt
+                       next_out = i; // suppress
+                       continue;
+                   }
+                   if(looking_at(buf, &i, "Ads removed: *\n") || looking_at(buf, &i, "\031(51 * *\031)")) {
+                       char *p = star_match[0];
+                       while(*p) {
+                           if(seekGraphUp) RemoveSeekAd(atoi(p));
+                           while(*p && *p++ != ' '); // next
+                       }
+                       looking_at(buf, &i, "*% "); // eat prompt
+                       next_out = i;
+                       continue;
+                   }
+               }
            }
 
            /* skip formula vars */
@@ -5913,7 +5974,7 @@ void LeftClick(ClickType clickType, int xPix, int yPix)
     static int second = 0, promotionChoice = 0;
     char promoChoice = NULLCHAR;
 
-    if(appData.seekGraph && appData.icsActive && 
+    if(appData.seekGraph && appData.icsActive && loggedOn &&
        (gameMode == BeginningOfGame || gameMode == IcsIdle)) {
        SeekGraphClick(clickType, xPix, yPix, FALSE);
        return;
index 9474c88..f97f16c 100644 (file)
--- a/common.h
+++ b/common.h
@@ -414,6 +414,7 @@ typedef struct {
     Boolean icsInputBox;
     Boolean useTelnet;
     Boolean seekGraph;
+    Boolean autoRefresh;
     char *telnetProgram;
     char *gateway;
     char *loadGameFile;