add validation messages
authorLaurent MAZET <laurent.mazet@thalesgroup.com>
Fri, 20 Dec 2024 10:57:14 +0000 (11:57 +0100)
committerLaurent MAZET <laurent.mazet@thalesgroup.com>
Fri, 20 Dec 2024 10:57:14 +0000 (11:57 +0100)
display.c
display.h
sokoban.c

index 75ec61fe55e0bccfee0a5fe50c11cf4d31e0350d..0b732b9608412ccf7e7de8d824f1dec15fba9f3a 100644 (file)
--- a/display.c
+++ b/display.c
@@ -374,10 +374,53 @@ char *savewindow (int length, int xoffset, int yoffset)
 
 void msgwindow (char *msg, int xoffset, int yoffset, int length)
 {
-    set_color (white);
+    set_color (black);
     _dobound ((length > 0) ? length : (int)strlen (msg), 1, xoffset, yoffset);
+    set_color (white);
     mvaddstr (yoffset, xoffset + ((length > 0) ? (length - (int)strlen (msg)) / 2 : 0), msg);
-    set_color (black);
+}
+
+int askwindow (char *msg, int xoffset, int yoffset, char *ok, char *ko)
+{
+    size_t i;
+
+    msgwindow (msg, xoffset, yoffset, 0);
+
+    int stop = 0;
+    while (!stop) {
+        int ch = getch ();
+
+        for (i = 0; i < strlen (ok); i++) {
+            if (ch == ok[i]) {
+                stop = 1;
+                break;
+            }
+        }
+
+        for (i = 0; i < strlen (ko); i++) {
+            if (ch == ko[i]) {
+                stop = -1;
+                break;
+            }
+        }
+
+        switch (ch) {
+        case ' ':
+        case '\n':
+        case '\r':
+            stop = 1;
+            break;
+        case KEY_BACKSPACE:
+        case KEY_DELETE:
+        case 127:
+        case '\b':
+        case KEY_ESC:
+            stop = -1;
+            break;
+        }
+    }
+
+    return stop;
 }
 
 /* vim: set ts=4 sw=4 et: */
index df04aa748f60a35b9b1d306f075f852939d0d4b3..936a4065d4282b49c2239dde77682526d4912fd7 100644 (file)
--- a/display.h
+++ b/display.h
@@ -14,6 +14,8 @@ char *savewindow (int length, int xoffset, int yoffset);
 
 void msgwindow (char *msg, int xoffset, int yoffset, int length);
 
+int askwindow (char *msg, int xoffset, int yoffset, char *ok, char *ko);
+
 #endif /* __DISPLAY_H__ */
 
 /* vim: set ts=4 sw=4 et: */
index 3e72f87aaf01f4ec971a808327ed8a38d9637f2f..19a394c87093e748340f03b93fcfa9a70c08135a 100644 (file)
--- a/sokoban.c
+++ b/sokoban.c
@@ -19,18 +19,19 @@ char *version = "0.1";
 
 char *filename = NULL; /* .sok */
 int level = 0;
-int savelen = 12;
 int scale = 1;
 int wide = 0;
-int xoffset = 1;
-int yoffset = 1;
+
+const int savelen = 12;
+const int xoffset = 0;
+const int yoffset = 0;
 
 char *help =
     "< > Go to next level\n"
-    "<i> Move up cursor\n"
-    "<j> Move left cursor\n"
-    "<k> Move down cursor\n"
-    "<l> Move right cursor\n"
+    "<i> Move up sokoban\n"
+    "<j> Move left sokoban\n"
+    "<k> Move down sokoban\n"
+    "<l> Move right sokoban\n"
     "<q> Quit\n"
     "<r> Restart level\n"
     "<s> Save file\n"
@@ -158,59 +159,48 @@ int main (int argc, char *argv[])
     curs_set (0);
     start_color ();
 
-    /* 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 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');
-
     /* event loop */
-    int mode = 0;
     int stop = 0;
     int dir = -1;
-    board_t *current = copyboard (board);
+    board_t *current = NULL;
+    char *savename = NULL;
     while (!stop) {
         char *ptr = NULL;
 
+        /* init board */
+        if (current == NULL) {
+            board->xoffset = xoffset + 1;
+            board->yoffset = xoffset + 1;
+            current = copyboard (board);
+            helpwindow (help, 2 * board->xoffset + 1 + board->xsize, board->yoffset - 1);
+        }
+
+        /* main action */
         if (dir >= 0) {
             movesokoban (current, dir);
             dir = -1;
         }
         boardwindow (current);
-        mode = endofgame (current);
+
+        /* tesdt end of game */
+        if (endofgame (current)) {
+            askwindow (" Next level ", max (board->xoffset + (board->xsize - savelen) / 2, 1), board->yoffset + (board->ysize - 1) / 2, "Yy", "Nn");
+            freeboard (current);
+            current = NULL;
+            level++;
+            board_t *temp = getlevel (level);
+            if (temp) {
+                freeboard (board);
+                board = copyboard (temp);
+                setscale (board, scale);
+            } else {
+                stop = 1;
+            }
+            continue;
+        }
 
         int ch = getch ();
         switch (ch) {
-        case ' ':
-        case '\n':
-        case '\r':
-            if (mode == 1) {
-                freeboard (current);
-                level++;
-                board_t *temp = getlevel (level);
-                if (temp) {
-                    freeboard (board);
-                    board = copyboard (temp);
-                    setscale (board, scale);
-                    current = copyboard (board);
-                } else {
-                    stop = 1;
-                }
-            }
-            break;
         case KEY_UP:
         case 'i':
             dir = 0;
@@ -230,6 +220,7 @@ int main (int argc, char *argv[])
         case KEY_ESC:
         case 'q':
             freeboard (current);
+            current = NULL;
             stop = 1;
             break;
         case KEY_BACKSPACE:
@@ -237,11 +228,13 @@ int main (int argc, char *argv[])
         case 127:
         case '\b':
         case 'r':
-            freeboard (current);
-            current = copyboard (board);
+            if (askwindow (" Restart (Y/N) ", max (board->xoffset + (board->xsize - savelen) / 2, 1), board->yoffset + (board->ysize - 1) / 2, "Yy", "Nn") == 1) {
+                freeboard (current);
+                current = NULL;
+            }
             break;
         case 's':
-            savename = savewindow (savelen, xsave, ysave);
+            savename = savewindow (savelen, max (board->xoffset + (board->xsize - savelen) / 2, 1), board->yoffset + (board->ysize - 1) / 2);
             if (savename != NULL) {
                 ptr = saveboard (board);
                 if (writedata (savename, ptr)) {
@@ -276,5 +269,6 @@ int main (int argc, char *argv[])
 /* test: { sleep 1; echo -n k; sleep 1; echo -ne 'a.sok\e'; sleep 1; echo -e 'sab\b.sok'; sleep 1; echo q; } | sokoban.exe -v 3 -f test.sok */
 /* test: { sleep 1; echo s; sleep 1; echo q; } | sokoban.exe -f a.sok && rm a.sok && test \! -f b.sok */
 /* test: { sleep 1; echo -n kkklll; sleep 1; echo -n jjjiiillkk; sleep 1; echo -n iijjkkkll; sleep 3; echo; } | sokoban.exe -f test.sok -s 3 */
+/* test: { sleep 1; echo -n kkklll; sleep 1; echo -n jjjiiillkk; sleep 1; echo -n iijjkkkll; sleep 1; echo; echo -n ijjjj; sleep 1; echo -n r; sleep 1; echo -n y; sleep 1; echo -n illl; sleep 1; echo -n r; sleep 1; echo -n n; sleep 1; } | sokoban.exe */
 
 /* vim: set ts=4 sw=4 et: */