Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exercise: Mazy Mice #211

Merged
merged 24 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ac718b4
Implement maze generation algorithm
rabestro Aug 12, 2023
a3c54af
Add unit tests for maze generator
rabestro Aug 13, 2023
004e77c
Add unit tests for maze generator
rabestro Aug 13, 2023
d017a53
Replace maze-generator.awk with mazy-mice.awk in tests
rabestro Aug 13, 2023
ae986c8
Update mazy-mice exercise documentation
rabestro Aug 17, 2023
e25d425
Add bats-support and bats-assert source code
rabestro Aug 17, 2023
de3cb04
Update 'config.json' for mazy-mice exercise
rabestro Aug 17, 2023
532669c
Add new exercise 'mazy-mice' to config.json
rabestro Aug 17, 2023
849175a
Add hints documentation for 'mazy-mice'
rabestro Aug 17, 2023
1320f85
Update exercises/practice/mazy-mice/.docs/introduction.md
rabestro Aug 17, 2023
718af54
Update exercises/practice/mazy-mice/.meta/config.json
rabestro Aug 17, 2023
bc6216d
Update exercises/practice/mazy-mice/.docs/instructions.md
rabestro Aug 18, 2023
aa6169c
Add box drawing characters to 'mazy-mice' hints
rabestro Aug 22, 2023
389c13f
Merge remote-tracking branch 'origin/maze-generator' into maze-generator
rabestro Aug 22, 2023
de18457
Update maze size notation in instructions.md
rabestro Aug 23, 2023
d56fb8c
Refine maze dimension instructions in mazy-mice exercise
rabestro Aug 24, 2023
242d27e
Update Mazy Mice exercise description for clarity
rabestro Aug 24, 2023
86d5885
Revise maze details in Mazy Mice instructions
rabestro Aug 24, 2023
c04abac
Update exercises/practice/mazy-mice/.docs/instructions.md
rabestro Aug 25, 2023
1d8f6fc
Update exercises/practice/mazy-mice/.docs/instructions.md
rabestro Aug 25, 2023
79d0549
Update exercises/practice/mazy-mice/.docs/instructions.md
rabestro Aug 25, 2023
e1370fd
Update maze description in tutorial
rabestro Aug 26, 2023
0603ea5
Merge remote-tracking branch 'origin/maze-generator' into maze-generator
rabestro Aug 26, 2023
0a1fe42
Add sleep to ensure unique seed in mazy-mice test
rabestro Aug 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,14 @@
"practices": [],
"prerequisites": [],
"difficulty": 4
},
{
"slug": "mazy-mice",
"name": "Mazy Mice",
"uuid": "a1e388fe-9c4b-4a02-b922-423dce834cb0",
"practices": [],
"prerequisites": [],
"difficulty": 8
}
]
},
Expand Down
30 changes: 30 additions & 0 deletions exercises/practice/mazy-mice/.docs/hints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# placeholder
rabestro marked this conversation as resolved.
Show resolved Hide resolved

## General

- The `rand` [numeric function][rand-func] can generate random numbers.
- The `srand` [numeric function][srand-func] will be helpful to set the seed for `rand`.

## Maze generation

You can use any algorithm to generate a perfect maze. The [recursive backtracker][recursive-backtracker] is a good choice.

## Box drawing characters

| Character | Name | Unicode |
|:---------:|:--------------------------------------|:--------|
| ┌ | box drawings light down and right | U+250C |
| ─ | box drawings light horizontal | U+2500 |
| ┬ | box drawings light down and horizontal| U+252C |
| ┐ | box drawings light down and left | U+2510 |
| │ | box drawings light vertical | U+2502 |
| └ | box drawings light up and right | U+2514 |
| ┴ | box drawings light up and horizontal | U+2534 |
| ┘ | box drawings light up and left | U+2518 |
| ├ | box drawings light vertical and right | U+2520 |
| ⇨ | rightwards white arrow | U+21E8 |


[rand-func]: https://www.gnu.org/software/gawk/manual/html_node/Numeric-Functions.html#index-rand_0028_0029-function
[srand-func]: https://www.gnu.org/software/gawk/manual/html_node/Numeric-Functions.html#index-srand_0028_0029-function
[recursive-backtracker]: https://en.wikipedia.org/wiki/Maze_generation_algorithm
48 changes: 48 additions & 0 deletions exercises/practice/mazy-mice/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
## Instructions

Your task is to generate the perfect mazes for Mickey and Minerva — those with only one solution and no isolated sections.
Here's what you need to know:

- The maze has a rectangular shape with an opening at the start and end.
- The maze has rooms and passages, which intersect at right angles.
- The program should accept two parameters: rows and columns. The maze should be between 5 and 100 cells in size.
rabestro marked this conversation as resolved.
Show resolved Hide resolved
- A maze which is `x` columns wide and `y` rows high should be `2x + 1` characters wide and `2y + 1` characters high.
- If no seed is provided, generate a random maze. If the same seed is provided multiple times, the resulting maze should be the same each time.
- Use [box-drawing][Box-drawing] characters to draw walls, and an arrow symbol (⇨) for the entrance on the left and exit on the right.

It's time to create some perfect mazes for these adventurous mice!
IsaacG marked this conversation as resolved.
Show resolved Hide resolved

### Examples

1. The small square maze 5x5 cells (or 11x11 characters)
```text
┌───────┬─┐
│ │ │
│ ┌─┬── │ │
│ │ │ │ ⇨
│ │ │ ──┤ │
⇨ │ │ │ │
┌─┤ └── │ │
│ │ │ │
│ │ ────┘ │
│ │
└─────────┘
```
2. The rectangular maze 6x18 cells
```text
┌───────────┬─────────┬───────────┬─┐
│ │ │ │ │
│ ┌───────┐ │ ┌─┐ ──┐ └───┐ ┌───┐ │ │
│ │ │ │ │ │ │ │ │ │ ⇨
│ └─┐ ┌─┐ │ │ │ ├── ├───┐ │ │ ──┼── │
│ │ │ │ │ │ │ │ │ │ │ │
└── │ │ ├───┴───┤ ┌─┘ ┌─┘ │ ├── │ ──┤
⇨ │ │ │ │ │ │ │ │ │
┌─┬─┴─┐ └─┐ ┌─┐ │ └─┐ │ ┌─┘ │ ──┴─┐ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ └── │ │ │ └── │ ──┘ ┌─┘ ──┐ │ │
│ │ │ │ │ │ │
└───┴───────┴───────┴─────┴─────┴───┘
```

[Box-drawing]: https://en.wikipedia.org/wiki/Box-drawing_character
3 changes: 3 additions & 0 deletions exercises/practice/mazy-mice/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Introduction

Meet Mickey and Minerva, two clever mice who love to navigate their way through a maze to find cheese. They enjoy a good challenge, but with only their tiny mouse brains, they prefer if there is only one correct path to the cheese.
22 changes: 22 additions & 0 deletions exercises/practice/mazy-mice/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"authors": [
"rabestro"
],
"files": {
"solution": [
"mazy-mice.awk"
],
"test": [
"test-mazy-mice.bats"
],
"example": [
".meta/example.awk"
],
"editor": [
"test-maze.awk"
]
},
"blurb": "Meet Mickey and Minerva, two clever mice who love to navigate their way through a maze to find cheese. They enjoy a good challenge, but with only their tiny mouse brains, they prefer if there is only one correct path to the cheese.",
"source": "Inspired by the 'Maze Generator' created by Jan Boström at Alance AB.",
"source_url": "https://mazegenerator.net/"
}
66 changes: 66 additions & 0 deletions exercises/practice/mazy-mice/.meta/example.awk
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
BEGIN {
OFS = ""
Rows = Rows ? Rows : 8
Cols = Cols ? Cols : 16
Seed ? srand(Seed) : srand()

Width = 2 * Cols + 1
Height = 2 * Rows + 1

create_grid()
generate_maze(1, 1)
arrange_doors()
print_maze()
}

function create_grid( row, col) {
for (row = 0; row < Height; row++)
for (col = 0; col < Width; col++)
Grid[row, col] = 1
}
function print_maze( row, col) {
for (row = 0; row < Height; row++) {
for (col = 0; col < Width; col++)
$(col + 1) = symbol(row, col)
print
}
}

# Recursive backtracking algorithm
function generate_maze(row, col, directions,randDir,dx,dy,newRow,newCol) {
Grid[row, col] = 0

directions = "NESW"
while (length(directions) > 0) {
randDir = substr(directions, int(rand() * length(directions)) + 1, 1)
sub(randDir, "", directions)

dx = dy = 0
if (randDir == "N") dy = -2
if (randDir == "E") dx = 2
if (randDir == "S") dy = 2
if (randDir == "W") dx = -2
newRow = row + dy
newCol = col + dx

if (newRow > 0 && newRow < Height && newCol > 0 && newCol < Width && Grid[newRow, newCol]) {
Grid[row + dy / 2, col + dx / 2] = 0
generate_maze(newRow, newCol)
}
}
}
function arrange_doors() {
MazeEntrance = 1 + 2 * int(rand() * Rows)
MazeExit = 1 + 2 * int(rand() * Rows)
}
function symbol(row, col, n,e,s,w) {
if (!Grid[row, col]) return " "
if (is_door(row, col)) return "⇨"
n = row ? Grid[row - 1, col] : 0
e = col < Width - 1 ? Grid[row, col + 1] : 0
s = row < Height - 1 ? Grid[row + 1, col] : 0
w = col ? Grid[row, col - 1] : 0
return substr(" │─└││┌├─┘─┴┐┤┬┼", 1 + n + 2 * e + 4 * s + 8 * w, 1)
}

function is_door(row, col) {return row == MazeEntrance && col == 0 || row == MazeExit && col == Width - 1}