diff --git a/.gitignore b/.gitignore index 7014d68..7731956 100644 --- a/.gitignore +++ b/.gitignore @@ -31,7 +31,8 @@ $RECYCLE.BIN/ .LSOverride # Icon must end with two \r -Icon +Icon + # Thumbnails ._* @@ -67,3 +68,4 @@ Temporary Items # .nfs files are created when an open file is removed but is still being accessed .nfs* +laberinto_sdl3 diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..6a3c866 --- /dev/null +++ b/main.cpp @@ -0,0 +1,185 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +class Maze { +private: + int n_rows, n_cols; + int real_rows, real_cols; + std::vector> data; + + const int EMPTY = 0; + const int WALL = 1; + + struct Cell { + int r, c; + }; + + bool isValid(int r, int c, const std::vector>& visited) { + return (r >= 0 && r < n_rows && c >= 0 && c < n_cols && !visited[r][c]); + } + + void generateMaze() { + std::vector> visited(n_rows, std::vector(n_cols, false)); + std::stack cellStack; + + int dr[] = {-1, 1, 0, 0}; + int dc[] = {0, 0, -1, 1}; + + unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); + std::default_random_engine engine(seed); + + Cell current = {0, 0}; + visited[current.r][current.c] = true; + data[1][1] = EMPTY; + + cellStack.push(current); + + while (!cellStack.empty()) { + current = cellStack.top(); + std::vector neighbors; + + for (int i = 0; i < 4; ++i) { + if (isValid(current.r + dr[i], current.c + dc[i], visited)) { + neighbors.push_back(i); + } + } + + if (!neighbors.empty()) { + std::shuffle(neighbors.begin(), neighbors.end(), engine); + int dirIndex = neighbors[0]; + + int next_r = current.r + dr[dirIndex]; + int next_c = current.c + dc[dirIndex]; + + int current_real_r = current.r * 2 + 1; + int current_real_c = current.c * 2 + 1; + int next_real_r = next_r * 2 + 1; + int next_real_c = next_c * 2 + 1; + + int wall_r = current_real_r + dr[dirIndex]; + int wall_c = current_real_c + dc[dirIndex]; + + data[wall_r][wall_c] = EMPTY; + data[next_real_r][next_real_c] = EMPTY; + + visited[next_r][next_c] = true; + cellStack.push({next_r, next_c}); + } else { + cellStack.pop(); + } + } + + // Perforar entrada y salida + data[1][0] = EMPTY; + data[real_rows - 2][real_cols - 1] = EMPTY; + } + +public: + Maze(int r, int c) : n_rows(r), n_cols(c) { + real_rows = 2 * n_rows + 1; + real_cols = 2 * n_cols + 1; + data.assign(real_rows, std::vector(real_cols, WALL)); + generateMaze(); + } + + int getRealRows() const { return real_rows; } + int getRealCols() const { return real_cols; } + int getValue(int r, int c) const { return data[r][c]; } +}; + +int main(int argc, char* argv[]) { + if (argc != 3) { + std::cerr << "Uso: " << argv[0] << " \n"; + return 1; + } + + int filas = std::stoi(argv[1]); + int columnas = std::stoi(argv[2]); + + if (filas <= 0 || columnas <= 0) { + std::cerr << "Error: Las dimensiones deben ser mayores que cero.\n"; + return 1; + } + + // Generar el laberinto + Maze maze(filas, columnas); + + // Configuración de píxeles por celda + const float CELL_SIZE = 16.0f; + int window_width = maze.getRealCols() * CELL_SIZE; + int window_height = maze.getRealRows() * CELL_SIZE; + + // Inicializar SDL3 + if (!SDL_Init(SDL_INIT_VIDEO)) { + std::cerr << "Error al inicializar SDL3: " << SDL_GetError() << "\n"; + return 1; + } + + // Crear ventana y renderer con la API moderna de SDL3 + SDL_Window* window = nullptr; + SDL_Renderer* renderer = nullptr; + + if (!SDL_CreateWindowAndRenderer("Generador de Laberintos (SDL3)", window_width, window_height, 0, &window, &renderer)) { + std::cerr << "Error al crear la ventana/renderer: " << SDL_GetError() << "\n"; + SDL_Quit(); + return 1; + } + + bool running = true; + SDL_Event event; + + // Bucle principal de renderizado + while (running) { + // Manejo de eventos (cerrar ventana o pulsar ESC) + while (SDL_PollEvent(&event)) { + if (event.type == SDL_EVENT_QUIT) { + running = false; + } else if (event.type == SDL_EVENT_KEY_DOWN) { + if (event.key.key == SDLK_ESCAPE) { + running = false; + } + } + } + + // Limpiar pantalla en negro (los pasillos y fondo) + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + + // Dibujar los muros + // El color gris oscuro/azul destaca muy bien para los muros + SDL_SetRenderDrawColor(renderer, 40, 50, 70, 255); + + for (int i = 0; i < maze.getRealRows(); ++i) { + for (int j = 0; j < maze.getRealCols(); ++j) { + if (maze.getValue(i, j) == 1) { // Si es un muro (WALL) + SDL_FRect rect; + rect.x = j * CELL_SIZE; + rect.y = i * CELL_SIZE; + rect.w = CELL_SIZE; + rect.h = CELL_SIZE; + + SDL_RenderFillRect(renderer, &rect); + } + } + } + + // Presentar el frame en pantalla + SDL_RenderPresent(renderer); + + // Pequeño delay para no saturar la CPU a miles de FPS innecesariamente + SDL_Delay(16); + } + + // Limpieza final de recursos + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} \ No newline at end of file