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
┌───────────┘│└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ │ │
│ └┐ │
│ └─────┐ │
│ │ ┌┐ ┌───────┐ │
│ └────┐ ┌────┘│┌─┐ ┌─┐ └────┐ └──────┐ │
│ ┌─────┘ ┌──┐└─┐ │└┐│ │┌┘ ┌┘ ┌┐ ┌┘ │
│ │ └┐ └─┐└──┐│ │└───┐┌┘└─┐ ┌─┐│┌─┘└┐ │┌─┐ ┌───┐ │
│ │ ┌───┐ │ └───┘└─┘ └┘ ┌─┘ ┌──┐ │┌┘└┘┌──┘ │└┐│ ┌──┘ └──────┐ │
│ └──┘ ┌┘ │ ┌─┐ └────┘ │ ┌─┘└┐ ┌┘ ┌─┐└─┘└─┐ ┌┘ ┌─┘ │
│ └─┐ │ │┌┘ ┌───┐└┐ ┌─┘ ┌─┘ └─────┘┌┘ ┌┐└─┐ ┌─┘ ┌───┐└─┐ │
│ │ │ ┌──┘└──┐┌─┐ └┐ └─┘ └─┐ └──────┐ │ ┌┘└──┘ │ ┌────┘ │┌─┘ │
│ ┌┘ └┐┌┐└┐ └┘ │ ┌┘ └──┐ ┌┘ └┐ ┌┘ └────┘ ┌─────┐│└─┐ │
│ ┌─────┘ ┌┐ ││└─┘┌──┐ ┌┘ ┌┘ ┌───┘┌───┘┌────┘ │ ┌┐ └────┐└┘ │ │
│ ┌──┐ ┌─┐└┐┌┐┌┐┌──┐│└───┐│└──┐│┌─┘ │ ┌┘ └┐┌──┘ ┌┘ │ ┌─┐ ││ ┌┘┌──✕│ │
│ └┐ └─┘ └─┘│└┘│└┐ └┘ ┌┐┌┘│ └┘└┐ │┌─┐┌─┐└─┐ ┌┘└────┐┌┘ ┌┐ │ └┐│┌─┘│ └┐└───┘ │
│ └──┐┌────┘ ┌┘ └────┘│└─┘┌─────┘ └┘ └┘┌┘┌─┘ │┌┐ ┌─┘└──┘└┐┌──┘ ┌─┘└┘┌─┘ ┌───┐└┐ │
│ └┘ ┌─┘ ┌─────┐└┐ └──┐ ┌───┘ └─┐ ┌───┐ ┌┐ └┘└─┐└──┐ ┌─┘└─┐ ┌─┐└───┐└───┘┌─┐└─┘ │
│ ┌──────────┘┌──┘┌────┘ └─────┘ ┌─────┘ └─┘ └┐│└────┐└┐ └┐ └─┐ │ ┌───┐ ┌┘ │ └────┐│ └─┐ │
│ ┌┘ │┌──┘┌────────┐ ┌┘ └┘ ┌┘ └┐┌─┘ ┌┐│┌─┘┌┐└┐ │ ┌┘ │ ┌─┘└┐ │ │
│ │ ┌──┘└───┘ └───┐│ └──┐│└───┘└┘└──┘└┐│┌─┘┌┘ │ └───┘ │ │
│ └───┐ ┌┘ └┘ ┌─┐ ┌──┘└───────┐ ┌──┘│└──┘ └─────────┐ ┌─┘ │
│ ┌┘ │ ┌───┐ └┐│ ┌───┘┌──┐ ┌─┘ └──┐└┐ └──┘ │
│ └─────┘ ┌┘ └──┘└─┘ └─┐│ └─┐ └─┘ │
│ └┐ ┌┐ ┌┘└───┐ │ │
│ ┌──┐┌─┘ ││┌┘ └──┐└─┐ │
│ ┌─┐└─┐└┘┌──┐ │└┘ └──┘ │
│ ┌┘┌┘ │ │ └┐ ┌┘┌─────┐ │
│ │ └─┐┌┘ │ └────┐ └─┘ ┌┘ │
│ └─┐ └┘┌─┐│ └┐ └┐ │
│ └┐ └┐└┘ │ ┌───┐┌──┐└─────┐ │
│ └───┘ └─┘ ┌─┘│ ┌┘ ┌───┘ │
│ └─┐└┐│ └────┐ │
│ └─┘└─┐┌┐ │ │
│ ┌─┘│└────┘ │
│ └──┘ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
%