From 0733495e0c47ce7590d799cafa9d1d1f9906ef41 Mon Sep 17 00:00:00 2001
From: H.G.Muller <hgm@hgm-xboard.(none)>
Date: Fri, 7 Mar 2014 13:30:14 +0100
Subject: [PATCH] Improve calculation of thinking time in sudden-death games

GNU Chess seems to assume a session length of 50 moves in Fischer time
controls, and would be taken by surprise by the fact that it would not
receive new time after that. This is pretty fatal in sudden-death game,
when there is no time increment from which it could do the remaining
moves. So for sudden-death games in XBoard mode it now calculates the
thinking time as if there are at least still 30 moves to go.
---
 gnushogi/rawdsp.c  |    7 ++++++-
 gnushogi/tcontrl.c |   10 ++++++++--
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/gnushogi/rawdsp.c b/gnushogi/rawdsp.c
index 45c2d8a..a63f86d 100644
--- a/gnushogi/rawdsp.c
+++ b/gnushogi/rawdsp.c
@@ -761,8 +761,13 @@ Raw_SelectLevel(char *sx)
         if (sscanf(sx, "%d %d %d", &mps, &min, &inc) != 3)
             sscanf(sx, "%d %d:%d %d", &mps, &min, &sec, &inc);
         TCminutes = min; TCseconds = sec;
-        TCadd = inc*100; TCmoves = mps ? mps : 50;
+        TCadd = inc*100; TCmoves = mps;
         MaxResponseTime = 0; TCflag = true;
+        if (!mps) /* Fischer TC or sudden death */
+        {
+            TCmoves = 50;
+            TCflag = 2; /* kludge to requests special calculation of ResponseTime */
+        }
     }
 
     TimeControl.clock[black] = TimeControl.clock[white] = 0;
diff --git a/gnushogi/tcontrl.c b/gnushogi/tcontrl.c
index 4e1da41..afdb32c 100644
--- a/gnushogi/tcontrl.c
+++ b/gnushogi/tcontrl.c
@@ -163,11 +163,14 @@ void SetResponseTime(short side)
             {
                 short rtf = in_opening_stage ? 8 : 2;
                 short tcq = in_opening_stage ? 2 : 4;
+                int moves = TimeControl.moves[side];
 
                 if(!xboard) /* no pre-add of increment in XBoard mode */
                     TimeControl.clock[side] += TCadd;
+                if(TCflag == 2 && TCadd == 0) /* sudden death */
+                    moves = (moves < 30 ? 30 : moves);
                 ResponseTime = (TimeControl.clock[side])
-                    / (((TimeControl.moves[side]) * rtf) + 1);
+                    / (moves * rtf + 1);
                 TCleft = (long)ResponseTime / tcq;
                 ResponseTime += TCadd / 2;
             }
@@ -253,12 +256,15 @@ void SetResponseTime(short side)
         else
         {
             /* calculate avg time per move remaining */
+            int moves = TimeControl.moves[side];
 
             if(!xboard) /* no pre-add of increment in XBoard mode */
                 TimeControl.clock[side] += TCadd;
 
+            if(TCflag == 2 && TCadd == 0) /* sudden death */
+                moves = (moves < 30 ? 30 : moves);
             ResponseTime = (TimeControl.clock[side])
-                / (((TimeControl.moves[side]) * 2) + 1);
+                / (moves * 2 + 1);
             TCleft = (int) ResponseTime / 3;
             ResponseTime += TCadd / 2;
 
-- 
1.7.0.4