]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - test/bs.c
ncurses 6.4 - patch 20240420
[ncurses.git] / test / bs.c
index a954d2d2ade23630e2adcaec3ea3f4f5bdf9d77b..c7569cf207fd6a9c79de9814b03642f493464c8a 100644 (file)
--- a/test/bs.c
+++ b/test/bs.c
@@ -1,5 +1,6 @@
 /****************************************************************************
- * Copyright (c) 1998-2016,2017 Free Software Foundation, Inc.              *
+ * Copyright 2018-2022,2023 Thomas E. Dickey                                *
+ * Copyright 1998-2016,2017 Free Software Foundation, Inc.                  *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -25,7 +26,7 @@
  * sale, use or other dealings in this Software without prior written       *
  * authorization.                                                           *
  ****************************************************************************/
-/* 
+/*
  * bs.c - original author: Bruce Holloway
  *             salvo option by: Chuck A DeGaul
  * with improved user interface, autoconfiguration and code cleanup
@@ -34,7 +35,7 @@
  * v2.0 featuring strict ANSI/POSIX conformance, November 1993.
  * v2.1 with ncurses mouse support, September 1995
  *
- * $Id: bs.c,v 1.70 2017/09/30 15:40:39 tom Exp $
+ * $Id: bs.c,v 1.79 2023/05/27 20:13:10 tom Exp $
  */
 
 #include <test.priv.h>
@@ -116,17 +117,20 @@ static char *your_name;
 static char dftname[] = "stranger";
 
 /* direction constants */
-#define E      0
-#define SE     1
-#define S      2
-#define SW     3
-#define W      4
-#define NW     5
-#define N      6
-#define NE     7
-static int xincr[8] =
+typedef enum {
+    dir_E = 0
+    ,dir_SE
+    ,dir_S
+    ,dir_SW
+    ,dir_W
+    ,dir_NW
+    ,dir_N
+    ,dir_NE
+    ,dir_MAX
+} DIRECTIONS;
+static int xincr[dir_MAX + 2] =
 {1, 1, 0, -1, -1, -1, 0, 1};
-static int yincr[8] =
+static int yincr[dir_MAX + 2] =
 {0, 1, 1, 1, 0, -1, -1, -1};
 
 /* current ship position and direction */
@@ -177,7 +181,7 @@ static int salvo, blitz, closepack;
 
 #define        PR      (void)addstr
 
-static void uninitgame(int sig) GCC_NORETURN;
+static GCC_NORETURN void uninitgame(int sig);
 
 static void
 uninitgame(int sig GCC_UNUSED)
@@ -327,9 +331,9 @@ randomplace(int b, ship_t * ss)
 {
 
     do {
-       ss->dir = rnd(2) ? E : S;
-       ss->x = rnd(BWIDTH - (ss->dir == E ? ss->length : 0));
-       ss->y = rnd(BDEPTH - (ss->dir == S ? ss->length : 0));
+       ss->dir = rnd(2) ? dir_E : dir_S;
+       ss->x = rnd(BWIDTH - (ss->dir == dir_E ? ss->length : 0));
+       ss->y = rnd(BDEPTH - (ss->dir == dir_S ? ss->length : 0));
     } while
        (!checkplace(b, ss, FALSE));
 }
@@ -495,19 +499,19 @@ initgame(void)
            switch (c) {
            case 'k':
            case '8':
-               ss->dir = N;
+               ss->dir = dir_N;
                break;
            case 'j':
            case '2':
-               ss->dir = S;
+               ss->dir = dir_S;
                break;
            case 'h':
            case '4':
-               ss->dir = W;
+               ss->dir = dir_W;
                break;
            case 'l':
            case '6':
-               ss->dir = E;
+               ss->dir = dir_E;
                break;
            }
 
@@ -545,14 +549,15 @@ initgame(void)
 static int
 getcoord(int atcpu)
 {
-    int ny, nx, c;
-
     if (atcpu)
        cgoto(cury, curx);
     else
        pgoto(cury, curx);
     (void) refresh();
+
     for (;;) {
+       int ny, nx, c;
+
        if (atcpu) {
            MvPrintw(CYBASE + BDEPTH + 1, CXBASE + 11, "(%d, %c)",
                     curx, 'A' + cury);
@@ -665,7 +670,7 @@ collidecheck(int b, int y, int x)
     if (!closepack) {
        int i;
 
-       for (i = 0; i < 8; i++) {
+       for (i = 0; i < dir_MAX; i++) {
            int xend, yend;
 
            yend = y + yincr[i];
@@ -728,10 +733,9 @@ static int
 awinna(void)
 {
     int i, j;
-    ship_t *ss;
 
     for (i = 0; i < 2; ++i) {
-       ss = (i) ? cpuship : plyship;
+       ship_t *ss = (i) ? cpuship : plyship;
        for (j = 0; j < SHIPTYPES; ++j, ++ss)
            if (ss->length > ss->hits)
                break;
@@ -758,12 +762,14 @@ hitship(int x, int y)
            if (++ss->hits < ss->length)        /* still afloat? */
                return ((ship_t *) NULL);
            else {              /* sunk! */
-               int i, j;
+               int i;
+
+               if (!closepack) {
+                   int j;
 
-               if (!closepack)
                    for (j = -1; j <= 1; j++) {
-                       int bx = ss->x + j * xincr[(ss->dir + 2) % 8];
-                       int by = ss->y + j * yincr[(ss->dir + 2) % 8];
+                       int bx = ss->x + j * xincr[(ss->dir + 2) % dir_MAX];
+                       int by = ss->y + j * yincr[(ss->dir + 2) % dir_MAX];
 
                        for (i = -1; i <= ss->length; ++i) {
                            int x1, y1;
@@ -789,6 +795,7 @@ hitship(int x, int y)
                            }
                        }
                    }
+               }
 
                for (i = 0; i < ss->length; ++i) {
                    int x1 = ss->x + i * xincr[ss->dir];
@@ -881,18 +888,19 @@ plyturn(void)
 static int
 sgetc(const char *s)
 {
-    const char *s1;
-    int ch;
-
     (void) refresh();
+
     for (;;) {
-       ch = getch();
+       int ch = getch();
+       const char *s1;
+
        if (islower(ch))
            ch = toupper(ch);
        if (is_QUIT(ch))
            uninitgame(0);
-       for (s1 = s; *s1 && ch != *s1; ++s1)
-           continue;
+       for (s1 = s; *s1 && ch != *s1; ++s1) {
+           /* EMPTY */ ;
+       }
        if (*s1) {
            AddCh(ch);
            (void) refresh();
@@ -1027,11 +1035,14 @@ cputurn(void)
        break;
 
     case RANDOM_HIT:           /* last shot was random and hit */
-       used[E / 2] = used[S / 2] = used[W / 2] = used[N / 2] = FALSE;
+       used[dir_E / 2] =
+           used[dir_S / 2] =
+           used[dir_W / 2] =
+           used[dir_N / 2] = FALSE;
        /* FALLTHROUGH */
 
     case HUNT_DIRECT:          /* last shot hit, we're looking for ship's long axis */
-       for (d = navail = 0; d < 4; d++) {
+       for (d = navail = 0; d < (dir_MAX) / 2; d++) {
            x = ts.x + xincr[d * 2];
            y = ts.y + yincr[d * 2];
            if (!used[d] && POSSIBLE(x, y))
@@ -1043,13 +1054,13 @@ cputurn(void)
            goto refire;        /* ...so we must random-fire */
        else {
            n = rnd(navail) + 1;
-           for (d = 0; d < 4 && used[d]; d++) ;
+           for (d = 0; d < (dir_MAX) / 2 && used[d]; d++) ;
            /* used[d] is first that == 0 */
            for (; n > 1; n--)
-               while (d < 4 && used[++d]) ;
+               while (d < (dir_MAX) / 2 && used[++d]) ;
            /* used[d] is next that == 0 */
 
-           assert(d < 4);
+           assert(d < (dir_MAX) / 2);
            assert(used[d] == FALSE);
 
            used[d] = TRUE;
@@ -1083,7 +1094,7 @@ cputurn(void)
        break;
 
     case REVERSE_JUMP:         /* nail down the ship's other end */
-       d = (ts.dir + 4) % 8;
+       d = (ts.dir + (dir_MAX) / 2) % dir_MAX;
        x = ts.x + ts.hits * xincr[d];
        y = ts.y + ts.hits * yincr[d];
        if (POSSIBLE(x, y) && (hit = cpufire(x, y))) {
@@ -1152,55 +1163,6 @@ playagain(void)
     return (sgetc("YN") == 'Y');
 }
 
-static void
-do_options(int c, char *op[])
-{
-    register int i;
-
-    if (c > 1) {
-       for (i = 1; i < c; i++) {
-           switch (op[i][0]) {
-           default:
-           case '?':
-               (void) fprintf(stderr, "Usage: battle [-s | -b] [-c]\n");
-               (void) fprintf(stderr, "\tWhere the options are:\n");
-               (void) fprintf(stderr, "\t-s : play a salvo game\n");
-               (void) fprintf(stderr, "\t-b : play a blitz game\n");
-               (void) fprintf(stderr, "\t-c : ships may be adjacent\n");
-               ExitProgram(EXIT_FAILURE);
-               break;
-           case '-':
-               switch (op[i][1]) {
-               case 'b':
-                   blitz = 1;
-                   if (salvo == 1) {
-                       (void) fprintf(stderr,
-                                      "Bad Arg: -b and -s are mutually exclusive\n");
-                       ExitProgram(EXIT_FAILURE);
-                   }
-                   break;
-               case 's':
-                   salvo = 1;
-                   if (blitz == 1) {
-                       (void) fprintf(stderr,
-                                      "Bad Arg: -s and -b are mutually exclusive\n");
-                       ExitProgram(EXIT_FAILURE);
-                   }
-                   break;
-               case 'c':
-                   closepack = 1;
-                   break;
-               default:
-                   (void) fprintf(stderr,
-                                  "Bad arg: type \"%s ?\" for usage message\n",
-                                  op[0]);
-                   ExitProgram(EXIT_FAILURE);
-               }
-           }
-       }
-    }
-}
-
 static int
 scount(int who)
 {
@@ -1221,12 +1183,68 @@ scount(int who)
     return (shots);
 }
 
+static void
+usage(int ok)
+{
+    static const char *msg[] =
+    {
+       "Usage: bs [options]"
+       ,""
+       ,USAGE_COMMON
+       ,"Options:"
+       ," -b       play a blitz game"
+       ," -c       ships may be adjacent"
+       ," -s       play a salvo game"
+    };
+    size_t n;
+
+    for (n = 0; n < SIZEOF(msg); n++)
+       fprintf(stderr, "%s\n", msg[n]);
+
+    ExitProgram(ok ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+/* *INDENT-OFF* */
+VERSION_COMMON()
+/* *INDENT-ON* */
+
 int
 main(int argc, char *argv[])
 {
-    setlocale(LC_ALL, "");
+    int ch;
+
+    while ((ch = getopt(argc, argv, OPTS_COMMON "bcs")) != -1) {
+       switch (ch) {
+       case 'b':
+           blitz = 1;
+           if (salvo == 1) {
+               (void) fprintf(stderr,
+                              "Bad Arg: -b and -s are mutually exclusive\n");
+               ExitProgram(EXIT_FAILURE);
+           }
+           break;
+       case 's':
+           salvo = 1;
+           if (blitz == 1) {
+               (void) fprintf(stderr,
+                              "Bad Arg: -s and -b are mutually exclusive\n");
+               ExitProgram(EXIT_FAILURE);
+           }
+           break;
+       case 'c':
+           closepack = 1;
+           break;
+       case OPTS_VERSION:
+           show_version(argv);
+           ExitProgram(EXIT_SUCCESS);
+       default:
+           usage(ch == OPTS_USAGE);
+           /* NOTREACHED */
+       }
+    }
+    if (optind < argc)
+       usage(FALSE);
 
-    do_options(argc, argv);
+    setlocale(LC_ALL, "");
 
     intro();
     do {
@@ -1253,8 +1271,9 @@ main(int argc, char *argv[])
                    }
                }
            } else
-               while ((turn ? cputurn() : plyturn()) && awinna() == -1)
-                   continue;
+               while ((turn ? cputurn() : plyturn()) && awinna() == -1) {
+                   /* EMPTY */ ;
+               }
            turn = OTHER;
        }
     } while