Я написал реализацию алгоритма Прима, который создает лабиринт в QT (использовал C++, QGraphicView + QGraphicScene, мой лабиринт представляет собой матрицу 0 и 1), и следующим шагом моего проекта является - пользователь может щелкнуть любую ячейку лабиринта и выбрать начало и конец для алгоритмов поиска проходов.
У кого-нибудь есть идеи реализации установки позиций начала/финиша с помощью мыши?
мой код создания лабиринта -
#include "mazegenerator.h"
// лямда для пошуку та занесення крайових клітин в вектор borders
// лямда виконує такі дії:
// 1. Перевіряє чи координати точки не виходять за межі лабіринту
// 2. Перевіряє чи координати точки не є межами(кордонами) лабіринту
// 3. Перевіряє унікальність даної точки для уникнення повторного занесення
// 4. Якщо умови пройдені - додає координати точки до borders
auto isBorder = [this,&borders](int x,int y)
{
if(x+2 > 0 && x+2 < m_maze->getColumns()-1 && y > 0 && y < m_maze->getRows()-1 && m_maze->getValue(x+2,y) == 1)
{
// лямда для пошуку та занесення клітин-проходів в вектор borders
// лямда виконує такі дії:
// 1. Перевіряє чи координати точки не виходять за межі лабіринту
// 2. Якщо умови пройдені - додає координати точки до passes
auto isPass = [this,&passes](int x,int y)
{
if( x+2 < m_maze->getColumns() && y >=0 && y < m_maze->getRows() && m_maze->getValue(x+2,y) == 0)
{
passes.push_back({x+2,y});
}
if( x-2>=0 && x-2 < m_maze->getColumns() && y >=0 && y < m_maze->getRows() && m_maze->getValue(x-2,y) == 0)
{
passes.push_back({x-2,y});
}
if( x >= 0 && x < m_maze->getColumns() && y+2 < m_maze->getRows() && m_maze->getValue(x,y+2) == 0)
{
passes.push_back({x,y+2});
}
if( x >= 0 && x < m_maze->getColumns() && y-2 >=0 && y-2 < m_maze->getRows() && m_maze->getValue(x,y-2) == 0)
{
passes.push_back({x,y-2});
}
};
// 1.Генеруємо випадкову не парну клітинку і перетворюємо її на прохід
QRandomGenerator generator;
int x = generator.bounded(1,(m_maze->getColumns()-2) );
if(x % 2 == 0)
{
x -= 1;
}
int y = generator.bounded(1,(m_maze->getRows()-2) );
if(y % 2 == 0)
{
y -= 1;
}
m_maze->setValue(x,y,0);
emit cellChanged(x,y,0);
// 2. Шукаємо крайові клітинки і заносимо їх до вектора borders
isBorder(x,y);
while(borders.size() != 0)
{
int randBord = generator.bounded(0,static_cast(borders.size()));
int xBord = borders[randBord].first;
int yBord = borders[randBord].second;
borders.erase(borders.begin() + randBord);
m_maze->setValue(xBord,yBord,0);
emit cellChanged(xBord,yBord,0);
isBorder(xBord,yBord);
isPass(xBord,yBord);
bool ok = true;
if (!passes.empty())
{
while(ok)
{
int randPas = generator.bounded(0,static_cast(passes.size()) );
if( (passes[randPas].first + xBord)%2 == 0 && (passes[randPas].second + yBord)%2 == 0)
{
int betweenX = (passes[randPas].first + xBord)/2;
int betweenY = (passes[randPas].second + yBord)/2;
m_maze->setValue(betweenX,betweenY,0);
emit cellChanged(betweenX,betweenY,0);
ok = false;
break;
}
}
}
passes.clear();
}
}
функция инициализации и раскраски прямоугольника:
void Mazerenderer::mazeInitalization(int rows, int columns)
{
for(int y = 0; y < rows; y++)
{
for(int x = 0; x < columns; x++)
{
auto* item = m_scene->addRect(x * m_cellSize , y * m_cellSize, m_cellSize, m_cellSize, QPen(Qt::darkYellow), QBrush(wallColor));
rec_matrix[y][x] = item;
}
}
}
void Mazerenderer::changeCell(int x, int y, int signal)// responds to a signal from Mazegenerator::primsAlgorithm()
{
if(signal == 0)
{
rec_matrix[x][y]->setBrush(QBrush(passColor));
}
else if(signal == 2)
{
rec_matrix[x][y]->setBrush(QBrush(borderColor));
}
}
Я написал реализацию алгоритма Прима, который создает лабиринт в QT (использовал C++, QGraphicView + QGraphicScene, мой лабиринт представляет собой матрицу 0 и 1), и следующим шагом моего проекта является - пользователь может щелкнуть любую ячейку лабиринта и выбрать начало и конец для алгоритмов поиска проходов. [img]https://i.sstatic.net/3GUvMjcl.png[/img]
У кого-нибудь есть идеи реализации установки позиций начала/финиша с помощью мыши? мой код создания лабиринта - #include "mazegenerator.h"
// лямда для пошуку та занесення крайових клітин в вектор borders // лямда виконує такі дії: // 1. Перевіряє чи координати точки не виходять за межі лабіринту // 2. Перевіряє чи координати точки не є межами(кордонами) лабіринту // 3. Перевіряє унікальність даної точки для уникнення повторного занесення // 4. Якщо умови пройдені - додає координати точки до borders auto isBorder = [this,&borders](int x,int y) { if(x+2 > 0 && x+2 < m_maze->getColumns()-1 && y > 0 && y < m_maze->getRows()-1 && m_maze->getValue(x+2,y) == 1) {
// лямда для пошуку та занесення клітин-проходів в вектор borders // лямда виконує такі дії: // 1. Перевіряє чи координати точки не виходять за межі лабіринту // 2. Якщо умови пройдені - додає координати точки до passes
auto isPass = [this,&passes](int x,int y) { if( x+2 < m_maze->getColumns() && y >=0 && y < m_maze->getRows() && m_maze->getValue(x+2,y) == 0) { passes.push_back({x+2,y}); } if( x-2>=0 && x-2 < m_maze->getColumns() && y >=0 && y < m_maze->getRows() && m_maze->getValue(x-2,y) == 0) { passes.push_back({x-2,y}); } if( x >= 0 && x < m_maze->getColumns() && y+2 < m_maze->getRows() && m_maze->getValue(x,y+2) == 0) { passes.push_back({x,y+2}); } if( x >= 0 && x < m_maze->getColumns() && y-2 >=0 && y-2 < m_maze->getRows() && m_maze->getValue(x,y-2) == 0) { passes.push_back({x,y-2}); } };
// 1.Генеруємо випадкову не парну клітинку і перетворюємо її на прохід QRandomGenerator generator; int x = generator.bounded(1,(m_maze->getColumns()-2) ); if(x % 2 == 0) { x -= 1; } int y = generator.bounded(1,(m_maze->getRows()-2) ); if(y % 2 == 0) { y -= 1; } m_maze->setValue(x,y,0); emit cellChanged(x,y,0); // 2. Шукаємо крайові клітинки і заносимо їх до вектора borders isBorder(x,y);
while(borders.size() != 0) { int randBord = generator.bounded(0,static_cast(borders.size())); int xBord = borders[randBord].first; int yBord = borders[randBord].second; borders.erase(borders.begin() + randBord); m_maze->setValue(xBord,yBord,0); emit cellChanged(xBord,yBord,0); isBorder(xBord,yBord);
isPass(xBord,yBord);
bool ok = true; if (!passes.empty()) { while(ok) { int randPas = generator.bounded(0,static_cast(passes.size()) ); if( (passes[randPas].first + xBord)%2 == 0 && (passes[randPas].second + yBord)%2 == 0) { int betweenX = (passes[randPas].first + xBord)/2; int betweenY = (passes[randPas].second + yBord)/2;
m_maze->setValue(betweenX,betweenY,0); emit cellChanged(betweenX,betweenY,0); ok = false; break; }
} } passes.clear(); } }
[list] [*]функция инициализации и раскраски прямоугольника: [/list] void Mazerenderer::mazeInitalization(int rows, int columns) { for(int y = 0; y < rows; y++) { for(int x = 0; x < columns; x++) {
auto* item = m_scene->addRect(x * m_cellSize , y * m_cellSize, m_cellSize, m_cellSize, QPen(Qt::darkYellow), QBrush(wallColor)); rec_matrix[y][x] = item; } } } void Mazerenderer::changeCell(int x, int y, int signal)// responds to a signal from Mazegenerator::primsAlgorithm() { if(signal == 0) { rec_matrix[x][y]->setBrush(QBrush(passColor)); } else if(signal == 2) { rec_matrix[x][y]->setBrush(QBrush(borderColor)); } }