add undo turn feature
authorLaurent Mazet <mazet@softndesign.org>
Wed, 3 Jul 2024 21:13:37 +0000 (23:13 +0200)
committerLaurent Mazet <mazet@softndesign.org>
Wed, 3 Jul 2024 21:13:37 +0000 (23:13 +0200)
checkers.c
function.c
function.h
type.h

index 72834da3d56de660edfec0af01fb6a44dee530d0..76b3ea03efee0ec030c82e7f8cc3395da93e7b8f 100644 (file)
@@ -176,6 +176,9 @@ int main (int argc, char *argv[])
     int ymsg = max (yboard + xoffset + 1 + board->ysize, yhelp + lhelp + yoffset + 1);
     int lmsg = xhelp - xmsg + strmaxlen (help, '\n');
 
+    /* cache */
+    cache_t *cache = initcache (board);
+
     /* event loop */
     int mode = 0;
     int stop = 0;
@@ -196,11 +199,10 @@ int main (int argc, char *argv[])
                 sprintf (msg + strlen (msg), "Begin turn (%d)", nbmaxjumps);
                 break;
             case 1:
-            case 2:
                 jump = cursorwindow (board, xcursor, ycursor, 1);
                 sprintf (msg + strlen (msg), "Choose next (%d)", nbmaxjumps);
                 break;
-            case 3:
+            case 2:
                 sprintf (msg + strlen (msg), "Validate turn");
                 break;
             }
@@ -231,13 +233,18 @@ int main (int argc, char *argv[])
                 domove (board, &xcursor, &ycursor, 0);
                 break;
             case 1:
-            case 2:
                 if ((jump) && (testjump (board, xcursor, ycursor, 0))) {
+                    pushcache (cache, board, xcursor, ycursor);
+                    board = copyboard (board);
                     dopetjump (board, &xcursor, &ycursor, 0);
-                    mode = (testalljumps (board, xcursor, ycursor)) ? 2 : 3;
+                    if (!testalljumps (board, xcursor, ycursor)) {
+                        mode = 2;
+                    }
                 } else if ((player == 1) && (!jump) && (getvalue (board, xcursor + 1, ycursor - 1) == '.')) {
+                    pushcache (cache, board, xcursor, ycursor);
+                    board = copyboard (board);
                     dopetmove (board, &xcursor, &ycursor, 0);
-                    mode = 3;
+                    mode = 2;
                 }
                 break;
             }
@@ -249,13 +256,18 @@ int main (int argc, char *argv[])
                 domove (board, &xcursor, &ycursor, 1);
                 break;
             case 1:
-            case 2:
                 if ((jump) && (testjump (board, xcursor, ycursor, 1))) {
+                    pushcache (cache, board, xcursor, ycursor);
+                    board = copyboard (board);
                     dopetjump (board, &xcursor, &ycursor, 1);
-                    mode = (testalljumps (board, xcursor, ycursor)) ? 2 : 3;
+                    if (!testalljumps (board, xcursor, ycursor)) {
+                        mode = 2;
+                    }
                 } else if ((player == 1) && (!jump) && (getvalue (board, xcursor - 1, ycursor - 1) == '.')) {
+                    pushcache (cache, board, xcursor, ycursor);
+                    board = copyboard (board);
                     dopetmove (board, &xcursor, &ycursor, 1);
-                    mode = 3;
+                    mode = 2;
                 }
                 break;
             }
@@ -267,13 +279,18 @@ int main (int argc, char *argv[])
                 domove (board, &xcursor, &ycursor, 2);
                 break;
             case 1:
-            case 2:
                 if ((jump) && (testjump (board, xcursor, ycursor, 2))) {
+                    pushcache (cache, board, xcursor, ycursor);
+                    board = copyboard (board);
                     dopetjump (board, &xcursor, &ycursor, 2);
-                    mode = (testalljumps (board, xcursor, ycursor)) ? 2 : 3;
+                    if (!testalljumps (board, xcursor, ycursor)) {
+                        mode = 2;
+                    }
                 } else if ((player == 0) && (!jump) && (getvalue (board, xcursor - 1, ycursor + 1) == '.')) {
+                    pushcache (cache, board, xcursor, ycursor);
+                    board = copyboard (board);
                     dopetmove (board, &xcursor, &ycursor, 2);
-                    mode = 3;
+                    mode = 2;
                 }
                 break;
             }
@@ -285,13 +302,18 @@ int main (int argc, char *argv[])
                 domove (board, &xcursor, &ycursor, 3);
                 break;
             case 1:
-            case 2:
                 if ((jump) && (testjump (board, xcursor, ycursor, 3))) {
+                    pushcache (cache, board, xcursor, ycursor);
+                    board = copyboard (board);
                     dopetjump (board, &xcursor, &ycursor, 3);
-                    mode = (testalljumps (board, xcursor, ycursor)) ? 2 : 3;
+                    if (!testalljumps (board, xcursor, ycursor)) {
+                        mode = 2;
+                    }
                 } else if ((player == 0) && (!jump) && (getvalue (board, xcursor + 1, ycursor + 1) == '.')) {
+                    pushcache (cache, board, xcursor, ycursor);
+                    board = copyboard (board);
                     dopetmove (board, &xcursor, &ycursor, 3);
-                    mode = 3;
+                    mode = 2;
                 }
                 break;
             }
@@ -316,8 +338,9 @@ int main (int argc, char *argv[])
         case '\n':
         case '\r':
         case 'v':
-            if (mode == 3) {
+            if (mode == 2) {
                 player = (player == 0) ? 1 : 0;
+                emptycache (cache);
                 mode = 0;
             }
             break;
@@ -326,6 +349,10 @@ int main (int argc, char *argv[])
         case 127:
         case '\b':
         case 'x':
+            if (cache->board) {
+                board = popcache (cache, &xcursor, &ycursor);
+                mode = 1;
+            }
             break;
         //case ERR:
         //default:
@@ -333,7 +360,7 @@ int main (int argc, char *argv[])
     }
 
     endwin ();
-
+    freecache (cache);
     freeboard (board);
 
     return 0;
index f339d0fcacb5e7d04a599034efcf12bc0926cce1..1bb7ceead15c5bf1635508291db5bbab0c875b86 100644 (file)
@@ -405,4 +405,52 @@ int globalmaxjumps (board_t *board, int id)
     return maxjumps;
 }
 
+cache_t *initcache (board_t *board)
+{
+    cache_t *cache = (cache_t *) calloc (board->width / 2 * (board->height - 1) / 2, sizeof (cache_t));
+    CHECKALLOC (cache);
+    return cache;
+}
+
+board_t *pushcache (cache_t *cache, board_t *board, int xcursor, int ycursor)
+{
+    while (cache->board != NULL) {
+        cache++;
+    }
+    cache->board = board;
+    cache->xcursor = xcursor;
+    cache->ycursor = ycursor;
+    return board;
+}
+
+board_t *popcache (cache_t *cache, int *xcursor, int *ycursor)
+{
+    board_t *board = NULL;
+    if (cache->board != NULL) {
+        while ((cache + 1)->board != NULL) {
+            cache++;
+        }
+        board = cache->board;
+        *xcursor = cache->xcursor;
+        *ycursor = cache->ycursor;
+        cache->board = NULL;
+    }
+    return board;
+}
+
+void emptycache (cache_t *cache)
+{
+    while (cache->board != NULL) {
+        free (cache->board);
+        cache->board = NULL;
+        cache++;
+    }
+}
+
+void freecache (cache_t *cache)
+{
+    emptycache (cache);
+    free (cache);
+}
+
 /* vim: set ts=4 sw=4 et: */
index ef405c30a2110be20a5139e2749dabc49b78505c..775d00867e14f418116b24be7708ee6332e7961e 100644 (file)
@@ -53,6 +53,16 @@ int evalmaxjumps (board_t *board, int x, int y, int id);
 
 int globalmaxjumps (board_t *board, int id);
 
+cache_t *initcache (board_t *board);
+
+board_t *pushcache (cache_t *cache, board_t *board, int xcursor, int ycursor);
+
+board_t *popcache (cache_t *cache, int *xcursor, int *ycursor);
+
+void emptycache (cache_t *cache);
+
+void freecache (cache_t *cache);
+
 #endif /* __FUNCTION_H__ */
 
 /* vim: set ts=4 sw=4 et: */
diff --git a/type.h b/type.h
index 763b209863980e93da142a2c02c734f5daf2546f..5d1e386218faad8a4b04ba42d12db74d5a77081c 100644 (file)
--- a/type.h
+++ b/type.h
@@ -13,6 +13,12 @@ typedef struct {
     int turn;
 } board_t;
 
+typedef struct {
+    board_t *board;
+    int xcursor;
+    int ycursor;
+} cache_t;
+
 #endif /* __TYPE_H__ */
 
 /* vim: set ts=4 sw=4 et: */