#define SDL_DISABLE_IMMINTRIN_H #include #include #include "SDL2/SDL.h" int mazeWidth = 50; int mazeHeight = 50; typedef struct cell { int x, y; char walls; struct cell *parent; } Cell; int min(int a, int b) { return a < b ? a : b; } int max(int a, int b) { return a > b ? a : b; } int pos(int x, int y) { x = min(mazeWidth - 1, max(0, x)); y = min(mazeHeight - 1, max(0, y)); return x + y * mazeWidth; } void drawCell(SDL_Renderer *r, Cell n, int cell, int wall, char red, char green, char blue) { SDL_SetRenderDrawColor(r, red, green, blue, 255); SDL_Rect rect; rect.x = n.x * cell + (n.x + 1) * wall; rect.y = n.y * cell + (n.y + 1) * wall; rect.w = cell; rect.h = cell; SDL_RenderFillRect(r, &rect); int x = n.x * (wall + cell); int y = n.y * (wall + cell); if (~n.walls & 1) { rect.x = x; rect.y = wall + y; rect.w = wall; rect.h = cell; SDL_RenderFillRect(r, &rect); } if (~n.walls & 4) { rect.x = wall + x; rect.y = y; rect.w = cell; rect.h = wall; SDL_RenderFillRect(r, &rect); } } void reset(Cell *maze) { for (int i = 0; i < mazeWidth * mazeHeight; i++) { maze[i].walls = 15; maze[i].parent = 0; } } int main(int argc, char**argv) { srand(time(0)); if (argc >= 3) { mazeWidth = atoi(argv[1]); mazeHeight = atoi(argv[2]); } int cellSize = 16; int wallSize = 4; SDL_Init(SDL_INIT_VIDEO); SDL_Window *w = 0; SDL_Renderer *r = 0; SDL_CreateWindowAndRenderer(0, 0, SDL_WINDOW_RESIZABLE, &w, &r); SDL_RenderSetLogicalSize(r, mazeWidth * (cellSize + wallSize) + wallSize, mazeHeight * (cellSize + wallSize) + wallSize); Cell maze[mazeWidth * mazeHeight]; for (int x = 0; x < mazeWidth; x++) for (int y = 0; y < mazeHeight; y++) { maze[pos(x, y)].x = x; maze[pos(x, y)].y = y; } reset(maze); Cell *curr = &maze[pos(rand() % mazeWidth, rand() % mazeHeight)]; curr->parent = curr; SDL_Event e; while (e.type != SDL_QUIT) { while (SDL_PollEvent(&e)) { if (e.key.type == SDL_KEYDOWN) switch (e.key.keysym.sym) { case SDLK_RETURN: reset(maze); curr = &maze[pos(rand() % mazeWidth, rand() % mazeHeight)]; break; case SDLK_UP: if (cellSize + 1 < 20) { cellSize ++; wallSize --; } SDL_RenderSetLogicalSize(r, mazeWidth * (cellSize + wallSize) + wallSize, mazeHeight * (cellSize + wallSize) + wallSize); break; case SDLK_DOWN: if (cellSize - 1 > 1) { cellSize --; wallSize ++; } SDL_RenderSetLogicalSize(r, mazeWidth * (cellSize + wallSize) + wallSize, mazeHeight * (cellSize + wallSize) + wallSize); } } SDL_SetRenderDrawColor(r, 80, 80, 80, 255); SDL_RenderClear(r); for (int i = 0; i < mazeWidth * mazeHeight; i++) { if (maze[i].parent) drawCell(r, maze[i], cellSize, wallSize, 255, 255, 255); } drawCell(r, *curr, cellSize, wallSize, 0, 255, 0); // not all neighbors have parent if (!maze[pos(curr->x + 1, curr->y)].parent || !maze[pos(curr->x - 1, curr->y)].parent || !maze[pos(curr->x, curr->y + 1)].parent || !maze[pos(curr->x, curr->y - 1)].parent) { Cell *neighbor = curr; char dir = 0; char rdir = 0; while (neighbor->parent) { dir = 1 << rand() % 4; int x = curr->x; int y = curr->y; switch (dir) { case 1: x--; rdir = 2; break; case 2: x++; rdir = 1; break; case 4: y--; rdir = 8; break; case 8: y++; rdir = 4; break; } if (!maze[pos(x, y)].parent) neighbor = &maze[pos(x, y)]; } curr->walls &= ~dir; neighbor->walls &= ~rdir; neighbor->parent = curr; curr = neighbor; } else if (curr->parent != curr) { // curr isn't the starting cell curr = curr->parent; } SDL_RenderPresent(r); SDL_Delay(10); } SDL_DestroyWindow(w); SDL_DestroyRenderer(r); SDL_Quit(); return 0; }