diff options
author | Juan Manuel Tomás <jtomas1815@gmail.com> | 2018-09-12 15:13:40 -0300 |
---|---|---|
committer | Juan Manuel Tomás <jtomas1815@gmail.com> | 2018-09-12 15:13:40 -0300 |
commit | afcc1fd6b076abe34bb35503a7caf32be566482b (patch) | |
tree | cc2c7b63be6514103f7a34e6c6a69a5cd6a8db1d /maze.c | |
download | maze-master.tar.gz maze-master.zip |
Diffstat (limited to 'maze.c')
-rwxr-xr-x | maze.c | 146 |
1 files changed, 146 insertions, 0 deletions
@@ -0,0 +1,146 @@ +#define SDL_DISABLE_IMMINTRIN_H +#include <stdlib.h> +#include <time.h> +#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; +} |