most functions are implemented
authorLaurent Mazet <mazet@softndesign.org>
Sun, 18 Aug 2024 14:09:44 +0000 (16:09 +0200)
committerLaurent Mazet <mazet@softndesign.org>
Sun, 18 Aug 2024 14:09:44 +0000 (16:09 +0200)
function.c
function.h
pentomino.c
type.h

index cfd96da7952bf5c880434f7c114126ae4ae6086a..ce21140e4206f2729611027c7301845ddb85fdc4 100644 (file)
@@ -261,6 +261,32 @@ void freeblock (block_t *block)
     free (block);
 }
 
+block_t *mirrorblock (block_t *block, int dir)
+{
+    int i, j;
+    switch (dir % 2) {
+    case 0:
+        for (i = 0; i < block->width; i++) {
+            for (j = 0; j < block->height / 2; j++) {
+                char t = *getcell (block, i, j);
+                *getcell (block, i, j) = *getcell (block, i, block->height - 1 - j);
+                *getcell (block, i, block->height - 1 - j) = t;
+            }
+        }
+        break;
+    case 1:
+        for (i = 0; i < block->width / 2; i++) {
+            for (j = 0; j < block->height; j++) {
+                char t = *getcell (block, i, j);
+                *getcell (block, i, j) = *getcell (block, block->width - 1 - i, j);
+                *getcell (block, block->width - 1 - i, j) = t;
+            }
+        }
+        break;
+    }
+    return block;
+}
+
 block_t *rotateblock (block_t *block, int rot)
 {
     int i, j;
@@ -320,20 +346,72 @@ blocks_t *initblocks (int nb)
     CHECKALLOC (blocks->y);
     blocks->block = (block_t **) calloc (nb, sizeof (block_t *));
     CHECKALLOC (blocks->block);
+    blocks->settle = (int *) calloc (nb, sizeof (int));
+    CHECKALLOC (blocks->settle);
 
     return (blocks);
 }
 
 void freeblocks (blocks_t *blocks)
 {
-    int i;
-    for (i = 0; i < blocks->nb; i++) {
-        freeblock (blocks->block[i]);
+    if (blocks) {
+        int i;
+        for (i = 0; i < blocks->nb; i++) {
+            freeblock (blocks->block[i]);
+        }
+        free (blocks->x);
+        free (blocks->y);
+        free (blocks->block);
+        free (blocks->settle);
     }
-    free (blocks->x);
-    free (blocks->y);
-    free (blocks->block);
     free (blocks);
 }
 
+int findnext (int i, int *tab, int n)
+{
+    int c = 0;
+    do {
+        i++;
+        if (i >= n) {
+            i = 0;
+        }
+        c++;
+        if (c > n) {
+            return -1;
+        }
+    } while (tab[i]);
+
+    return i;
+}
+
+int testposition (board_t *board, block_t *block, int x, int y)
+{
+    int i, j;
+
+    for (i = 0; i < block->width; i++) {
+        for (j = 0; j < block->height; j++) {
+            if (*getcell (block, i, j) != ' ') {
+                if (*getcell (board, x + i, y + j) != ' ') {
+                    return 0;
+                }
+            }
+        }
+    }
+
+    return 1;
+}
+
+void settleblock (board_t *board, block_t *block, int x, int y)
+{
+    int i, j;
+
+    for (i = 0; i < block->width; i++) {
+        for (j = 0; j < block->height; j++) {
+            if (*getcell (block, i, j) != ' ') {
+                *getcell (board, x + i, y + j) = ' ' + block->color;
+            }
+        }
+    }
+}
+
 /* vim: set ts=4 sw=4 et: */
index 3c82c945748d5bf95be48790284f088e6f8f4fc6..325005f4cf5c6aa098d9a60b267aa16fe876607b 100644 (file)
@@ -47,12 +47,20 @@ block_t *copyblock (block_t *block);
 
 void freeblock (block_t *block);
 
+block_t *mirrorblock (block_t *block, int dir);
+
 block_t *rotateblock (block_t *block, int rot);
 
 blocks_t *initblocks (int nb);
 
 void freeblocks (blocks_t *blocks);
 
+int testposition (board_t *board, block_t *block, int x, int y);
+
+void settleblock (board_t *board, block_t *block, int x, int y);
+
+int findnext (int i, int *tab, int n);
+
 #endif /* __FUNCTION_H__ */
 
 /* vim: set ts=4 sw=4 et: */
index e2973e7020430a7e1a8a0c922567f8c3dbf5b160..b864f0ea19079433c12eb2eed782c13299aa3e19 100644 (file)
@@ -28,7 +28,9 @@ char *help =
     "<j> Move left cursor\n"
     "<k> Move down cursor\n"
     "<l> Move right cursor\n"
+    "<m> Mirror horizontally \n"
     "<o> Rotate piece right\n"
+    "<p> Mirror vertically \n"
     "<u> Rotate piece left\n"
     "<y> Yank next piece\n"
     "<q> Quit\n"
@@ -172,12 +174,12 @@ int main (int argc, char *argv[])
         n = 3;
         break;
     }
-    bench = initboard (xoffset + (xoffset + wblock) * (blocks->nb) / n, (1 + n) * yoffset + n * hblock);
+    bench = initboard (xoffset + (xoffset + wblock) * (blocks->nb) / n, (n - 1) * yoffset + n * hblock);
     VERBOSE (DEBUG, fprintf (stderr, "windows: %dx%d\n", xoffset + (xoffset + wblock) * (blocks->nb + n - 1) / n, (1 + n) * yoffset + n * hblock));
     setscale (bench, scale);
     for (i = 0; i < blocks->nb; i++) {
         blocks->x[i] = xoffset + (xoffset + wblock) * (i / n) + (wblock - blocks->block[i]->width + 1) / 2;
-        blocks->y[i] = yoffset + (yoffset + hblock) * (i % n) + (hblock - blocks->block[i]->height + 1) / 2; 
+        blocks->y[i] = (yoffset + hblock) * (i % n) + (hblock - blocks->block[i]->height + 1) / 2;
     }
 
     /* init curses window */
@@ -189,31 +191,34 @@ int main (int argc, char *argv[])
     curs_set (0);
     start_color ();
 
-    /* window positions */
+    /* window positions (board) */
     int xboard = board->xoffset = xoffset + 1;
     int yboard = board->yoffset = xoffset + 1;
-    int xhelp = xboard + xoffset + 1 + board->xsize;
-    int xcursor = board->width / 2;
-    int ycursor = board->height / 2;
-    int cursor = 0;
-    int yhelp = yboard - 1;
     int xsave = max (xboard + (board->xsize - savelen) / 2, 1);
     int ysave = yboard + (board->ysize - 1) / 2;
-
     char *savename = NULL;
 
-    /* help window */
+    /* cursor definition */
+    int cursor = 0;
+    int xcursor = (board->width - blocks->block[cursor]->width) / 2;
+    int ycursor = (board->height - blocks->block[cursor]->height) / 2;
+
+    /* window positions (bench) */
+    int xbench = bench->xoffset = xboard;
+    int ybench = bench->yoffset = yboard + board->ysize + 1 + yoffset;
+
+    /* window positions (help) */
+    int xhelp = xbench + bench->xsize + xoffset + 1;
+    int yhelp = yboard - 1;
     int lhelp = helpwindow (help, xhelp, yhelp);
 
-    /* window positions */
-    int xblocks = bench->xoffset = xboard;
-    int yblocks = bench->yoffset = max (yboard + board->ysize + 1, yhelp + lhelp) + yoffset + 1;
-    int xmsg = xblocks;
-    int ymsg = yblocks + yoffset + 2;
-    int lmsg = xhelp - xmsg + strmaxlen (help, '\n');
+    /* window positions (msg) */
+    int xmsg = xbench;
+    int ymsg = ybench + bench->ysize + yoffset + 1;
+    int lmsg = bench->xsize + strmaxlen (help, '\n') + xoffset + 1;
 
     /* blocks positions */
-    boardwindow (bench, 0);
+    boardwindow (bench, 1);
     for (i = 0; i < blocks->nb; i++) {
         displayblock (bench, blocks->block[i], blocks->x[i], blocks->y[i]);
     }
@@ -223,30 +228,61 @@ int main (int argc, char *argv[])
     while (!stop) {
         boardwindow (board, 0);
 
-        block_t *block = blocks->block[cursor];
-        displayblock (board, block, xcursor, ycursor);
-
-        if (1) { //if (!endofgame (board)) {
-        //    cursorwindow (board, xcursor, ycursor, mode);
+        block_t *block = NULL;
+        if (cursor >= 0) {
+            block = blocks->block[cursor];
+            displayblock (board, block, xcursor, ycursor);
+            msgwindow ("Can you solve this puzzle?", xmsg, ymsg, lmsg);
         } else {
-            msgwindow ("End of game", xmsg, ymsg, lmsg);
+            msgwindow ("Puzzle solved", xmsg, ymsg, lmsg);
         }
 
         int ch = getch ();
+
+        /* general controls */
+        switch (ch) {
+        case KEY_ESC:
+        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;
+        }
+
+        /* test end of game */
+        if (cursor < 0) {
+            continue;
+        }
+
+        /* game controls */
         switch (ch) {
         case '\n':
         case '\r':
         case 'h':
+            if (testposition (board, block, xcursor, ycursor)) {
+                settleblock (board, block, xcursor, ycursor);
+                blocks->settle[cursor] = 1;
+                cursor = findnext (cursor, blocks->settle, blocks->nb);
+            }
             break;
         case KEY_UP:
         case 'i':
-            if (ycursor > - (block->height + 0) / 2) {
+            if (ycursor > - block->height / 2) {
                 ycursor--;
             }
             break;
         case KEY_LEFT:
         case 'j':
-            if (xcursor > - (block->width + 0) / 2) {
+            if (xcursor > - block->width / 2) {
                 xcursor--;
             }
             break;
@@ -262,25 +298,16 @@ int main (int argc, char *argv[])
                 xcursor++;
             }
             break;
+        case 'm':
+            mirrorblock (block, 0);
+            break;
         case KEY_DELETE:
         case 127:
         case 'o':
             rotateblock (block, 1);
             break;
-        case KEY_ESC:
-        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);
-            }
+        case 'p':
+            mirrorblock (block, 1);
             break;
         case KEY_BACKSPACE:
         case '\b':
@@ -289,14 +316,8 @@ int main (int argc, char *argv[])
             break;
         case ' ':
         case 'y':
-            cursor++;
-            if (cursor >= blocks->nb) {
-                cursor = 0;
-            }
-            break;
+            cursor = findnext (cursor, blocks->settle, blocks->nb);
             break;
-        //case ERR:
-        //default:
         }
     }
 
@@ -304,6 +325,7 @@ int main (int argc, char *argv[])
     endwin ();
 
     freeboard (board);
+    freeblocks (blocks);
 
     return 0;
 }
diff --git a/type.h b/type.h
index 9f49930a0b254dc810c43c445aff844c82f045a0..c912717c5c94b2b2309fde56e7b47cce91db2147 100644 (file)
--- a/type.h
+++ b/type.h
@@ -28,6 +28,7 @@ typedef struct {
     int *x;
     int *y;
     block_t **block;
+    int *settle;
 } blocks_t;
 
 #endif /* __TYPE_H__ */