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;
}
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;
}
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;
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 {
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)
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;
}
}
+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: */
/* 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 ();
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 */
/* main loop */
int stop = 0;
int mode = 0;
- int score = 0;
- int duration = 0;
timeval_t turn = {0, 0};
int nbturns = 0;
while (!stop) {
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;
}
}
/* 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: */