generateMaze
This commit is contained in:
+3
-1
@@ -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
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
#include <algorithm>
|
||||
#include <random>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
class Maze {
|
||||
private:
|
||||
int n_rows, n_cols;
|
||||
int real_rows, real_cols;
|
||||
std::vector<std::vector<int>> data;
|
||||
|
||||
const int EMPTY = 0;
|
||||
const int WALL = 1;
|
||||
|
||||
struct Cell {
|
||||
int r, c;
|
||||
};
|
||||
|
||||
bool isValid(int r, int c, const std::vector<std::vector<bool>>& visited) {
|
||||
return (r >= 0 && r < n_rows && c >= 0 && c < n_cols && !visited[r][c]);
|
||||
}
|
||||
|
||||
void generateMaze() {
|
||||
std::vector<std::vector<bool>> visited(n_rows, std::vector<bool>(n_cols, false));
|
||||
std::stack<Cell> 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<int> 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<int>(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] << " <filas> <columnas>\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;
|
||||
}
|
||||
Reference in New Issue
Block a user