Skip to content

Instantly share code, notes, and snippets.

@tani
Last active October 19, 2020 05:00
Show Gist options
  • Save tani/5578f6e730144595de313c498786b15d to your computer and use it in GitHub Desktop.
Save tani/5578f6e730144595de313c498786b15d to your computer and use it in GitHub Desktop.
// clang++ -std=c++17 -lncurses -o maze maze.cpp
#include<array>
#include<cstdio>
#include<cstdint>
#include<ctime>
#include<cstdlib>
#include<ncurses.h>
enum State {
WALL,
LOAD,
PLAYER
};
template<size_t WIDTH, size_t HEIGHT>
auto generate() {
static_assert(WIDTH % 2 == 1, "Width must be odd number.");
static_assert(HEIGHT % 2 == 1, "Height must be odd number.");
std::array<std::array<State, WIDTH>, HEIGHT> map{};
for(int y = 0; y < map.size(); y++) {
for(int x = 0; x < map.at(y).size(); x++) {
map.at(y).at(x) = ((x % 2 == 1) || (y % 2 == 1)) ? LOAD : WALL;
}
}
map.at(1).at(1) = PLAYER;
for(int y = 0; y < map.size(); y++) {
map.at(y).at(0) = WALL;
map.at(y).at(WIDTH - 1) = WALL;
}
for(int x = 0; x < map.at(0).size(); x++) {
map.at(0).at(x) = WALL;
map.at(HEIGHT - 1).at(x) = WALL;
}
for(int y = 2; y <= map.size() - 2; y += 2) {
for(int x = 2; x <= map.at(y).size() - 2; x += 2) {
const std::array<std::array<int, 2>, 4> t = {{{x+1, y}, {x-1, y}, {x, y+1}, {x, y-1}}};
while(true){
const auto [u, v] = t.at(rand() % (y == 2 ? 4 : 3));
if(map.at(v).at(u)) {
map.at(v).at(u) = WALL;
break;
}
}
}
}
return map;
}
const auto walk = [](auto& map, int dx, int dy) {
for(int y = 0; y < map.size(); y++) {
for(int x = 0; x < map.at(y).size(); x++) {
if(map.at(y).at(x) == PLAYER) {
if(map.at(y+dy).at(x+dx) == LOAD) {
map.at(y).at(x) = LOAD;
map.at(y+dy).at(x+dx) = PLAYER;
return;
}
}
}
}
};
const auto draw = [](const auto& map) {
for(int y = 0; y < map.size(); y++) {
for(int x = 0; x < map.at(y).size(); x++) {
switch(map.at(y).at(x)){
case WALL:
mvaddch(y, x, 'x');
break;
case PLAYER:
mvaddch(y, x, 'o');
break;
case LOAD:
mvaddch(y, x, ' ');
break;
}
}
}
};
int main(int argc, char** argv) {
initscr();
start_color();
cbreak();
noecho();
std::srand(std::time(NULL));
auto map = generate<21, 21>();
while(true) {
draw(map);
const char c = getch();
switch(c) {
case 'h': walk(map, -1, 0); continue;
case 'j': walk(map, 0, 1); continue;
case 'k': walk(map, 0, -1); continue;
case 'l': walk(map, 1, 0); continue;
case 'q': break;
default: continue;
}
break;
}
endwin();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment