#include<iostream> #include<cstdlib> #include<vector> #include<ctime> #include "Maze.h" #include "Polzunok.h" Maze::Maze(int heigth, int width) { this->height = heigth; this->width = width; for (int i = 0; i < height; i++) { vector<int> line; for (int j = 0; j < width; j++) line.push_back(WALL); maze.push_back(line); } maze_make(); } void Maze::maze_make() { int x, y, c, a; bool b; for (int i = 0; i < height; i++) // Массив заполняется землей-ноликами for (int j = 0; j < width; j++) maze[i][j] = WALL; x = 3; y = 3; a = 0; // Точка приземления крота и счетчик while (a < height * width * 100) { // Да, простите, костыль, иначе есть как, но лень maze[y][x] = PASS; a++; while (1) { // Бесконечный цикл, который прерывается только тупиком c = rand() % 4; // Напоминаю, что крот прорывает switch (c) { // по две клетки в одном направлении за прыжок case 0: if (y != 1) if (maze[y - 2][x] == WALL) { // Вверх maze[y - 1][x] = PASS; maze[y - 2][x] = PASS; y -= 2; } case 1: if (y != height - 2) if (maze[y + 2][x] == WALL) { // Вниз maze[y + 1][x] = PASS; maze[y + 2][x] = PASS; y += 2; } case 2: if (x != 1) if (maze[y][x - 2] == WALL) { // Налево maze[y][x - 1] = PASS; maze[y][x - 2] = PASS; x -= 2; } case 3: if (x != width - 2) if (maze[y][x + 2] == WALL) { // Направо maze[y][x + 1] = PASS; maze[y][x + 2] = PASS; x += 2; } } if (deadend(x, y)) break; } if (deadend(x, y)) // Вытаскиваем крота из тупика do { x = 2 * (rand() % ((width - 1) / 2)) + 1; y = 2 * (rand() % ((height - 1) / 2)) + 1; } while (maze[y][x] != PASS); } // На этом и все. } void Maze::markup_wave_algoritm() { pos finish_pos = pos(maze.size() - 2, maze[0].size() - 2); bool is_finished = false; vector<pos> polzuns_pos = { pos(1, 1) }; maze[1][1] = 1; vector< vector<int> > markup = maze; int currstep = 2; while (polzuns_pos.size() != 0) { vector<pos> new_polzuns_pos; for (int i = 0; i < polzuns_pos.size(); i++) { pos check_position = polzuns_pos[i]; if (check_position.i == finish_pos.i && check_position.j == finish_pos.j) is_finished = true; } if (is_finished) break; for (int i = 0; i < polzuns_pos.size(); i++) { pos curr_pos = polzuns_pos[i]; Polzunok polzune = Polzunok(&markup, curr_pos.i, curr_pos.j, currstep); if (polzune.try_move(-1, 0)) { new_polzuns_pos.push_back(pos(curr_pos.i - 1, curr_pos.j)); } if (polzune.try_move(1, 0)) { new_polzuns_pos.push_back(pos(curr_pos.i + 1, curr_pos.j)); } if (polzune.try_move(0, -1)) { new_polzuns_pos.push_back(pos(curr_pos.i, curr_pos.j - 1)); } if (polzune.try_move(0, 1)) { new_polzuns_pos.push_back(pos(curr_pos.i, curr_pos.j + 1)); } } polzuns_pos = new_polzuns_pos; currstep++; } // строим путь обратно way.push_back(finish_pos); currstep = markup[finish_pos.i][finish_pos.j] - 1; pos curr_pos = finish_pos; while (1) { if (markup[curr_pos.i][curr_pos.j] == 1) { way.push_back(curr_pos); break; } // look up if (is_out(curr_pos.i - 1, curr_pos.j) == false && markup[curr_pos.i 1][curr_pos.j] == currstep) { curr_pos.i -= 1; way.push_back(curr_pos); } // look down else if (is_out(curr_pos.i + 1, curr_pos.j) == false && markup[curr_pos.i + 1][curr_pos.j] == currstep) { curr_pos.i += 1; way.push_back(curr_pos); } // look left else if (is_out(curr_pos.i, curr_pos.j - 1) == false && markup[curr_pos.i][curr_pos.j - 1] == currstep) { curr_pos.j -= 1; way.push_back(curr_pos); } // look right else if (is_out(curr_pos.i, curr_pos.j + 1) == false && markup[curr_pos.i][curr_pos.j + 1] == currstep) { curr_pos.j += 1; way.push_back(curr_pos); } currstep--; } for (auto p : way) { maze[p.i][p.j] = WAY; } } bool Maze::is_out(int i, int j) { if (i < 0 || i >= maze.size()) return true; if (j < 0 || j >= maze[0].size()) return true; return false; } bool Maze::deadend(int x, int y) { int a = 0; if (x != 1) { if (maze[y][x - 2] == PASS) a += 1; } else a += 1; if (y != 1) { if (maze[y - 2][x] == PASS) a += 1; } else a += 1; if (x != width - 2) { if (maze[y][x + 2] == PASS) a += 1; } else a += 1; if (y != height - 2) { if (maze[y + 2][x] == PASS) a += 1; } else a += 1; if (a == 4) return 1; else return 0; } //void // // // // // // // // // //} visual(int** maze, int height, int width) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) switch (maze[i][j]) { case WALL: cout << "# "; break; case PASS: cout << " "; break; } cout << endl; } cout << endl;