Pannyx

devel

Request #05


~/devel/sleek
% cda
~/devel/proto/aej
% pp maze.c maze.h
#include <chars.h>
#define MAZE_C
#include <maze.h>

int_t screen_width;
int_t screen_height;

int_t board_width;
int_t board_height;

#define N_PAD 8192
static char s_pad_1 [N_PAD];
static char s_pad_2 [N_PAD];

void
draw_frame (void)
{
   int_t k;
   char * s;

   if (!( (s = getenv("COLUMNS")) == NULL)) { screen_width = atoll(s); } else { screen_width = 160; }
   if (!( (s = getenv("LINES")) == NULL)) { screen_height = atoll(s); } else { screen_height = 46; }
   board_width = screen_width - 3; board_height = screen_height - 4;
   fputs("\x1b[1;1H\x1b[2J", stdout);

   strncpy(s_pad_1, s_south_west_corner, 3);
   k = 1; while (k < board_width + 1) { strcpy(& s_pad_1 [k * 3], s_h_bar); k += 1; }
   strcpy(& s_pad_1 [k * 3], s_south_east_corner);
   mvto(0, 0); fputs(s_pad_1, stdout);

   strncpy(s_pad_2, s_v_bar, 3);
   memset(& s_pad_2 [3], '\x20', board_width);
   strcpy(& s_pad_2 [3 + board_width], s_v_bar);
   k = 1; while (k < board_height + 1) { mvto(0, k); fputs(s_pad_2, stdout); k += 1; }

   strncpy(s_pad_1, s_north_west_corner, 3);
   strcpy(& s_pad_1 [(board_width + 1) * 3], s_north_east_corner);
   mvto(0, board_height + 1); fputs(s_pad_1, stdout);

   fflush(stdout);
   return;

}

void
draw_gap (int_t x, int_t y)
{

   if (x < 1) {
      mvto(x, y - 1);
      if (1 < y) { fputs(s_north_east_corner, stdout); }  // ┐
      else       { fputs(s_h_bar,             stdout); }  // ─
      mvto(x, y + 1);
      if (y < board_height) { fputs(s_south_east_corner, stdout); }  // ┘
      else                  { fputs(s_h_bar,             stdout); }  // ─
   }
   else if (board_width < x) {
      mvto(x, y - 1);
      if (1 < y) { fputs(s_north_west_corner, stdout); }  // ┌
      else       { fputs(s_h_bar,             stdout); }  // ─
      mvto(x, y + 1);
      if (y < board_height) { fputs(s_south_west_corner, stdout); }  // └
      else                  { fputs(s_h_bar,             stdout); }  // ─
   }
   else if (y < 1) {
      mvto(x - 1, y);
      if (1 < x) { fputs(s_north_east_corner, stdout); }  // ┐
      else       { fputs(s_v_bar,             stdout); }  // │
      mvto(x + 1, y);
      if (x < board_width) { fputs(s_north_west_corner, stdout); }  // ┌
      else                 { fputs(s_v_bar,             stdout); }  // │
   }
   else if (board_height < y) {
      mvto(x - 1, y);
      if (1 < x) { fputs(s_south_east_corner, stdout); }  // ┘
      else       { fputs(s_v_bar,             stdout); }  // │
      mvto(x + 1, y);
      if (x < board_width) { fputs(s_south_west_corner, stdout); }  // └
      else                 { fputs(s_v_bar,             stdout); }  // │
   }
   else {
      ouch();
   }
   mvto(x, y);
   return;

}

void
mvto (int_t x, int_t y) {
      printf("\x1b[%lld;%lldH", screen_height - 2 - y, x + 1);
      return; }

void
acknowledge (char * s) {
      mvto(0, -1); fputs(s, stdout); fflush(stdout); while (!( getchar() == '\n')) { ; } mvto(0, -1);
      return; }

// maze.c
#ifndef MAZE_H
#define MAZE_H
#include <daejana.h>


#ifndef MAZE_C

extern int_t screen_width;
extern int_t screen_height;

extern int_t board_width;
extern int_t board_height;
#endif

void draw_frame (void);
void draw_gap (int_t, int_t);

void mvto (int_t, int_t);

void acknowledge (char *);

#endif
// maze.h
% cdm
~/devel/sleek
% pp maze_m.c
#include <chars.h>
#include <maze.h>

static void move (int_t, int_t);
static void draw (const char *);
static bool_t found_path (int_t);

enum { S, E, N, W };

static int_t perms [] = {
   0, 1, 2, 3,  0, 1, 3, 2,  0, 2, 1, 3,  0, 2, 3, 1,  0, 3, 1, 2,  0, 3, 2, 1,  0, 1, 2, 3,  0, 1, 3, 2,  0, 3, 1, 2,  0, 3, 2, 1,
//                                                                              S → E        S → E        S → W        S → W

   1, 0, 2, 3,  1, 0, 3, 2,  1, 2, 0, 3,  1, 2, 3, 0,  1, 3, 0, 2,  1, 3, 2, 0,  1, 3, 0, 2,  1, 3, 2, 0,  1, 3, 0, 2,  1, 3, 2, 0,
//                                                                              E → W        E → W        E → W        E → W

   2, 0, 1, 3,  2, 0, 3, 1,  2, 1, 0, 3,  2, 1, 3, 0,  2, 3, 0, 1,  2, 3, 1, 0,  2, 1, 0, 3,  2, 1, 3, 0,  2, 3, 0, 1,  2, 3, 1, 0,
//                                                                              N → E        N → E        N → W        N → W

   3, 0, 1, 2,  3, 0, 2, 1,  3, 1, 0, 2,  3, 1, 2, 0,  3, 2, 0, 1,  3, 2, 1, 0,  3, 1, 0, 2,  3, 1, 2, 0,  3, 1, 0, 2,  3, 1, 2, 0,
//                                                                              W → E        W → E        W → E        W → E
};

int_t x_diff [] = {  0,  1,  0, -1 };
int_t y_diff [] = { -1,  0,  1,  0 };

const char * s_mark [] = {
   s_skull,             s_north_west_corner, s_v_bar,             s_north_east_corner,  // ☠ ┌ │ ┐
                                                                                    // S → S E N W

   s_north_west_corner, s_skull,             s_south_west_corner, s_h_bar,              // ┌ ☠ └ ─
                                                                                    // E → S E N W

   s_v_bar,             s_south_west_corner, s_skull,             s_south_east_corner,  // │ └ ☠ ┘
                                                                                    // N → S E N W

   s_north_east_corner, s_h_bar,             s_south_east_corner, s_skull               // ┐ ─ ┘ ☠
                                                                                    // W → S E N W
};

static bool_t * taken;

static int_t where_x;
static int_t where_y;

static void
move (int_t x, int_t y) {
      mvto(x + 1, y + 1);
      where_x = x; where_y = y;
      return; }

static void
draw (const char * s) {
      fputs(s, stdout);
      return; }

static bool_t
found_path (int_t whence)
{
   int_t * a; int_t k;
   int_t heading; int_t x; int_t y;

   if (where_x          < 0      ) { draw_gap(where_x + 1, where_y + 1); draw(s_h_bar); return true; }
   if (board_width - 1  < where_x) { draw_gap(where_x + 1, where_y + 1); draw(s_h_bar); return true; }
   if (where_y          < 0      ) { draw_gap(where_x + 1, where_y + 1); draw(s_v_bar); return true; }
   if (board_height - 1 < where_y) { draw_gap(where_x + 1, where_y + 1); draw(s_v_bar); return true; }

   taken [(1 + where_y) * (board_width + 2) + 1 + where_x] = true;
   a = & perms [whence * 40 + rand() % 10 * 4 + 1];
   k = 0;
   while (k < 3) {
      heading = a[k];
      x = where_x + x_diff[heading]; y = where_y + y_diff[heading];
      if (! taken [(1 + y) * (board_width + 2) + 1 + x]) {
         draw(s_mark[whence * 4 + heading]);
         move(x, y);
         if (found_path((heading + 2) % 4)) { return true; }

         move(where_x + x_diff[(heading + 2) % 4], where_y + y_diff[(heading + 2) % 4]);
      }
      k += 1;
   }
   draw("\x20");
   taken [(1 + where_y) * (board_width + 2) + 1 + where_x] = false;
   return false;

}

int
main (int argc, char * argv [])
{
   int_t k;

   error_flag = false;
   srand(rseed());
   draw_frame();
   {
      bool_t a [(board_width + 2) * (board_height + 2)];

      taken = a;
      mvto(0, -1); draw(s_ellipsis);
      k = 0; while (k < (board_width + 2) * (board_height + 2)) { taken[k] = false; k += 1; }
      move(board_width / 8 + rand() % board_width * 3 / 4, board_height / 4 + rand() % board_height / 2);
      draw(s_x_cross);
      taken [(1 + where_y) * (board_width + 2) + 1 + where_x] = true;
      k = rand() % 4;
      move(where_x + x_diff[k], where_y + y_diff[k]);
      if (! found_path((k + 2) % 4)) { ouch(); }
   }
   mvto(0, 0);
   printf("\n");
   if (error_flag) { exit(EXIT_FAILURE); }

   return EXIT_SUCCESS;

}

// maze_m.c
% cmr maze_m chars maze

┌───────────┘│└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│            │                                                                                                                                                │
│            └┐                                                                                                                                               │
│             └─────┐                                                                                                                                         │
│                   │                      ┌┐                         ┌───────┐                                                                               │
│                   └────┐            ┌────┘│┌─┐     ┌─┐              └────┐  └──────┐                                                                        │
│                  ┌─────┘        ┌──┐└─┐   │└┐│     │┌┘                  ┌┘ ┌┐     ┌┘                                                                        │
│                  │              └┐ └─┐└──┐│ │└───┐┌┘└─┐              ┌─┐│┌─┘└┐    │┌─┐                  ┌───┐                                               │
│                  │  ┌───┐        │   └───┘└─┘    └┘ ┌─┘  ┌──┐        │┌┘└┘┌──┘    │└┐│               ┌──┘   └──────┐                                        │
│                  └──┘  ┌┘        │      ┌─┐         └────┘  │      ┌─┘└┐ ┌┘    ┌─┐└─┘└─┐            ┌┘           ┌─┘                                        │
│                        └─┐       │      │┌┘            ┌───┐└┐   ┌─┘ ┌─┘ └─────┘┌┘   ┌┐└─┐        ┌─┘       ┌───┐└─┐                                        │
│                          │       │   ┌──┘└──┐┌─┐       └┐  └─┘   └─┐ └──────┐   │   ┌┘└──┘        │    ┌────┘   │┌─┘                                        │
│                         ┌┘       └┐┌┐└┐     └┘ │       ┌┘          └──┐    ┌┘   └┐ ┌┘             └────┘ ┌─────┐│└─┐                                        │
│                   ┌─────┘   ┌┐    ││└─┘┌──┐   ┌┘      ┌┘          ┌───┘┌───┘┌────┘ │                  ┌┐ └────┐└┘  │                                        │
│           ┌──┐ ┌─┐└┐┌┐┌┐┌──┐│└───┐│└──┐│┌─┘   │      ┌┘           └┐┌──┘   ┌┘      │             ┌─┐  ││     ┌┘┌──✕│                                        │
│           └┐ └─┘ └─┘│└┘│└┐ └┘ ┌┐┌┘│   └┘└┐    │┌─┐┌─┐└─┐          ┌┘└────┐┌┘ ┌┐    │             └┐│┌─┘│     └┐└───┘                                        │
│            └──┐┌────┘ ┌┘ └────┘│└─┘┌─────┘    └┘ └┘┌┘┌─┘          │┌┐  ┌─┘└──┘└┐┌──┘            ┌─┘└┘┌─┘ ┌───┐└┐                                            │
│               └┘    ┌─┘ ┌─────┐└┐  └──┐        ┌───┘ └─┐ ┌───┐ ┌┐ └┘└─┐└──┐  ┌─┘└─┐          ┌─┐└───┐└───┘┌─┐└─┘                                            │
│          ┌──────────┘┌──┘┌────┘ └─────┘  ┌─────┘       └─┘   └┐│└────┐└┐  └┐ └─┐  │  ┌───┐  ┌┘ │    └────┐│ └─┐                                             │
│         ┌┘           │┌──┘┌────────┐    ┌┘                    └┘    ┌┘ └┐┌─┘ ┌┐│┌─┘┌┐└┐  │ ┌┘  │       ┌─┘└┐  │                                             │
│         │         ┌──┘└───┘        └───┐│                           └──┐│└───┘└┘└──┘└┐│┌─┘┌┘   │       └───┘  │                                             │
│         └───┐    ┌┘                    └┘                   ┌─┐     ┌──┘└───────┐ ┌──┘│└──┘    └─────────┐  ┌─┘                                             │
│            ┌┘    │                                    ┌───┐ └┐│ ┌───┘┌──┐     ┌─┘ └──┐└┐                 └──┘                                               │
│            └─────┘                                   ┌┘   └──┘└─┘    └─┐│     └─┐    └─┘                                                                    │
│                                                      └┐            ┌┐ ┌┘└───┐   │                                                                           │
│                                                 ┌──┐┌─┘            ││┌┘     └──┐└─┐                                                                         │
│                                              ┌─┐└─┐└┘┌──┐          │└┘         └──┘                                                                         │
│                                             ┌┘┌┘  │  │  └┐        ┌┘┌─────┐                                                                                 │
│                                             │ └─┐┌┘  │   └────┐   └─┘    ┌┘                                                                                 │
│                                             └─┐ └┘┌─┐│        └┐         └┐                                                                                 │
│                                               └┐  └┐└┘         │ ┌───┐┌──┐└─────┐                                                                           │
│                                                └───┘           └─┘ ┌─┘│ ┌┘  ┌───┘                                                                           │
│                                                                    └─┐└┐│   └────┐                                                                          │
│                                                                      └─┘└─┐┌┐    │                                                                          │
│                                                                         ┌─┘│└────┘                                                                          │
│                                                                         └──┘                                                                                │
│                                                                                                                                                             │
│                                                                                                                                                             │
│                                                                                                                                                             │
│                                                                                                                                                             │
│                                                                                                                                                             │
│                                                                                                                                                             │
│                                                                                                                                                             │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
%