From 032676db65e347a6146aafe7203a38b697f5c5a9 Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Sun, 1 Sep 2024 00:21:40 +0200 Subject: [PATCH] save and restore work fine --- function.c | 175 ++++++++++++++++++++++++++++++++++++++++------------- function.h | 12 +++- snake.c | 61 +++++++++++++++---- type.h | 14 +++-- 4 files changed, 202 insertions(+), 60 deletions(-) diff --git a/function.c b/function.c index 63e8c56..39316be 100644 --- a/function.c +++ b/function.c @@ -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: */ diff --git a/function.h b/function.h index 65da249..96342f5 100644 --- a/function.h +++ b/function.h @@ -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 83d2a97..24faa7b 100644 --- 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 abd7fb4..3c84e74 100644 --- 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: */ -- 2.30.2