Last active
October 19, 2020 05:00
-
-
Save tani/5578f6e730144595de313c498786b15d 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
// 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