save and restore work fine
authorLaurent Mazet <mazet@softndesign.org>
Sat, 31 Aug 2024 22:21:40 +0000 (00:21 +0200)
committerLaurent Mazet <mazet@softndesign.org>
Sat, 31 Aug 2024 22:21:40 +0000 (00:21 +0200)
function.c
function.h
snake.c
type.h

index 63e8c564974d700605e3824d8d4b1ffe04761ab2..39316be9b7f10b3c4f667ee7f1317c42bf850b77 100644 (file)
@@ -34,8 +34,30 @@ board_t *initboard (int width, int height)
     board->ysize = board->height = height;
     board->xoffset = 0;
     board->yoffset = 0;
-    board->current = -1;
-    board->next = -1;
+    return board;
+}
+
+board_t *setscale (board_t *board, int scale)
+{
+    board->scale = scale;
+    switch (scale) {
+    case 0:
+        board->xsize = board->width;
+        board->ysize = board->height;
+        break;
+    case 1:
+        board->xsize = board->width * 2;
+        board->ysize = board->height;
+        break;
+    case 2:
+        board->xsize = board->width * 2;
+        board->ysize = board->height * 2;
+        break;
+    case 3:
+        board->xsize = board->width * 3;
+        board->ysize = board->height * 2;
+        break;
+    }
     return board;
 }
 
@@ -89,23 +111,48 @@ int _makecomments (char *buffer, board_t *board)
     return l;
 }
 
-char *saveboard (board_t *board)
+char _itoz (int x)
+{
+    return (x < 10) ? '0' + x : 'A' + x - 10;
+}
+
+int _ztoi (char x)
 {
-    int size = 6 * (8 + 3) + 8 + board->width * board->height + 1;
-    VERBOSE (INFO, size += board->height * (8 + board->width));
+    return (x > '9') ? x - 'A' + 10 : x - '0';
+}
+
+int _sprinttab (char *buffer, char *name, int *tab, int nb)
+{
+    int i;
+    int l = sprintf (buffer, "%s: \"", name);
+    for (i = 0; i < nb; i++) {
+        l += sprintf (buffer + l, "%c", _itoz (tab[i]));
+    }
+    l += sprintf (buffer + l, "\"\n");
+    return l;
+}
+
+char *saveboard (data_t *data)
+{
+    int size = 5 * (7 + 3 + 3);
+    size += 5 + 5 + data->board->width * data->board->height + 1;
+    size += 2 * (5 + 5 + data->snake->length + 1);
+    VERBOSE (INFO, size += data->board->height * (8 + data->board->width));
 
     char *buffer = (char *) calloc (size, 1);
     CHECKALLOC (buffer);
 
-    int l = sprintf (buffer, "width: %d\n", board->width);
-    l += sprintf (buffer + l, "height: %d\n", board->height);
-    l += sprintf (buffer + l, "tab: \"%s\"\n", board->tab);
-    l += sprintf (buffer + l, "current: %d\n", board->current);
-    l += sprintf (buffer + l, "lines: %d\n", board->lines);
-    l += sprintf (buffer + l, "next: %d\n", board->next);
-    l += sprintf (buffer + l, "score: %d\n", board->score);
+    int l = sprintf (buffer, "direction: %d\n", data->snake->dir);
+    l += sprintf (buffer + l, "duration: %d\n", data->duration);
+    l += sprintf (buffer + l, "height: %d\n", data->board->height);
+    l += sprintf (buffer + l, "length: %d\n", data->snake->length);
+    l += sprintf (buffer + l, "score: %d\n", data->score);
+    l += sprintf (buffer + l, "tab: \"%s\"\n", data->board->tab);
+    l += sprintf (buffer + l, "width: %d\n", data->board->width);
+    l += _sprinttab (buffer + l, "xsnake", data->snake->x, data->snake->length);
+    l += _sprinttab (buffer + l, "ysnake", data->snake->y, data->snake->length);
 
-    VERBOSE (INFO, _makecomments (buffer + l, board));
+    VERBOSE (INFO, _makecomments (buffer + l, data->board));
 
     return buffer;
 }
@@ -165,15 +212,17 @@ char *atos (char *str)
     return ret;
 }
 
-board_t *loadboard (char *str)
+data_t *loaddata (char *str)
 {
-    int width = 0;
+    int direction = 0;
+    int duration = 0;
     int height = 0;
-    char *tab = NULL;
-    int current = -1;
-    int lines = 0;
-    int next = -1;
+    int length = 0;
     int score = 0;
+    char *tab = NULL;
+    int width = 0;
+    char *xsnake = NULL;
+    char *ysnake = NULL;
 
     char *saveptr1, *saveptr2;
 
@@ -187,20 +236,24 @@ board_t *loadboard (char *str)
             value++;
         }
 
-        if (strcmp (keyword,  "width") == 0) {
-            width = atoi (value);
+        if (strcmp (keyword,  "direction") == 0) {
+            direction = atoi (value);
+        } else if (strcmp (keyword,  "duration") == 0) {
+            duration = atoi (value);
         } else if (strcmp (keyword,  "height") == 0) {
             height = atoi (value);
-        } else if (strcmp (keyword,  "tab") == 0) {
-            tab = atos (value);
-        } else if (strcmp (keyword,  "current") == 0) {
-            current = atoi (value);
-        } else if (strcmp (keyword,  "lines") == 0) {
-            lines = atoi (value);
-        } else if (strcmp (keyword,  "next") == 0) {
-            next = atoi (value);
+        } else if (strcmp (keyword,  "length") == 0) {
+            length = atoi (value);
         } else if (strcmp (keyword,  "score") == 0) {
             score = atoi (value);
+        } else if (strcmp (keyword,  "tab") == 0) {
+            tab = atos (value);
+        } else if (strcmp (keyword,  "width") == 0) {
+            width = atoi (value);
+        } else if (strcmp (keyword,  "xsnake") == 0) {
+            xsnake = atos (value);
+        } else if (strcmp (keyword,  "ysnake") == 0) {
+            ysnake = atos (value);
         } else if (strcmp (keyword,  "rem") == 0) {
             /* nothing to do with remark */
         } else {
@@ -210,17 +263,26 @@ board_t *loadboard (char *str)
         line = strtok_r (NULL, "\n", &saveptr1);
     }
 
-    board_t *board = NULL;
-    if ((tab) && (strlen (tab) == (size_t)(width * height))) {
-        board = initboard (width, height);
-        memcpy (board->tab, tab, width * height);
-        board->current = current;
-        board->lines = lines;
-        board->next = next;
-        board->score = score;
+    data_t *data = NULL;
+    int maxlen = width * height;
+    VERBOSE (DEBUG, printf ("%d %d\n", strlen (tab), maxlen));
+    VERBOSE (DEBUG, printf ("%d %d %d\n", length, strlen (xsnake), strlen (ysnake)));
+    if ((tab) && (strlen (tab) == (size_t)maxlen) && (length <= maxlen) &&
+        (xsnake) && (strlen (xsnake) == (size_t)length) &&
+        (ysnake) && (strlen (ysnake) == (size_t)length)) {
+        int i;
+        data = initdata (width, height);
+        data->duration = duration;
+        data->score = score;
+        data->snake->dir = direction;
+        data->snake->length = length;
+        for (i = 0; i < length; i++) {
+            data->snake->x[i] = _ztoi (xsnake[i]);
+            data->snake->y[i] = _ztoi (ysnake[i]);
+        }
     }
 
-    return board;
+    return data;
 }
 
 snake_t *initsnake (board_t *board)
@@ -228,12 +290,12 @@ snake_t *initsnake (board_t *board)
     snake_t *snake = (snake_t *) calloc (1, sizeof (snake_t));
     CHECKALLOC (snake);
 
-    snake->maxlength = board->width * board->height + 1;
+    snake->maxlen = board->width * board->height + 1;
 
-    snake->x = (int *) calloc (snake->maxlength, sizeof (int));
+    snake->x = (int *) calloc (snake->maxlen, sizeof (int));
     CHECKALLOC (snake->x);
 
-    snake->y = (int *) calloc (snake->maxlength, sizeof (int));
+    snake->y = (int *) calloc (snake->maxlen, sizeof (int));
     CHECKALLOC (snake->y);
 
     snake->x[0] = board->width / 2 + 1;
@@ -356,4 +418,35 @@ void drawbonus (board_t *board, snake_t *snake, int malus, int bonus)
     }
 }
 
+data_t *initdata (int width, int height)
+{
+    data_t *data = (data_t *) calloc (1, sizeof (data_t));
+    CHECKALLOC (data);
+    data->board = initboard (width, height);
+    data->snake = initsnake (data->board);
+    return data;
+}
+
+data_t *createdata (board_t *board, snake_t *snake)
+{
+    data_t *data = NULL;
+    if (board->width * board->height + 1 == snake->maxlen) {
+        data = initdata (board->width, board->height);
+        memcpy (data->board->tab, board->tab , (board->width * board->height) * sizeof (char));
+        memcpy (data->snake->x, snake->x, snake->length * sizeof (int));
+        memcpy (data->snake->y, snake->y, snake->length * sizeof (int));
+        data->snake->length = snake->length;
+    }
+    return data;
+}
+
+void freedata (data_t *data)
+{
+    if (data) {
+        freeboard (data->board);
+        freesnake (data->snake);
+    }
+    free (data);
+}
+
 /* vim: set ts=4 sw=4 et: */
index 65da2491eeee50326165f2a6155a02ff48fb736a..96342f553eeee1899a2eb2933e7866e699e5ecd8 100644 (file)
@@ -23,13 +23,15 @@ int strmaxlen (char *str, char ch);
 
 board_t *initboard (int width, int height);
 
+board_t *setscale (board_t *board, int scale);
+
 board_t *applyscale (board_t *board, int scale);
 
 void freeboard (board_t *board);
 
 int _makecomments (char *buffer, board_t *board);
 
-char *saveboard (board_t *board);
+char *saveboard (data_t *data);
 
 int writedata (char *filename, char *data);
 
@@ -37,7 +39,7 @@ char *readdata (char *filename);
 
 char *atos (char *str);
 
-board_t *loadboard (char *str);
+data_t *loaddata (char *str);
 
 snake_t *initsnake (board_t *board);
 
@@ -47,6 +49,12 @@ int movesnake (board_t *board, snake_t *snake, int dir);
 
 void drawbonus (board_t *board, snake_t *snake, int malus, int bonus);
 
+data_t *initdata (int width, int height);
+
+data_t *createdata (board_t *board, snake_t *snake);
+
+void freedata (data_t *data);
+
 #endif /* __FUNCTION_H__ */
 
 /* vim: set ts=4 sw=4 et: */
diff --git a/snake.c b/snake.c
index 83d2a979ccadd3907dd39cd345d2eb30ac5322e5..24faa7b6b0c7341727713d7bfa25147f7569f441 100644 (file)
--- a/snake.c
+++ b/snake.c
@@ -111,6 +111,32 @@ int main (int argc, char *argv[])
     /* init seed */
     seed = newseed (seed);
 
+    /* init game */
+    int score = 0;
+    int duration = 0;
+    int whelp = strmaxlen (help, '\n');
+    board_t *board = NULL;
+    snake_t *snake = NULL;
+    if (filename) {
+        char *buffer = readdata (filename);
+        if (buffer == NULL) {
+            VERBOSE (ERROR, fprintf (stderr, "can't read file (%s)\n", filename));
+            return 1;
+        }
+        data_t *data = loaddata (buffer);
+        free (buffer);
+        if (data == NULL) {
+            VERBOSE (ERROR, fprintf (stderr, "incorrect file (%s)\n", filename));
+            return 1;
+        }
+        board = data->board;
+        setscale (board, scale);
+        duration = data->duration;
+        score = data->score;
+        snake = data->snake;
+        free (data);
+    }
+
     /* init curses window */
     initscr ();
     noecho ();
@@ -122,12 +148,13 @@ int main (int argc, char *argv[])
     halfdelay (1);
 
     /* load playground */
-    int whelp = strmaxlen (help, '\n');
-    int w0board = COLS - whelp - 2 * (xoffset + 1);
-    int h0board = LINES - 2 * (yoffset + 1);
-    board_t *board = initboard (w0board, h0board);
-    applyscale (board, scale);
-    snake_t *snake = initsnake (board);
+    if (!filename) {
+        int w0board = COLS - whelp - 2 * (xoffset + 1);
+        int h0board = LINES - 2 * (yoffset + 1);
+        board = initboard (w0board, h0board);
+        applyscale (board, scale);
+        snake = initsnake (board);
+    }
     drawbonus (board, snake, malus, bonus);
 
     /* window positions */
@@ -149,8 +176,6 @@ int main (int argc, char *argv[])
     /* main loop */
     int stop = 0;
     int mode = 0;
-    int score = 0;
-    int duration = 0;
     timeval_t turn = {0, 0};
     int nbturns = 0;
     while (!stop) {
@@ -213,12 +238,16 @@ int main (int argc, char *argv[])
         case 's':
             savename = savewindow (savelen, xsave, ysave);
             if (savename != NULL) {
-                char *ptr = saveboard (board);
+                data_t *data = createdata (board, snake);
+                data->duration = duration;
+                data->score = score;
+                char *ptr = saveboard (data);
                 if (writedata (savename, ptr)) {
                     VERBOSE (WARNING, printf ("issue writing Board\n"));
                 }
                 free (ptr);
                 free (savename);
+                freedata (data);
             }
             break;
         }
@@ -256,13 +285,21 @@ int main (int argc, char *argv[])
 }
 
 /* test: snake.exe -f 2>&1 | grep 'no file' */
-/* test~: snake.exe -f nofile.snk 2>&1 | grep "can't read file" */
-/* test~: snake.exe -f bogus.snk 2>&1 | grep 'incorrect file' */
+/* test: snake.exe -f nofile.snk 2>&1 | grep "can't read file" */
+/* test: snake.exe -f bogus.snk 2>&1 | grep 'incorrect file' */
 /* test: snake.exe -h | grep usage */
 /* test: snake.exe -s 2>&1 | grep 'no scale' */
 /* test: snake.exe -s 4 2>&1 | grep incorrect */
 /* test: snake.exe -v 2>&1 | grep missing */
 /* test: snake.exe _ 2>&1 | grep invalid */
-/* test: { for c in p i j k l q; do sleep 1; echo -n $c; done; } | snake.exe -s 0 */
+/* test: { for c in p i j k l 'stest.snk\n' q; do sleep 1; echo -ne $c; done; } | snake.exe -v 2 */
+/* test: { for c in p i j k l '' k '' j 'stest.snk\n' q; do sleep 1; echo -ne $c; done; } | snake.exe -s 0 */
+/* test: { for c in p k q; do sleep 1; echo -n $c; done; } | snake.exe -s 0 -f test.snk && rm test.snk*/
+/* test: { for c in p i j k l '' k '' j 'stest.snk\n' q; do sleep 1; echo -ne $c; done; } | snake.exe -s 1 */
+/* test: { for c in p k q; do sleep 1; echo -n $c; done; } | snake.exe -s 1 -f test.snk && rm test.snk*/
+/* test: { for c in p i j k l '' k '' j 'stest.snk\n' q; do sleep 1; echo -ne $c; done; } | snake.exe -s 2 */
+/* test: { for c in p k q; do sleep 1; echo -n $c; done; } | snake.exe -s 2 -f test.snk && rm test.snk*/
+/* test: { for c in p i j k l '' k '' j 'stest.snk\n' q; do sleep 1; echo -ne $c; done; } | snake.exe -s 3 */
+/* test: { for c in p k q; do sleep 1; echo -n $c; done; } | snake.exe -s 3 -f test.snk && rm test.snk*/
 
 /* vim: set ts=4 sw=4 et: */
diff --git a/type.h b/type.h
index abd7fb4ca3ef4a187130e23c853dcbd9a3f862dc..3c84e74b13e2557893201367c8139f1f0a831088 100644 (file)
--- a/type.h
+++ b/type.h
@@ -10,10 +10,6 @@ typedef struct {
     int ysize;
     int xoffset;
     int yoffset;
-    int current;
-    int lines;
-    int next;
-    int score;
 } board_t;
 
 typedef struct {
@@ -26,11 +22,19 @@ typedef struct {
 typedef struct {
     int dir;
     int length;
-    int maxlength;
+    int maxlen;
     int *x;
     int *y;
 } snake_t;
 
+typedef struct {
+    board_t *board;
+    int direction;
+    int duration;
+    int score;
+    snake_t *snake;
+} data_t;
+
 #endif /* __TYPE_H__ */
 
 /* vim: set ts=4 sw=4 et: */