// Genera un laberinto, lo resuelve con BFS y con DFS, y lo dibuja.
// Uso: maze ancho alto semilla [paredes_extra]
#include <cstdlib>
#include <iostream>
#include <random>

#include "maze.h"
#include "solver.h"

int main(int argc, char* argv[]) {
    if (argc != 4 && argc != 5) {
        std::cerr << "uso: maze ancho alto semilla [paredes_extra]\n";
        return 1;
    }
    int width = std::atoi(argv[1]);
    int height = std::atoi(argv[2]);
    int extra = argc == 5 ? std::atoi(argv[4]) : 0;
    if (width <= 0 || height <= 0 || extra < 0) {
        std::cerr << "ancho y alto deben ser positivos, y paredes_extra no puede ser negativo\n";
        return 1;
    }
    std::mt19937 rng(static_cast<std::mt19937::result_type>(std::atoi(argv[3])));
    Maze maze(width, height);
    generate_maze(maze, rng);
    open_extra_walls(maze, extra, rng);
    Graph graph = maze_graph(maze);
    int source = 0;
    int target = maze.cell_count() - 1;
    SearchResult by_bfs = bfs_search(graph, source, target);
    SearchResult by_dfs = dfs_search(graph, source, target);
    std::cout << "BFS: camino de " << by_bfs.path.size() - 1 << " aristas, " << by_bfs.visited.size() << " nodos visitados\n";
    std::cout << maze.render(by_bfs.path, by_bfs.visited);
    std::cout << "DFS: camino de " << by_dfs.path.size() - 1 << " aristas, " << by_dfs.visited.size() << " nodos visitados\n";
    std::cout << maze.render(by_dfs.path, by_dfs.visited);
    return 0;
}
