not working
authorLaurent MAZET <laurent.mazet@thalesgroup.com>
Wed, 28 Aug 2024 15:13:40 +0000 (17:13 +0200)
committerLaurent MAZET <laurent.mazet@thalesgroup.com>
Wed, 28 Aug 2024 15:13:40 +0000 (17:13 +0200)
constant.c
constant.h
display.c
function.c
function.h
snake.c
time.c [new file with mode: 0644]
time.h [new file with mode: 0644]
type.h

index 3629180dd244cc3c771771faa55511d477606f92..0a2b796e7456309772c8148e972d1119d02f001c 100644 (file)
@@ -1,78 +1,9 @@
-#include <stdio.h>
-#include <string.h>
-
-#include "block.h"
-#include "function.h"
-#include "type.h"
-
 #include "constant.h"
 
 /* constants */
 
-int height = 20;
-int minwidth = 8;
-int width = 10;
-int maxwidth = 15;
-
-int nbdigit = 5;
-int maxscor = 100000;
-int nbholes = 2;
-
 int savelen = 12;
 int xoffset = 1;
 int yoffset = 1;
 
-/* blocks */
-
-#define _nb_blocks_std 12
-
-block_t _blocks_std[_nb_blocks_std] = {
-    {3, 3, yellow, " ....  . "}, // F
-    {1, 5, blue, "...."},      // I
-    {2, 4, lightmagenta, ". . . .."},  // L
-    {2, 4, lightblue, " .... . "},  // N
-    {2, 3, lightgreen, " ....."},    // P
-    {3, 3, lightcyan, "... .  . "}, // T
-    {3, 2, magenta, ". ...."},    // U
-    {3, 3, cyan, ".  .  ..."}, // V
-    {3, 3, lightergreen, ".  ..  .."}, // W
-    {3, 3, red, " . ... . "}, // X
-    {2, 4, darkblue, " ... . ."},  // Y
-    {3, 3, brown, "..  .  .."}, // Z
-};
-
-block_t *getblocks (char *name, int *nb)
-{
-    block_t *pt = NULL;
-
-    if (strcmp (name, "std") == 0) {
-        pt = _blocks_std;
-        *nb = _nb_blocks_std;
-    }
-
-    return pt;
-}
-
-/* board */
-
-board_t *getboard (char *name)
-{
-    board_t *board = NULL;
-
-    if (strcmp (name, "6x10") == 0) {
-        board = initboard (6, 10);
-    } else if (strcmp (name, "5x12") == 0) {
-        board = initboard (5, 12);
-    } else if (strcmp (name, "4x15") == 0) {
-        board = initboard (4, 15);
-    } else if (strcmp (name, "3x20") == 0) {
-        board = initboard (3, 20);
-    } else if (strcmp (name, "list") == 0) {
-        printf ("board: 6x10 5x12 4x15 3x20\n");
-        board = (board_t *)(-1);
-    }
-
-    return board;
-}
-
 /* vim: set ts=4 sw=4 et: */
index 00de5ac0db317741884765f6fd66605370d44c5e..df70ca346aec2ff51d204daa1ad8d02f3cee8ac2 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef __CONSTANT_H__
 #define __CONSTANT_H__
 
-#include "type.h"
-
 /* global constants */
 
 #ifndef __CONSTANT_C__
@@ -13,12 +11,6 @@ extern int yoffset;
 
 #endif /* __CONSTANT_C__ */
 
-/* block definitions */
-
-block_t *getblocks (char *name, int *nb);
-
-board_t *getboard (char *name);
-
 #endif /* __CONSTANT_H__ */
 
 /* vim: set ts=4 sw=4 et: */
index f8d85a35bb1fe172ec6643c61b25c0004fd9f1ad..6afa866e1a3aff4395807a9538db3e5b7b6eeb94 100644 (file)
--- a/display.c
+++ b/display.c
@@ -161,24 +161,14 @@ void boardwindow (board_t *board, int mode)
     }
 }
 
-void displayblock (board_t *board, block_t *block, int x, int y)
+void displaysnake (board_t *board, snake_t *snake)
 {
-    int i, j;
-
-    if (x == -1) {
-        x = board->width / 2;
-    }
-
-    if (y == -1) {
-        y = (board->height - block->height) / 2;
-    }
+    int i;
 
-    for (i = 0; i < block->width; i++) {
-        for (j = 0; j < block->height; j++) {
-            if (*getcell (block, i, j) != ' ') {
-                _element (board, x - block->width / 2 + i, y + j, '0' + block->color);
-            }
-        }
+    int color  = green;
+    for (i = 0; i < snake->length; i++) {
+        _element (board, snake->x[i], snake->y[i], color);
+        color = darkgreen;
     }
 }
 
index cfa5471f8d58fca0179c56de330a19ea1b6622d3..7f9584628f30796d993b346292727d8ae56d7bdf 100644 (file)
@@ -39,25 +39,25 @@ board_t *initboard (int width, int height)
     return board;
 }
 
-board_t *setscale (board_t *board, int scale)
+board_t *applyscale (board_t *board, int scale)
 {
     board->scale = scale;
     switch (scale) {
     case 0:
-        board->xsize = board->width;
-        board->ysize = board->height;
+        board->width = board->xsize;
+        board->height = board->ysize;
         break;
     case 1:
-        board->xsize = board->width * 2;
-        board->ysize = board->height;
+        board->width = board->xsize / 2;
+        board->height = board->ysize;
         break;
     case 2:
-        board->xsize = board->width * 2;
-        board->ysize = board->height * 2;
+        board->width = board->xsize / 2;
+        board->height = board->ysize / 2;
         break;
     case 3:
-        board->xsize = board->width * 3;
-        board->ysize = board->height * 2;
+        board->width = board->xsize / 3;
+        board->height = board->ysize / 2;
         break;
     }
     return board;
@@ -218,94 +218,98 @@ board_t *loadboard (char *str)
     return board;
 }
 
-block_t *initblock (int width, int height)
+snake_t *initsnake (board_t *board)
 {
-    block_t *block = (block_t *) malloc (sizeof (block_t));
-    CHECKALLOC (block);
-    block->tab = (char *) calloc (1, width * height + 1);
-    CHECKALLOC (block->tab);
-    memset (block->tab, ' ', width * height);
-    block->width = width;
-    block->height = height;
-    return block;
-}
+    snake_t *snake = (snake_t *) calloc (1, sizeof (snake_t));
+    CHECKALLOC (snake);
 
-block_t *changeblock (block_t *dest, block_t *src)
-{
-    block_t *ret = NULL;
-    if (dest && src) {
-        free (dest->tab);
-        memcpy (dest, src, sizeof (block_t));
-        dest->tab = strdup (src->tab);
-        CHECKALLOC (dest->tab);
-        ret = dest;
-    }
-    return ret;
-}
+    snake->maxlength = board->width * board->height + 1;
 
-block_t *copyblock (block_t *block)
-{
-    block_t *newblock = initblock (block->width, block->height);
-    char *tab = newblock->tab;
-    memcpy (newblock, block, sizeof (block_t));
-    newblock->tab = tab;
-    memcpy (newblock->tab, block->tab, block->width * block->height + 1);
-    return newblock;
+    snake->x = (int *) calloc (snake->maxlength, sizeof (int));
+    CHECKALLOC (snake->x);
+
+    snake->y = (int *) calloc (snake->maxlength, sizeof (int));
+    CHECKALLOC (snake->y);
+
+    snake->x[0] = board->width / 2 + 1;
+    snake->y[0] = board->height / 2;
+    snake->x[1] = board->width / 2;
+    snake->y[1] = board->height / 2;
+
+    snake->length = 2;
+    snake->dir = 0;
+
+    return snake;
 }
 
-void freeblock (block_t *block)
+void freesnake (snake_t *snake)
 {
-    if (block) {
-        free (block->tab);
+    if (snake != NULL) {
+        free (snake->x);
+        free (snake->y);
     }
-    free (block);
+    free (snake);
 }
 
-block_t *rotateblock (block_t *block, int rot)
+int movesnake (board_t *board, snake_t *snake, int dir)
 {
-    int i, j;
-
-    rot = (rot > 0) ? rot % 4 : ((1 - rot / 4) * 4 + rot) % 4;
+    int i;
+    int ret = 0;
 
-    block_t *newblock = NULL;
+    int x = snake->x[0];
+    int y = snake->y[0];
 
-    switch (rot) {
+    switch (dir) {
     case 0:
-        newblock = copyblock (block);
+        y--;
         break;
     case 1:
-        newblock = initblock (block->height, block->width);
-        newblock->color = block->color;
-        for (i = 0; i < block->width; i++) {
-            for (j = 0; j < block->height; j++) {
-                *getcell (newblock, block->height - 1 - j, i) = *getcell (block, i, j);
-            }
-        }
+        x--;
         break;
     case 2:
-        newblock = initblock (block->width, block->height);
-        newblock->color = block->color;
-        for (i = 0; i < block->width; i++) {
-            for (j = 0; j < block->height; j++) {
-                *getcell (newblock, block->width - 1 - i, block->height - 1 - j) = *getcell (block, i, j);
-            }
-        }
+        y++;
         break;
     case 3:
-        newblock = initblock (block->height, block->width);
-        newblock->color = block->color;
-        for (i = 0; i < block->width; i++) {
-            for (j = 0; j < block->height; j++) {
-                *getcell (newblock, j, block->width - 1 - i) = *getcell (block, i, j);
-            }
-        }
+        x++;
         break;
     }
 
-    changeblock (block, newblock);
-    freeblock (newblock);
+    if ((x >= 0) && (x < board->width) &&
+        (y >= 0) && (y < board->height)) {
+
+        char *cell = getcell (board, x, y);
+        switch (*cell) {
+        case '6': /* decrease size */
+            if (snake->length > 2) {
+                snake->length--;
+                snake->x[snake->length] = 0;
+                snake->y[snake->length] = 0;
+            }
+            /* fall through */
+        case ' ': /* only forward */
+            for (i = snake->length - 1; i > 0; i++) {
+                snake->x[i] = snake->x[i - 1];
+                snake->y[i] = snake->y[i - 1];
+            }
+            break;
+        case '5': /* increase size */
+            for (i = snake->length - 1; i >= 0; i++) {
+                snake->x[i + 1] = snake->x[i];
+                snake->y[i + 1] = snake->y[i];
+            }
+            snake->length++;
+            break;
+        }
+
+        snake->x[0] = x;
+        snake->y[0] = y;
+
+        snake->dir = dir;
 
-    return block;
+        ret = 1;
+    }
+
+    return ret;
 }
 
 /* vim: set ts=4 sw=4 et: */
index 335fca6aa106a302d7c10ceecc20acd81d4b4b7d..b7e8d5f56ceee8e11b1929ddddadd5a75ba39aa6 100644 (file)
@@ -23,7 +23,7 @@ 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);
 
@@ -39,15 +39,11 @@ char *atos (char *str);
 
 board_t *loadboard (char *str);
 
-block_t *initblock (int width, int height);
+snake_t *initsnake (board_t *board);
 
-block_t *changeblock (block_t *dest, block_t *src);
+void freesnake (snake_t *snake);
 
-block_t *copyblock (block_t *block);
-
-void freeblock (block_t *block);
-
-block_t *rotateblock (block_t *block, int rot);
+int movesnake (board_t *board, snake_t *snake, int dir);
 
 #endif /* __FUNCTION_H__ */
 
diff --git a/snake.c b/snake.c
index 5c467778d60d28d4c4203a02e9fc8e3bd7d6f066..d18c9a68555e0bac3ab77457dd37e47d06e64281 100644 (file)
--- a/snake.c
+++ b/snake.c
@@ -1,8 +1,8 @@
 /* depend: */
 /* cflags: */
-/* linker: block.o color.c constant.o debug.o display.o function.o -lcurses */
-/* doslnk: block.o color.c constant.o debug.o display.o function.o -lpdc~1 */
-/* winlnk: block.o color.c constant.o debug.o display.o function.o -lpdcurses */
+/* linker: block.o color.c constant.o debug.o display.o function.o time.o -lcurses */
+/* doslnk: block.o color.c constant.o debug.o display.o function.o time.o -lpdc~1 */
+/* winlnk: block.o color.c constant.o debug.o display.o function.o time.o -lpdcurses */
 
 #include <curses.h>
 #include <stdio.h>
@@ -19,15 +19,14 @@ char *progname = NULL;
 char *version = "0.1";
 
 char *filename = NULL;
-int scale = 1;
-char *boardname = "6x10";
+int scale = 0;
 
 char *help =
     "<i> Move up cursor\n"
     "<j> Move left cursor\n"
     "<k> Move down cursor\n"
     "<l> Move right cursor\n"
-    "<o> Hold/Release piece\n"
+    "<p> Pause\n"
     "<q> Quit\n"
     "<s> Save file\n"
     ;
@@ -35,12 +34,11 @@ char *help =
 int usage (int ret)
 {
     FILE *fd = ret ? stderr : stdout;
-    fprintf (fd, "usage: %s [-b] [-f file] [-h] [-s int] [-v int]\n", progname);
-    fprintf (fd, " -b: board form  [6x10, 5x12, 4x15, 3x20] (%s)\n", boardname);
+    fprintf (fd, "usage: %s [-f file] [-h] [-s int] [-v int]\n", progname);
     fprintf (fd, " -f: file name (%s)\n", (filename) ? filename : "none");
     fprintf (fd, " -h: help message\n");
     fprintf (fd, " -s: scale [0..3] (%d)\n", scale);
-    fprintf (fd, " -v: verbose level (%d)\n", verbose);
+    fprintf (fd, " -v: verbose level [%d..%d] (%d)\n", ERROR, DEBUG, verbose);
     fprintf (fd, "%s version %s\n", progname, version);
 
     return ret;
@@ -68,14 +66,6 @@ int main (int argc, char *argv[])
         }
         char c = arg[1];
         switch (c) {
-        case 'b':
-            arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
-            if (arg == NULL) {
-                VERBOSE (ERROR, fprintf (stderr, "%s: no board specified\n", progname));
-                return usage (1);
-            }
-            boardname = arg;
-            break;
         case 'f':
             arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
             if (arg == NULL) {
@@ -112,32 +102,6 @@ int main (int argc, char *argv[])
         return 1;
     }
 
-    /* load playground */
-    board_t *board = NULL;
-    if (filename) {
-        char *buffer = readdata (filename);
-        if (buffer == NULL) {
-            VERBOSE (ERROR, fprintf (stderr, "can't read file (%s)\n", filename));
-            return 1;
-        }
-        board = loadboard (buffer);
-        free (buffer);
-        if (board == NULL) {
-            VERBOSE (ERROR, fprintf (stderr, "incorrect file (%s)\n", filename));
-            return 1;
-        }
-    } else if (boardname) {
-        board = getboard (boardname);
-        if (board == (board_t *)(-1)) {
-            return 0;
-        }
-        if (board == NULL) {
-            VERBOSE (ERROR, fprintf (stderr, "unknown board (%s)\n", boardname));
-            return 1;
-        }
-    }
-    setscale (board, scale);
-
     /* init curses window */
     initscr ();
     noecho ();
@@ -147,29 +111,110 @@ int main (int argc, char *argv[])
     curs_set (0);
     start_color ();
 
+    /* load playground */
+    int w0board = COLS - strmaxlen (help, '\n') - 2 * (xoffset + 1);
+    int h0board = LINES - 2 * (yoffset + 1);
+    board_t *board = initboard (w0board, h0board);
+    applyscale (board, scale);
+
     /* window positions */
     int xboard = board->xoffset = xoffset + 1;
-    int yboard = board->yoffset = xoffset + 1;
-    int xhelp = xboard + xoffset + 1 + board->xsize;
-    int xcursor = 0;
-    int ycursor = 0;
-    int yhelp = yboard - 1;
+    int yboard = board->yoffset = yoffset + 1;
+    int xscore = xboard + xoffset + 1 + board->xsize;
+    int yscore = yboard - 1;
+    int xhelp = xscore;
+    int yhelp = yscore + 3 + xoffset;
+    int xcursor = board->width / 2;
+    int ycursor = board->height / 2;
     int xsave = max (xboard + (board->xsize - savelen) / 2, 1);
     int ysave = yboard + (board->ysize - 1) / 2;
     char *savename = NULL;
 
-    /* help window */
-    int lhelp = helpwindow (help, xhelp, yhelp);
-
-    /* window positions */
-    int xmsg = xboard;
-    int ymsg = max (yboard + xoffset + 1 + board->ysize, yhelp + lhelp + yoffset + 1);
-    int lmsg = xhelp - xmsg + strmaxlen (help, '\n');
+    VERBOSE (DEBUG, printf ("width: %d\nheight: %d\n", board->width, board->height));
 
+    /* init snake */
+    snake_t *snake = initsnake (board);
 
+    /* help window */
+    helpwindow (help, xhelp, yhelp);
+
+    /* main loop */
+    int stop = 0;
+    int mode = 0;
+    int dir = 3;
+    timeval_t turn = {0, 0};
+    int speed = 3000;
+    while (!stop) {
+
+        boardwindow (board, 1);
+        if (isovertime (&turn)) {
+            setendtime (&turn, speed);
+            if (!movesnake (board, snake, snake->dir)) {
+                mode = 2;
+            }
+        }
 
+        int ch = getch ();
+
+        /* main controls */
+        switch (ch) {
+        case ' ':
+        case 'p':
+            if (mode == 0) {
+                mode = 1;
+                setendtime (&turn, speed);
+            } else if (mode == 1) {
+                mode = 0;
+            }
+            break;
+        case 'q':
+            stop = 1;
+            break;
+        case 's':
+            savename = savewindow (savelen, xsave, ysave);
+            if (savename != NULL) {
+                char *ptr = saveboard (board);
+                if (writedata (savename, ptr)) {
+                    VERBOSE (WARNING, printf ("issue writing Board\n"));
+                }
+                free (ptr);
+                free (savename);
+            }
+            break;
+        }
 
+        if (mode != 1) {
+            continue;
+        }
 
+        /* game controls */
+        switch (ch) {
+        case KEY_UP:
+        case 'i':
+            if (!movesnake (board, snake, 0)) {
+                mode = 2;
+            }
+            break;
+        case KEY_LEFT:
+        case 'j':
+            if (!movesnake (board, snake, 1)) {
+                mode = 2;
+            }
+            break;
+        case KEY_DOWN:
+        case 'k':
+            if (!movesnake (board, snake, 2)) {
+                mode = 2;
+            }
+            break;
+        case KEY_RIGHT:
+        case 'l':
+            if (!movesnake (board, snake, 3)) {
+                mode = 2;
+            }
+            break;
+        }
+    }
 
     endwin ();
 
diff --git a/time.c b/time.c
new file mode 100644 (file)
index 0000000..9c1e119
--- /dev/null
+++ b/time.c
@@ -0,0 +1,38 @@
+#include <stdlib.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "time.h"
+
+int newseed (int seed)
+{
+    if (seed == 0) {
+        seed = time (NULL);
+    }
+    srand (seed);
+    return seed;
+}
+
+void setendtime (timeval_t *t, int s)
+{
+    gettimeofday (t, NULL);
+    t->tv_usec += s * 1000l;
+    t->tv_sec += t->tv_usec / 1000000l;
+    t->tv_usec = t->tv_usec % 1000000l;
+}
+
+int isovertime (timeval_t *t)
+{
+    struct timeval _c;
+    struct timeval *c = &_c;
+    gettimeofday (c, NULL);
+    return ((t->tv_sec + t->tv_usec == 0) || (t->tv_sec < c->tv_sec) || ((t->tv_sec == c->tv_sec) && ( t->tv_usec < c->tv_usec)));
+}
+
+void msleep (int msec)
+{
+    usleep (msec * 1000);
+}
+
+/* vim: set ts=4 sw=4 et: */
diff --git a/time.h b/time.h
new file mode 100644 (file)
index 0000000..e032e5c
--- /dev/null
+++ b/time.h
@@ -0,0 +1,18 @@
+#ifndef __TIME_H__
+#define __TIME_H__
+
+#include <sys/time.h>
+
+typedef struct timeval timeval_t;
+
+int newseed (int seed);
+
+void setendtime (timeval_t *t, int s);
+
+int isovertime (timeval_t *t);
+
+void msleep (int msec);
+
+#endif /* __TIME_H__ */
+
+/* vim: set ts=4 sw=4 et: */
diff --git a/type.h b/type.h
index 199c75f7edc3501d218feccc8914e6c495e2450a..abd7fb4ca3ef4a187130e23c853dcbd9a3f862dc 100644 (file)
--- a/type.h
+++ b/type.h
@@ -23,6 +23,14 @@ typedef struct {
     char *tab;
 } block_t;
 
+typedef struct {
+    int dir;
+    int length;
+    int maxlength;
+    int *x;
+    int *y;
+} snake_t;
+
 #endif /* __TYPE_H__ */
 
 /* vim: set ts=4 sw=4 et: */