-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest-maze.awk
executable file
·103 lines (97 loc) · 3.3 KB
/
test-maze.awk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env gawk -f
#
# Copyright (c) 2023 Jegors Čemisovs
# License: MIT License
# Repository: https://github.com/rabestro/awk-maze-generator
#
# These variables are initialized on the command line (using '-v'):
# - Rows
# - Cols
#
function die(message) {print message > "/dev/stderr"; exit 1}
function assert(condition, message) {if (!condition) die(message)}
BEGIN {
ExpectedCols = Cols * 2 + 1
ExpectedRows = Rows * 2 + 1
FPAT = "."
OFS = ""
}
NF != ExpectedCols {
die("Error: expected " ExpectedCols " columns, got " NF " at line " NR)
}
NR > ExpectedRows {
die("Error: expected no more then " ExpectedRows " rows, got " NR)
}
{
++Height
}
Height == 1 && !/┌[─┬]+┐/ {
die("Error: an invalid pattern of the top border")
}
$1 == "⇨" {
assert(!StartRow, "Error: multiple start points at line " NR)
assert(Height % 2 == 0, "Error: start point must be at the even row")
StartRow = Height
}
$NF == "⇨" {
if (EndRow) die("Error: multiple end points at line " NR)
assert(Height % 2 == 0, "Error: end point must be at the even row")
EndRow = Height
}
{
for (; NF; --NF) Grid[Height, NF] = $NF
}
ENDFILE {
assert(StartRow, "Error: no start point")
assert(EndRow, "Error: no end point")
assert(Height == ExpectedRows, "Error: expected " ExpectedRows " rows, got " Height)
check_symbols()
fill_spaces(2, 2)
check_vertices()
print "The maze is perfect."
}
function check_symbols( row,col,cell) {
for (row = ExpectedRows; row; --row)
for (col = ExpectedCols; col; --col) {
cell = Grid[row, col]
if (row == 1 || row == ExpectedRows || col == 1 || col == ExpectedCols) {
assert(cell != " ", "Error: border at " row "," col " is empty")
}
if (row % 2 == 0 && col % 2 == 0) {
assert(cell == " ", "Error: vertex at " row "," col " is not empty")
}
if (cell != " " && cell != "⇨") {
assert(cell == symbol(row, col), "Error: invalid symbol '" cell "' at " row "," col ". Expected: '" symbol(row, col) "'")
}
}
}
function symbol(row, col, n,e,s,w) {
n = row > 1 && Grid[row - 1, col] != " "
e = col < ExpectedCols && Grid[row, col + 1] != " "
s = row < ExpectedRows && Grid[row + 1, col] != " "
w = col > 1 && Grid[row, col - 1] != " "
return substr(" │─└││┌├─┘─┴┐┤┬┼", 1 + n + 2 * e + 4 * s + 8 * w, 1)
}
function fill_spaces(row, col, directions,randDir,dx,dy) {
assert(Grid[row, col] == " ", "Error: an extra passage detected at " row "," col)
Grid[row, col] = "·"
directions = "NESW"
while (length(directions)) {
randDir = substr(directions, 1, 1)
sub(randDir, "", directions)
dx = dy = 0
if (randDir == "N") dy = -1
if (randDir == "E") dx = 1
if (randDir == "S") dy = 1
if (randDir == "W") dx = -1
if (Grid[row + dy, col + dx] == " ") {
Grid[row + dy, col + dx] = "·"
fill_spaces(row + 2 * dy, col + 2 * dx)
}
}
}
function check_vertices( row,col) {
for (row = 2; row < ExpectedRows; row += 2)
for (col = 2; col < ExpectedCols; col += 2)
assert(Grid[row, col] != " ", "Error: vertex at " row "," col " is not reachable")
}