Wie wähle ich per Mausklick eine Zelle aus einer QGraphicView aus und starte meinen Algorithmus von diesem Punkt aus?C++

Programme in C++. Entwicklerforum
Anonymous
 Wie wähle ich per Mausklick eine Zelle aus einer QGraphicView aus und starte meinen Algorithmus von diesem Punkt aus?

Post by Anonymous »

Ich habe eine Realisierung des Prim-Algorithmus geschrieben, der ein Labyrinth in QT erstellt (verwendet C++, QGraphicView + QGraphicScene, mein Labyrinth ist eine Matrix aus 0 und 1) und der nächste Schritt meines Projekts ist – der Benutzer kann auf eine beliebige Zelle des Labyrinths klicken und Start und Ende für die Suche nach Durchlaufalgorithmen wählen.
Image

Hat jemand Ideen für die Umsetzung des Festlegens von Start-/Endpositionen mit Hilfe einer Maus?
mein Labyrinth-Erstellungscode -

Code: Select all

#include "mazegenerator.h"

#include 
#include 

#include 
#include 
#include 
#include 

Mazegenerator::Mazegenerator(Maze *maze,QObject* parent):QObject(parent)
{
m_maze = maze;
}

void Mazegenerator::primsAlgorithm()
{
std::vector borders; // масив крайових клітин
std::vector passes;  // масив клітин-проходів

// лямда для пошуку та занесення крайових клітин в вектор 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)
{

bool alreadyExists = false;
for(int i = 0; i < borders.size(); i++)
{
if(borders[i].first == x+2 && borders[i].second == y)
{
alreadyExists = true;
break;
}
}

if(!alreadyExists)
{
borders.push_back({x+2,y});
emit cellChanged(x+2,y,2);
}

}
if(x-2 > 0 && x-2 < m_maze->getColumns()-1 && y >0 && y < m_maze->getRows()-1 && m_maze->getValue(x-2,y) == 1)
{

bool alreadyExists = false;
for(int i = 0; i < borders.size(); i++)
{
if(borders[i].first == x-2 && borders[i].second == y)
{
alreadyExists = true;
break;
}
}

if(!alreadyExists)
{
borders.push_back({x-2,y});
emit cellChanged(x-2,y,2);
}

}
if( x > 0 && x < m_maze->getColumns()-1 &&  y+2 > 0 && y+2 < m_maze->getRows()-1 && m_maze->getValue(x,y+2) == 1)
{

bool alreadyExists = false;
for(int i = 0; i < borders.size(); i++)
{
if(borders[i].first == x && borders[i].second == y+2)
{
alreadyExists = true;
break;
}
}

if(!alreadyExists)
{
borders.push_back({x,y+2});
emit cellChanged(x,y+2,2);
}

}

if(x > 0 && x < m_maze->getColumns()-1 && y-2 >0 && y-2 < m_maze->getRows()-1 && m_maze->getValue(x,y-2) == 1)
{
if(x == 0 || x == m_maze->getColumns() - 1 || y-2 == 0 || y-2 == m_maze->getRows() - 1)
{
// нічого не робимо — це край
}
else
{
bool alreadyExists = false;
for (int i = 0; i < borders.size(); i++)
{
if (borders[i].first == x && borders[i].second == y-2)
{
alreadyExists = true;
break;
}
}

if(!alreadyExists)
{
borders.push_back({x,y-2});
emit cellChanged(x,y-2,2);
}
}

}
};

// лямда для пошуку та занесення клітин-проходів в вектор 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();
}
}
  • Funktion der Rect-Initialisierung und -Färbung:

Code: Select all

    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));
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post