better display
authorLaurent Mazet <mazet@softndesign.org>
Sat, 1 Mar 2025 21:04:45 +0000 (22:04 +0100)
committerLaurent Mazet <mazet@softndesign.org>
Sat, 1 Mar 2025 21:04:45 +0000 (22:04 +0100)
display.c
function.c
function.h
sudoku.c
type.h

index 39c94b533aa0792108ac97f6666e2a231d0b0dfc..0b6f93bba3c9cedefa621ece5d0a37ab7ac4cee0 100644 (file)
--- a/display.c
+++ b/display.c
@@ -128,6 +128,32 @@ void _dobound (int xsize, int ysize, int xoffset, int yoffset)
     mvaddch (yoffset + ysize, xoffset + xsize, ACS_LRCORNER);
 }
 
+void _dogrid (int xsize, int ysize, int gap, int xoffset, int yoffset)
+{
+    int i, j;
+
+    _dobound (xsize, ysize, xoffset, yoffset);
+
+    for (i = 0; i < xsize; i++) {
+        for (j = 0; j < ysize; j++) {
+            if (((i + 1) % gap == 0) && ((j + 1) % gap == 0)) {
+                mvaddch (yoffset + j, xoffset + i , ACS_PLUS);
+            } else if (((i + 1) % gap == 0) && ((j + 1) % gap != 0)) {
+                mvaddch (yoffset + j, xoffset + i , ACS_VLINE);
+            } else if (((i + 1) % gap != 0) && ((j + 1) % gap == 0)) {
+                mvaddch (yoffset + j, xoffset + i , ACS_HLINE);
+            }
+        }
+    }
+
+    for (i = 1; i < gap - 1; i++) {
+        mvaddch (yoffset - 1, xoffset - 1 + gap * i, ACS_TTEE);
+        mvaddch (yoffset - 1 + gap * i, xoffset - 1, ACS_LTEE);
+        mvaddch (yoffset + ysize, xoffset - 1 + gap * i, ACS_BTEE);
+        mvaddch (yoffset - 1 + gap * i, xoffset + xsize, ACS_RTEE);
+    }
+}
+
 int helpwindow (char *msg, int xoffset, int yoffset)
 {
     char *title = "Help message";
@@ -152,11 +178,12 @@ int helpwindow (char *msg, int xoffset, int yoffset)
 void displayboard (board_t *board, int xoffset, int yoffset)
 {
     int i, j;
+    int n = sqrti (board->length);
 
-    _dobound (board->nb + 2, board->nb + 2,  xoffset - 1, yoffset - 1);
-    for (i = 0; i < board->nb; i++) {
-        for (j= 0; j < board->nb; j++) {
-            mvaddch (j + yoffset, i + xoffset, getvalue (board, i, j));
+    _dogrid (board->length + n - 1, board->length + n - 1, n + 1, xoffset, yoffset);
+    for (i = 0; i < board->length; i++) {
+        for (j= 0; j < board->length; j++) {
+            mvaddch (j + yoffset + (j / n), i + xoffset + (i / n), getvalue (board, i, j));
         }
     }
 }
index 70b2ecfd3d13cb4ac6d3bf1b96556389a9f39283..c8f73eaf888cc4e5dcf0da6ec16eddb70ea86f08 100644 (file)
@@ -1,3 +1,4 @@
+#include <assert.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -22,18 +23,45 @@ int strmaxlen (char *str, char ch)
     return len;
 }
 
+int sqrti (int x)
+{
+    int r = 0;
+    switch (x) {
+    case 1: r = 1; break;
+    case 4: r = 2; break;
+    case 9: r = 3; break;
+    case 16: r = 4; break;
+    case 25: r = 5; break;
+    case 36: r = 6; break;
+    }
+    return r;
+}
+
 board_t *initboard (int length)
 {
     board_t *board = (board_t *) malloc (sizeof (board_t));
     CHECKALLOC (board);
     board->length = length;
-    int nb = board->nb = length * length;
-    board->tab = (char *) calloc (1, nb * nb + 1);
+    board->tab = (char *) calloc (1, length * length + 1);
     CHECKALLOC (board->tab);
-    memset (board->tab, ' ', nb * nb);
+    memset (board->tab, ' ', length * length);
     return board;
 }
 
+board_t *copyboard (board_t *board)
+{
+    board_t *new = NULL;
+    if (board) {
+        new = (board_t *) malloc (sizeof (board_t));
+        CHECKALLOC (new);
+        memcpy (new, board, sizeof (board_t));
+        new->tab = (char *) calloc (1, board->length * board->length + 1);
+        CHECKALLOC (new->tab);
+        memcpy (new->tab, board->tab, board->length * board->length);
+    }
+    return new;
+}
+
 char _itoh (int x)
 {
     char h = '0';
@@ -45,49 +73,88 @@ char _itoh (int x)
 
 board_t *initplay (board_t *board)
 {
-    int i, j, k;
-
-    for (i = 0; i < board->nb; i++) {
-        for (j = 0; j < board->nb; j++) {
-            int draw = 1;
-            while (draw) {
-
-                char tile = _itoh (1 + (rand () / board->nb) / (((RAND_MAX / board->nb) + board->nb) / board->nb));
-                VERBOSE (DEBUG, printf ("tile drawn '%c'\n", tile));
-                draw = 0;
-
-                /* check line */
-                VERBOSE (DEBUG, printf ("check line\n"));
-                for (k = 0; (k < j) && (!draw); k++) {
-                    if (getvalue (board, i, k) == tile) {
-                        draw = 1;
-                    }
+    int n = sqrti (board->length);
+
+    /* k is value */
+    int k;
+    for (k = 0; k < board->length; k++) {
+        char val = _itoh (1 + k);
+        board_t *vbox = initboard (n);
+
+        /* i in position */
+        int i;
+        for (i = 0; i < board->length; i++) {
+            int j;
+
+            /* look for forbiden position */
+            board_t *box = copyboard (vbox);
+
+            for (j = 0; j < board->length; j++) {
+
+                /* box check */
+                if (getvalue (board, n * (i % n) + j % n, n * (i / n) + j / n) != ' ') {
+                    *getcell (box, j % n, j / n) = '#';
                 }
 
-                /* check column */
-                VERBOSE (DEBUG, printf ("check column\n"));
-                for (k = 0; (k < i) && (!draw); k++) {
-                    if (getvalue (board, k, j) == tile) {
-                        draw = 1;
+                /* verical check */
+                if ((j / n == i / n) && (j % n != i % n)) {
+                    int l;
+                    for (l = 0; l < board->length; l++) {
+                        if (getvalue (board, n * (j % n) + l % n, n * (j / n) + l / n) == val) {
+                            int t;
+                            for (t = 0; t < n; t++) {
+                                *getcell (box, t, l / n) = '#';
+                            }
+                        }
                     }
                 }
 
-                /* check box */
-                VERBOSE (DEBUG, printf ("check box\n"));
-                for (k = 0; (k < board->nb) && (!draw); k++) {
-                    int I = board->length * (i / board->length);
-                    int J = board->length * (j / board->length);
-                    if (getvalue (board, I + k / board->length, J + k % board->length) == tile) {
-                        draw = 1;
+                /* horizontal check */
+                if ((j / n != i / n) && (j % n == i % n)) {
+                    int l;
+                    for (l = 0; l < board->length; l++) {
+                        if (getvalue (board, n * (j % n) + l % n, n * (j / n) + l / n) == val) {
+                            int t;
+                            for (t = 0; t < n; t++) {
+                                *getcell (box, l % n, t) = '#';
+                            }
+                        }
                     }
                 }
 
-                if (!draw) {
-                    VERBOSE (INFO, printf ("(%d, %d) = %c\n", i, j, tile));
-                    *getcell (board, i, j) = tile;
+            }
+
+            /* count avaliable position */
+            int pos = 0;
+            for (j = 0; j < board->length; j++) {
+                if (getvalue (box, j % n, j / n) == ' ') {
+                    pos++;
+                }
+            }
+
+            /* random position */
+            pos = (pos > 0) ? rand () % pos : 0;
+            for (j = 0; (j < board->length) && (pos >= 0); j++) {
+                if (getvalue (box, j % n, j / n) == ' ') {
+                    if (pos == 0) {
+                        *getcell (board, n * (i % n) + j % n, n * (i / n) + j / n) = val;
+                        *getcell (vbox, j % n, j / n) = '#';
+                    }
+                    pos--;
                 }
             }
+
+                char *buffer = (char *) calloc (board->length * (8 + board->length) + 1, 1);
+                _makecomments (buffer, box);
+                printf ("box:\n%s", buffer);
+                _makecomments (buffer, board);
+                printf ("board:\n%s", buffer);
+                free (buffer);
+
+            freeboard (box);
         }
+
+        freeboard (vbox);
     }
 
     return board;
@@ -104,9 +171,9 @@ void freeboard (board_t *board)
 int _makecomments (char *buffer, board_t *board)
 {
     int i, j, l = 0;
-    for (j = 0; j < board->nb; j++) {
+    for (j = 0; j < board->length; j++) {
         l += sprintf (buffer + l, "rem: \"");
-        for (i = 0; i < board->nb; i++) {
+        for (i = 0; i < board->length; i++) {
             l += sprintf (buffer + l, "%c", getvalue (board, i, j));
         }
         l += sprintf (buffer + l, "\"\n");
@@ -116,13 +183,12 @@ int _makecomments (char *buffer, board_t *board)
 
 char *saveboard (board_t *board)
 {
-    int size = 2 * (8 + 3) + 8 + board->nb * board->nb + 1;
+    int size = 2 * (8 + 3) + 8 + board->length * board->length + 1;
 
     char *buffer = (char *) calloc (size, 1);
     CHECKALLOC (buffer);
 
     int l = sprintf (buffer, "length: %d\n", board->length);
-    l += sprintf (buffer + l, "nb: %d\n", board->nb);
 
     VERBOSE (INFO, _makecomments (buffer + l, board));
 
@@ -187,7 +253,6 @@ char *atos (char *str)
 board_t *loadboard (char *str)
 {
     int length = 0;
-    int nb = 0;
     char *tab = NULL;
 
     char *saveptr1, *saveptr2;
@@ -204,8 +269,6 @@ board_t *loadboard (char *str)
 
         if (strcmp (keyword,  "length") == 0) {
             length = atoi (value);
-        } else if (strcmp (keyword,  "nb") == 0) {
-            nb = atoi (value);
         } else if (strcmp (keyword,  "rem") == 0) {
             /* nothing to do with remark */
         } else {
@@ -216,9 +279,9 @@ board_t *loadboard (char *str)
     }
 
     board_t *board = NULL;
-    if ((tab) && (nb == length * length) && (strlen (tab) == (size_t)(nb * nb))) {
+    if ((tab) && (strlen (tab) == (size_t)(length * length))) {
         board = initboard (length);
-        memcpy (board->tab, tab, nb * nb);
+        memcpy (board->tab, tab, length * length);
     }
 
     return board;
@@ -226,13 +289,13 @@ board_t *loadboard (char *str)
 
 char *getcell (board_t *board, int x, int y)
 {
-    return board->tab + x + board->nb * y;
+    return board->tab + x + board->length * y;
 }
 
 char getvalue (board_t *board, int x, int y)
 {
     VERBOSE (DEBUG, printf ("(%d, %d) => '%c'\n", x, y, *getcell (board, x, y)));
-    return (x >= 0) && (x < board->nb) && (y >= 0) && (y < board->nb) ? *getcell (board, x, y) : 0;
+    return (x >= 0) && (x < board->length) && (y >= 0) && (y < board->length) ? *getcell (board, x, y) : 0;
 }
 
 /* vim: set ts=4 sw=4 et: */
index 4d6b84d114770cfa78553bfc7007904db6f16d03..a1a7fc6821cbefcb30e394268d33092b83b529ce 100644 (file)
 
 int strmaxlen (char *str, char ch);
 
+int sqrti (int x);
+
 board_t *initboard (int length);
 
+board_t *copyboard (board_t *board);
+
 board_t *initplay (board_t *board);
 
 void freeboard (board_t *board);
index 3068bb641d6bac1d6c3166167d8a9060c9dc1715..5d2da5dcddc014aab0165e828eb6587d03e583fb 100644 (file)
--- a/sudoku.c
+++ b/sudoku.c
@@ -89,7 +89,7 @@ int main (int argc, char *argv[])
     }
 
     /* init board */
-    board_t *board = initboard (length);
+    board_t *board = initboard (length * length);
     initplay (board);
 
     /* init curses */
diff --git a/type.h b/type.h
index f7731aeac299da1ae5db78a388a53c729477ab65..e7606a97be77a49b400501dd19af3fdcfb2a922a 100644 (file)
--- a/type.h
+++ b/type.h
@@ -3,7 +3,6 @@
 
 typedef struct {
     int length;
-    int nb;
     char *tab;
 } board_t;