Created
March 14, 2018 17:58
-
-
Save shiracamus/a1ccb7f0f4f0c1a9694dbc78b86ed7ff to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include <cstdlib> | |
#include <ctime> | |
#include <iostream> | |
#include <random> | |
#include <vector> | |
class Maze { | |
int start_x, | |
start_y; | |
int last_x, | |
last_y; | |
const char WALL = '+', | |
ROAD = ' ', | |
START = 'S', | |
END = 'E'; | |
std::vector<std::vector<char>> map; | |
std::random_device rnd; | |
bool digable(int x, int y) { | |
return (y - 2 > 0 && map[y - 2][x] == WALL) | |
|| (y + 2 < map.size() && map[y + 2][x] == WALL) | |
|| (x - 2 > 0 && map[y][x - 2] == WALL) | |
|| (x + 2 < map[y].size() && map[y][x + 2] == WALL); | |
} | |
void dig_up(int x, int y) { | |
if (y - 2 > 0 && map[y - 2][x] == WALL) { | |
map[y - 1][x] = ROAD; | |
dig(x, y - 2); | |
} | |
} | |
void dig_down(int x, int y) { | |
if (y + 2 < map.size() && map[y + 2][x] == WALL) { | |
map[y + 1][x] = ROAD; | |
dig(x, y + 2); | |
} | |
} | |
void dig_left(int x, int y) { | |
if (x - 2 > 0 && map[y][x - 2] == WALL) { | |
map[y][x - 1] = ROAD; | |
dig(x - 2, y); | |
} | |
} | |
void dig_right(int x, int y) { | |
if (x + 2 < map[y].size() && map[y][x + 2] == WALL) { | |
map[y][x + 1] = ROAD; | |
dig(x + 2, y); | |
} | |
} | |
using digger = void (Maze::*)(int width, int height); | |
void dig(int x, int y) { | |
const digger digger[] = { | |
&Maze::dig_up, &Maze::dig_down, &Maze::dig_left, &Maze::dig_right, | |
}; | |
const int num_digger = sizeof(digger) / sizeof(digger[0]); | |
last_x = x; | |
last_y = y; | |
map[y][x] = ROAD; | |
while (digable(x, y)) { | |
(this->*digger[rnd() % num_digger])(x, y); | |
} | |
} | |
void fill_wall(int width, int height) { | |
map.resize(height); | |
for (int y = 0; y < map.size(); y++) { | |
map[y].resize(width); | |
for (int x = 0; x < map[y].size(); x++) { | |
map[y][x] = WALL; | |
} | |
} | |
} | |
public: | |
void make(int width, int height) { | |
start_x = (rnd() % ((width - 1) / 2)) * 2 + 1; | |
start_y = (rnd() % ((height - 1) / 2)) * 2 + 1; | |
fill_wall(width, height); | |
dig(start_x, start_y); | |
map[start_y][start_x] = START; | |
map[last_y][last_x] = END; | |
} | |
void print() { | |
for (int y = 0; y < map.size(); y++) { | |
for (int x = 0; x < map[y].size(); x++) { | |
std::cout << map[y][x]; | |
} | |
std::cout << "\n"; | |
} | |
} | |
}; | |
int main(int argc, char **args) { | |
int width, height; | |
if (argc < 3) { | |
std::cout << "width? "; | |
std::cin >> width; | |
std::cout << "height? "; | |
std::cin >> height; | |
} else { | |
width = atoi(args[1]); | |
height = atoi(args[2]); | |
} | |
Maze maze; | |
maze.make(width | 1, height | 1); | |
maze.print(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment