most of the code is ready
authorLaurent Mazet <mazet@softndesign.org>
Fri, 28 Jun 2024 20:30:04 +0000 (22:30 +0200)
committerLaurent Mazet <mazet@softndesign.org>
Fri, 28 Jun 2024 20:30:04 +0000 (22:30 +0200)
constant.c
display.c
display.h
function.c
function.h
solitaire.c
type.h

index 09d804cb9a2309e2e428a7ac18511841b714e5f0..d0dcbb269f30e47665d49407914e838335293303 100644 (file)
@@ -12,7 +12,8 @@ board_t _board_french = {7, 7,
     "XXXXXXX"
     "XXXXXXX"
     " XXXXX "
-    "  XXX  "};
+    "  XXX  ",
+    1, 0, 0};
 
 board_t _board_german = {9, 9,
     "   XXX   "
@@ -23,7 +24,8 @@ board_t _board_german = {9, 9,
     "XXXXXXXXX"
     "   XXX   "
     "   XXX   "
-    "   XXX   "};
+    "   XXX   ",
+    1, 0, 0};
 
 board_t _board_assymetric = {8, 9,
     "  XXX   "
@@ -34,7 +36,8 @@ board_t _board_assymetric = {8, 9,
     "XXXXXXXX"
     "  XXX   "
     "  XXX   "
-    "  XXX   "};
+    "  XXX   ",
+    1, 0, 0};
 
 board_t _board_english = {7, 7,
     "  XXX  "
@@ -43,7 +46,8 @@ board_t _board_english = {7, 7,
     "XXXOXXX"
     "XXXXXXX"
     "  XXX  "
-    "  XXX  "};
+    "  XXX  ",
+    1, 0, 0};
 
 board_t _board_diamond = {9, 9,
     "    X    "
@@ -54,7 +58,8 @@ board_t _board_diamond = {9, 9,
     " XXXXXXX "
     "  XXXXX  "
     "   XXX   "
-    "    X    "};
+    "    X    ",
+    1, 0, 0};
 
 board_t *getboard (char *name)
 {
index 10cf02ef1c1bd53f42416c6af881c387a0399a9d..9ba3e7ab04adcaa4b62ed328f759d1c75a3913ea 100644 (file)
--- a/display.c
+++ b/display.c
@@ -17,6 +17,12 @@ typedef enum {
     cyan,
     magenta,
     yellow,
+    bred,
+    bgreen,
+    bblue,
+    bcyan,
+    bmagenta,
+    byellow,
     black,
     wred,
     wgreen,
@@ -32,12 +38,18 @@ void set_color (color_t color)
 
     if (init) {
         init_pair (white, COLOR_WHITE, COLOR_BLACK);
-        init_pair (red, COLOR_BLACK, COLOR_RED);
-        init_pair (green, COLOR_BLACK, COLOR_GREEN);
-        init_pair (blue, COLOR_BLACK, COLOR_BLUE);
-        init_pair (magenta, COLOR_BLACK, COLOR_MAGENTA);
-        init_pair (yellow, COLOR_BLACK, COLOR_YELLOW);
-        init_pair (cyan, COLOR_BLACK, COLOR_CYAN);
+        init_pair (red, COLOR_RED, COLOR_BLACK);
+        init_pair (green, COLOR_GREEN, COLOR_BLACK);
+        init_pair (blue, COLOR_BLUE, COLOR_BLACK);
+        init_pair (magenta, COLOR_MAGENTA, COLOR_BLACK);
+        init_pair (yellow, COLOR_YELLOW, COLOR_BLACK);
+        init_pair (cyan, COLOR_CYAN, COLOR_BLACK);
+        init_pair (bred, COLOR_BLACK, COLOR_RED);
+        init_pair (bgreen, COLOR_BLACK, COLOR_GREEN);
+        init_pair (bblue, COLOR_BLACK, COLOR_BLUE);
+        init_pair (bmagenta, COLOR_BLACK, COLOR_MAGENTA);
+        init_pair (byellow, COLOR_BLACK, COLOR_YELLOW);
+        init_pair (bcyan, COLOR_BLACK, COLOR_CYAN);
         init_pair (black, COLOR_BLACK, COLOR_WHITE);
         init_pair (wred, COLOR_WHITE, COLOR_RED);
         init_pair (wgreen, COLOR_WHITE, COLOR_GREEN);
@@ -106,41 +118,89 @@ int helpwindow (char *msg, int xoffset, int yoffset)
     return j;
 }
 
-void boardwindow (board_t *board, int xoffset, int yoffset)
+void _element (board_t *board, int x, int y, int symb)
+{
+    int element = ' ';
+    switch (board->scale) {
+    case 1:
+        set_color (black);
+        switch (symb) {
+        case 'C':
+            set_color (bgreen);
+            break;
+        case 'F':
+            element = ACS_DIAMOND;
+            set_color (wgreen);
+            break;
+        case 'H':
+            element = ACS_DIAMOND;
+            set_color (red);
+            break;
+        case 'P':
+            element = ACS_DIAMOND;
+            set_color (byellow);
+            break;
+        case 'O':
+            set_color (white);
+            break;
+        case 'X':
+            set_color (white);
+            element = ACS_DIAMOND;
+            break;
+        case 'Z':
+            set_color (bblue);
+            break;
+        case ' ':
+            set_color (black);
+            break;
+        }
+        mvaddch (board->yoffset + y, board->xoffset + x, element);
+        set_color (white);
+        break;
+    }
+}
+
+void boardwindow (board_t *board)
 {
     int i, j;
 
     set_color (black);
-    _dobound (board->xsize, board->ysize, xoffset, yoffset);
+    _dobound (board->width * board->scale, board->height * board->scale, board->xoffset, board->yoffset);
     set_color (white);
 
-    for (i = 0; i < board->xsize; i++) {
-        for (j = 0; j < board->ysize; j++) {
-            int element = ' ';
-            char cell = *getcell (board, i, j);
-            switch (cell) {
-            case 'H':
-                element = ACS_DIAMOND;
-                set_color (green);
-                break;
-            case 'P':
-                element = ACS_DIAMOND;
-                set_color (red);
-                break;
-            case 'O':
-                set_color (white);
-                break;
-            case 'X':
-                element = ACS_DIAMOND;
-                break;
-            case ' ':
-                set_color (black);
-                break;
-            default:
-                VERBOSE (WARNING, printf ("unknown code '%c'\n", cell));
-            }
-            mvaddch (yoffset + j, xoffset + i, element);
-            set_color (white);
+   for (i = 0; i < board->width; i++) {
+        for (j = 0; j < board->height; j++) {
+            _element (board, i, j, getvalue (board, i, j));
+        }
+    }
+}
+
+void cursorwindow (board_t *board, int x, int y, int mode)
+{
+    switch (getvalue (board, x, y)) {
+    case 'O':
+        _element (board, x, y, 'C');
+        break;
+    case 'X':
+        _element (board, x, y, (mode) ? 'H' : 'F');
+        break;
+    case ' ':
+        _element (board, x, y, 'Z');
+        break;
+    }
+    if (mode) {
+        set_color (wred);
+        if (testjump (board, x, y, 0)) {
+            _element (board, x, y - 2, 'P');
+        }
+        if (testjump (board, x, y, 1)) {
+            _element (board, x - 2, y, 'P');
+        }
+        if (testjump (board, x, y, 2)) {
+            _element (board, x, y + 2, 'P');
+        }
+        if (testjump (board, x, y, 3)) {
+            _element (board, x + 2, y, 'P');
         }
     }
 }
index 3b4611d51d6360a159ee51c6b86f6cf6c7ebe149..4ec85b5f34db99a09ec118f013e29e27bdbc6fab 100644 (file)
--- a/display.h
+++ b/display.h
@@ -8,7 +8,9 @@
 
 int helpwindow (char *msg, int xoffset, int yoffset);
 
-void boardwindow (board_t *board, int xboard, int yboard);
+void boardwindow (board_t *board);
+
+void cursorwindow (board_t *board, int x, int y, int mode);
 
 char *savewindow (int length, int xoffset, int yoffset);
 
index f8e5daa9d8228774c8d98bcf5c247b7edf7474d3..d64ff5e5b4f0870d87bb0b5cc0b491fb86148dac 100644 (file)
@@ -21,18 +21,32 @@ int strmaxlen (char *str, char ch)
     return len;
 }
 
-board_t *initboard (int xsize, int ysize)
+board_t *initboard (int width, int height)
 {
     board_t *board = (board_t *) malloc (sizeof (board_t));
     CHECKALLOC (board);
-    board->tab = (char *) calloc (1, xsize * ysize + 1);
+    board->tab = (char *) calloc (1, width * height + 1);
     CHECKALLOC (board->tab);
-    memset (board->tab, ' ', xsize * ysize);
-    board->xsize = xsize;
-    board->ysize = ysize;
+    memset (board->tab, ' ', width * height);
+    board->width = width;
+    board->height = height;
+    board->scale = 1;
+    board->xoffset = 0;
+    board->yoffset = 0;
     return board;
 }
 
+board_t *copyboard (board_t *board)
+{
+    board_t *newboard = (board_t *) malloc (sizeof (board_t));
+    CHECKALLOC (board);
+    memcpy (newboard, board, sizeof (board_t));
+    newboard->tab = (char *) calloc (1, board->width * board->height + 1);
+    CHECKALLOC (newboard->tab);
+    memcpy (newboard->tab, board->tab, board->width * board->height + 1);
+    return newboard;
+}
+
 void freeboard (board_t *board)
 {
     if (board) {
@@ -44,10 +58,10 @@ void freeboard (board_t *board)
 int _makecomments (char *buffer, board_t *board)
 {
     int i, j, l = 0;
-    for (j = 0; j < board->ysize; j++) {
+    for (j = 0; j < board->height; j++) {
         l += sprintf (buffer + l, "rem: \"");
-        for (i = 0; i < board->xsize; i++) {
-            l += sprintf (buffer + l, "%c", *getcell (board, i, j));
+        for (i = 0; i < board->width; i++) {
+            l += sprintf (buffer + l, "%c", getvalue (board, i, j));
         }
         l += sprintf (buffer + l, "\"\n");
     }
@@ -56,14 +70,14 @@ int _makecomments (char *buffer, board_t *board)
 
 char *saveboard (board_t *board)
 {
-    int size = 2 * (8 + 3) + 8 + board->xsize * board->ysize + 1;
-    VERBOSE (INFO, size += board->ysize * (8 + board->xsize));
+    int size = 2 * (8 + 3) + 8 + board->width * board->height + 1;
+    VERBOSE (INFO, size += board->height * (8 + board->width));
 
     char *buffer = (char *) calloc (size, 1);
     CHECKALLOC (buffer);
 
-    int l = sprintf (buffer, "xsize: %d\n", board->xsize);
-    l += sprintf (buffer + l, "ysize: %d\n", board->ysize);
+    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);
 
     VERBOSE (INFO, _makecomments (buffer + l, board));
@@ -128,8 +142,8 @@ char *atos (char *str)
 
 board_t *loadboard (char *str)
 {
-    int xsize = 0;
-    int ysize = 0;
+    int width = 0;
+    int height = 0;
     char *tab = NULL;
 
     char *saveptr1, *saveptr2;
@@ -144,10 +158,10 @@ board_t *loadboard (char *str)
             value++;
         }
 
-        if (strcmp (keyword,  "xsize") == 0) {
-            xsize = atoi (value);
-        } else if (strcmp (keyword,  "ysize") == 0) {
-            ysize = atoi (value);
+        if (strcmp (keyword,  "width") == 0) {
+            width = atoi (value);
+        } else if (strcmp (keyword,  "height") == 0) {
+            height = atoi (value);
         } else if (strcmp (keyword,  "tab") == 0) {
             tab = atos (value);
         } else if (strcmp (keyword,  "rem") == 0) {
@@ -160,9 +174,9 @@ board_t *loadboard (char *str)
     }
 
     board_t *board = NULL;
-    if ((tab) && (strlen (tab) == (size_t)(xsize * ysize))) {
-        board = initboard (xsize, ysize);
-        memcpy (board->tab, tab, xsize * ysize);
+    if ((tab) && (strlen (tab) == (size_t)(width * height))) {
+        board = initboard (width, height);
+        memcpy (board->tab, tab, width * height);
     }
 
     return board;
@@ -170,7 +184,55 @@ board_t *loadboard (char *str)
 
 char *getcell (board_t *board, int x, int y)
 {
-    return board->tab + x + board->xsize * y;
+    return board->tab + x + board->width * y;
+}
+
+char getvalue (board_t *board, int x, int y)
+{
+    return (x >= 0) && (x < board->width) && (y >= 0) && (y < board->height) ? *getcell (board, x, y) : 0;
+}
+
+int testjump (board_t *board, int x, int y, int mode)
+{
+    int ret = 0;
+    switch (mode) {
+    case 0:
+        ret = (getvalue (board, x, y - 1) == 'X') && (getvalue (board, x, y - 2) == 'O');
+        break;
+    case 1:
+        ret = (getvalue (board, x - 1, y) == 'X') && (getvalue (board, x - 2, y) == 'O');
+        break;
+    case 2:
+        ret = (getvalue (board, x, y + 1) == 'X') && (getvalue (board, x, y + 2) == 'O');
+        break;
+    case 3:
+        ret = (getvalue (board, x + 1, y) == 'X') && (getvalue (board, x + 2, y) == 'O');
+        break;
+    }
+    return ret;
+}
+
+void dojump (board_t *board, int x, int y, int mode)
+{
+    *getcell (board, x, y) = 'O';
+    switch (mode) {
+    case 0:
+        *getcell (board, x, y - 1) = 'O';
+        *getcell (board, x, y - 2) = 'X';
+        break;
+    case 1:
+        *getcell (board, x - 1, y) = 'O';
+        *getcell (board, x - 2, y) = 'X';
+        break;
+    case 2:
+        *getcell (board, x, y + 1) = 'O';
+        *getcell (board, x, y + 2) = 'X';
+        break;
+    case 3:
+        *getcell (board, x + 1, y) = 'O';
+        *getcell (board, x + 2, y) = 'X';
+        break;
+    }
 }
 
 /* vim: set ts=4 sw=4 et: */
index 55ba397b3c27cefeb138bf2e98f5fb9bb15a4087..32878a88f57663417ac395386ad6172a4c3171ef 100644 (file)
@@ -19,6 +19,8 @@ int strmaxlen (char *str, char ch);
 
 board_t *initboard (int xsize, int ysize);
 
+board_t *copyboard (board_t *board);
+
 void freeboard (board_t *board);
 
 char *saveboard (board_t *board);
@@ -31,6 +33,12 @@ board_t *loadboard (char *str);
 
 char *getcell (board_t *board, int x, int y);
 
+char getvalue (board_t *board, int x, int y);
+
+int testjump (board_t *board, int x, int y, int mode);
+
+void dojump (board_t *board, int x, int y, int mode);
+
 #endif /* __FUNCTION_H__ */
 
 /* vim: set ts=4 sw=4 et: */
index 7dde7ae7cf7c137f6aabf0f2ed39e6aa9bf6fd5c..f6f99da7744ecad3c1ddc6e7411014d153c09e93 100644 (file)
@@ -34,6 +34,7 @@ char *help =
     "<k> Move down cursor\n"
     "<l> Move right cursor\n"
     "<q> Quit\n"
+    "<x> Release pet\n"
     "<s> Save file\n"
     ;
 
@@ -106,10 +107,11 @@ int main (int argc, char *argv[])
     board_t *board = NULL;
     if (filename) {
     } else if (boardname) {
-        board = getboard (boardname);
-        if (board == (board_t *)(-1)) {
+        board_t *temp = getboard (boardname);
+        if (temp == (board_t *)(-1)) {
             return 0;
         }
+        board = copyboard (temp);
     }
     if (board == NULL) {
         return 1;
@@ -125,25 +127,27 @@ int main (int argc, char *argv[])
     start_color ();
 
     /* window positions */
-    int xboard = xoffset + 1;
-    int yboard = xoffset + 1;
-    int xhelp = xboard + xoffset + 1 + board->xsize;
+    int xboard = board->xoffset = xoffset + 1;
+    int yboard = board->yoffset = xoffset + 1;
+    int xhelp = xboard + xoffset + 1 + board->width * board->scale;
     int xcursor = 0;
     int ycursor = 0;
     int yhelp = yboard;
-    int xsave = max (xboard + (board->xsize - savelen) / 2, 1);
-    int ysave = yboard + (board->ysize - 1) / 2;
+    int xsave = max (xboard + (board->width * board->scale - savelen) / 2, 1);
+    int ysave = yboard + (board->height * board->scale - 1) / 2;
     char *savename = NULL;
 
     /* init windows */
     helpwindow (help, xhelp, yhelp);
 
     /* event loop */
+    int mode = 0;
     int stop = 0;
     while (!stop) {
         char *ptr = NULL;
 
-        boardwindow (board, xboard, yboard);
+        boardwindow (board);
+        cursorwindow (board, xcursor, ycursor, mode);
 
         int ch = getch ();
         switch (ch) {
@@ -151,22 +155,51 @@ int main (int argc, char *argv[])
         case '\n':
         case '\r':
         case 'c':
+            if (mode == 1) {
+                mode = 0;
+            } else if (getvalue (board, xcursor, ycursor) == 'X') {
+                mode = 1;
+            }
             break;
         case KEY_UP:
         case 'i':
-            ycursor = (ycursor + board->ysize - 1) % board->ysize;
+            if (mode == 0) {
+                ycursor = (ycursor + board->height - 1) % board->height;
+            } else if (testjump (board, xcursor, ycursor, 0)) {
+                dojump (board, xcursor, ycursor, 0);
+                mode = 0;
+                ycursor -= 2;
+            }
             break;
         case KEY_LEFT:
         case 'j':
-            xcursor = (xcursor + board->xsize - 1) % board->xsize;
+            if (mode == 0) {
+                xcursor = (xcursor + board->width - 1) % board->width;
+            } else if (testjump (board, xcursor, ycursor, 1)) {
+                dojump (board, xcursor, ycursor, 1);
+                mode = 0;
+                xcursor -= 2;
+            }
             break;
         case KEY_DOWN:
         case 'k':
-            ycursor = (ycursor + 1) % board->ysize;
+            if (mode == 0) {
+                ycursor = (ycursor + 1) % board->height;
+            } else if (testjump (board, xcursor, ycursor, 2)) {
+                dojump (board, xcursor, ycursor, 2);
+                mode = 0;
+                ycursor += 2;
+            }
             break;
         case KEY_RIGHT:
         case 'l':
-        xcursor = (xcursor + 1) % board->xsize;
+            if (mode == 0) {
+                xcursor = (xcursor + 1) % board->width;
+            } else if (testjump (board, xcursor, ycursor, 3)) {
+                dojump (board, xcursor, ycursor, 3);
+                mode = 0;
+                xcursor += 2;
+            }
             break;
         case KEY_ESC:
         case 'q':
@@ -188,6 +221,7 @@ int main (int argc, char *argv[])
         case 127:
         case '\b':
         case 'x':
+            mode = 0;
             break;
         //case ERR:
         //default:
diff --git a/type.h b/type.h
index b32dd5651d3d5712f9c5ed99b99d776448176095..46cef0e786fd4f855f5b77d59cb28427f583c835 100644 (file)
--- a/type.h
+++ b/type.h
@@ -2,9 +2,12 @@
 #define __TYPE_H__
 
 typedef struct {
-    int xsize;
-    int ysize;
+    int width;
+    int height;
     char *tab;
+    int scale;
+    int xoffset;
+    int yoffset;
 } board_t;
 
 #endif /* __TYPE_H__ */