Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to change frames per second?



  • Hello,
    So, I am creating a maze generator/solver, how could I make, that my generator would work slowly.


  • Lifetime Qt Champion

    Hi,

    How are you making it work right now ?



  • So, I make QGraphicsScece and I draw inside scene squares (which are made from 4 walls(QGraphicsLineItem)), and then with Recursive backtracked algorithm, I generate maze.

    code:

    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        qsrand(QDateTime::currentMSecsSinceEpoch() / 1000);
    
        ui->setupUi(this);
    
        scene = new QGraphicsScene(this);
        ui->graphicsView->setScene(scene);
    
        int random_size = (qrand() % 30) + 5;
        maze_width = random_size;
        maze_height = random_size;
        square_size = 20;
        next_square_y = 0;
        next_square_x = 0;
    
        scene->setBackgroundBrush(Qt::white);
    
        QGraphicsRectItem *rect = new QGraphicsRectItem(0, 0, 200, 200);
    
        QPen no_border = QPen(Qt::NoPen);
        rect->setFlag(QGraphicsItem::ItemIsMovable);
        no_border.setWidth(5);
        rect->setPen(no_border);
        scene->addItem(rect);
    
        QPen wallPen = QPen(Qt::black);
        wallPen.setWidth(2);
    
        // walls will store square with 4 walls
    
        walls.resize(maze_width * maze_height);
        for (int y = 0; y < maze_height; y++){
            QVector < QGraphicsLineItem* > nothing;
            for (int x = 0; x < maze_width; x++){
                walls[y].push_back(nothing);
            }
        }
    
        // 0 walls are visited
        visited_walls.resize(maze_width * maze_height);
        for (int y = 0; y < maze_height; y++){
            for (int x = 0; x < maze_width; x++){
                visited_walls[y].push_back(0);
            }
        }
    
        current_square.resize(4);
    
        background_color_squares.resize(maze_width * maze_height);
        for (int y = 0; y < maze_height; y++){
            QGraphicsRectItem *nothing;
            for (int x = 0; x < maze_width; x++){
                background_color_squares[y].push_back(nothing);
            }
        }
    
    
    
        for (int y = 0; y < maze_height; y++ ){
            for (int x = 0; x < maze_width; x ++){
    
            QGraphicsRectItem *background_color_square = new QGraphicsRectItem(x * square_size, y * square_size, square_size, square_size, rect);
            background_color_square->setPen(no_border);
            background_color_squares[y][x] = background_color_square;
    
            // draw squares
    
            // top wall - 0
            QGraphicsLineItem *top_wall = new QGraphicsLineItem(x * square_size, y * square_size, (x * square_size) + square_size, y * square_size, rect);
            top_wall->setPen(wallPen);
            walls[y][x].push_back(top_wall);
    
            // left wall - 1
            QGraphicsLineItem *left_wall = new QGraphicsLineItem(x * square_size, y * square_size, x * square_size, (y * square_size) + square_size, rect);
            left_wall->setPen(wallPen);
            walls[y][x].push_back(left_wall);
    
            // right wall - 2
            QGraphicsLineItem *right_wall = new QGraphicsLineItem((x * square_size) + square_size, y * square_size, (x * square_size) + square_size, (y * square_size) + square_size, rect);
            right_wall->setPen(wallPen);
            walls[y][x].push_back(right_wall);
    
            // bottom wall - 3
            QGraphicsLineItem *bottom_wall = new QGraphicsLineItem(x * square_size, (y * square_size) + square_size, (x * square_size) + square_size, (y * square_size) + square_size, rect);
            bottom_wall->setPen(wallPen);
            walls[y][x].push_back(bottom_wall);
    
            }
        }
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    
    void MainWindow::on_pushButton_clicked()
    {
        generate_maze();
    }
    
    bool MainWindow::generate_maze()
    {
        QBrush background_white = QBrush(Qt::white);
    
        // first square is visited
        current_square = walls[0][0];
        visited_walls[0][0] = 1;
        background_color_squares[0][0]->setBrush(background_white);
        current_square[0]->setPen(Qt::NoPen);
        current_square_y = 0;
        current_square_x = 0;
    
        while (true){
            next_square = check_neighbours(next_square_y, next_square_x);
            while (next_square.size() == 0){
                memorize.pop_back();
                next_square_y = memorize[memorize.size() - 1].first;
                next_square_x = memorize[memorize.size() - 1].second;
                current_square_y = next_square_y;
                current_square_x = next_square_x;
                current_square = walls[current_square_y][current_square_x];
                next_square = check_neighbours(next_square_y, next_square_x); // it gives me next_square cordinates , bug!!!
                if (next_square.size() != 0){
                    break;
                }
            }
    
            visited_walls[next_square_y][next_square_x] = 1;
            QPair <int, int> memorized_cord = {next_square_y, next_square_x};
            memorize.push_back(memorized_cord);
    
            if (current_square_y - next_square_y == -1){
    
                current_square[3]->setPen(Qt::NoPen);
                next_square[0]->setPen(Qt::NoPen);
            }
    
            if (current_square_y - next_square_y == 1){
                current_square[0]->setPen(Qt::NoPen);
                next_square[3]->setPen(Qt::NoPen);
            }
    
            if (current_square_x - next_square_x == -1){
                current_square[2]->setPen(Qt::NoPen);
                next_square[1]->setPen(Qt::NoPen);
            }
    
            if (current_square_x - next_square_x == 1){
                current_square[1]->setPen(Qt::NoPen);
                next_square[2]->setPen(Qt::NoPen);
            }
    
            current_square = next_square;
            current_square_y = next_square_y;
            current_square_x = next_square_x;
            background_color_squares[next_square_y][next_square_x]->setBrush(background_white);
    
            if (!unvisited_squares()){
                break;
            }
        }
        return true;
    }
    
    bool MainWindow::unvisited_squares()
    {
        for (int y = 0; y < visited_walls.size(); y++){
            for (int x = 0; x < visited_walls[y].size(); x++){
                if (visited_walls[y][x] == 0){
                    return true;
                }
            }
        }
        return false;
    }
    
    QVector < QGraphicsLineItem* > MainWindow::check_neighbours(int y, int x)
    {
        QVector < QPair <int, int > > available_neighbours;
    
        // left neighbour
        if (x != 0){
            if (visited_walls[y][x - 1] != 1){
                QPair <int, int> neighbour = {y, x - 1};
                available_neighbours.push_back(neighbour);
            }
        }
        // right neighbour
        if (x != maze_width - 1){
            if (visited_walls[y][x + 1] != 1){
                QPair <int, int> neighbour = {y, x + 1};
                available_neighbours.push_back(neighbour);
            }
        }
        // above neighbour
        if (y != 0){
            if (visited_walls[y - 1][x] != 1){
                QPair <int, int> neighbour = {y - 1, x};
                available_neighbours.push_back(neighbour);
            }
        }
        // under
        if (y != maze_height - 1){
            if (visited_walls[y + 1][x] != 1){
                QPair <int, int> neighbour = {y + 1, x};
                available_neighbours.push_back(neighbour);
            }
        }
    
    
        if (available_neighbours.size() > 0){
            int random = (qrand() % available_neighbours.size());
            QPair <int, int> chosen_neighbour = available_neighbours[random];
            next_square_y = chosen_neighbour.first;
            next_square_x = chosen_neighbour.second;
            return walls[next_square_y][next_square_x];
        }
        return {};
    }
    
    

  • Lifetime Qt Champion

    Then take out the logic from the loop in its own function and then use a QTimer to trigger that method at the desired interval.



  • Maybe someone could show me how to do that? I can't figure out how to do that:/



  • Solved:)

    // ........
    
     // first square is visited
        current_square = walls[0][0];
        visited_walls[0][0] = 1;
        current_square_y = 0;
        current_square_x = 0;
    
        timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(MySlot()));
    
    }
    
    void MainWindow::on_pushButton_clicked()
    {
        timer->start(100);
    }
    
    void MainWindow::MySlot()
    {
        current_square[0]->setPen(Qt::NoPen);
        QBrush background_color = QBrush(QColor(28, 37, 65));
        background_color_squares[next_square_y][next_square_x]->setBrush(background_color);
        background_color_squares[0][0]->setBrush(QColor(68, 102, 30));
    
        next_square = check_neighbours(next_square_y, next_square_x);
        while (next_square.size() == 0){
            memorize.pop_back();
            next_square_y = memorize[memorize.size() - 1].first;
            next_square_x = memorize[memorize.size() - 1].second;
            current_square_y = next_square_y;
            current_square_x = next_square_x;
            current_square = walls[current_square_y][current_square_x];
            next_square = check_neighbours(next_square_y, next_square_x);
            if (next_square.size() != 0){
                break;
            }
        }
        background_color_squares[next_square_y][next_square_x]->setBrush(Qt::red);
    
        visited_walls[next_square_y][next_square_x] = 1;
    
        QPair <int, int> memorized_cord = {next_square_y, next_square_x};
        memorize.push_back(memorized_cord);
    
        if (current_square_y - next_square_y == -1){
    
            current_square[3]->setPen(Qt::NoPen);
            next_square[0]->setPen(Qt::NoPen);
        }
    
        if (current_square_y - next_square_y == 1){
            current_square[0]->setPen(Qt::NoPen);
            next_square[3]->setPen(Qt::NoPen);
        }
    
        if (current_square_x - next_square_x == -1){
            current_square[2]->setPen(Qt::NoPen);
            next_square[1]->setPen(Qt::NoPen);
        }
    
        if (current_square_x - next_square_x == 1){
            current_square[1]->setPen(Qt::NoPen);
            next_square[2]->setPen(Qt::NoPen);
        }
    
        current_square = next_square;
        current_square_y = next_square_y;
        current_square_x = next_square_x;
    
        if (!unvisited_squares()){
            background_color_squares[next_square_y][next_square_x]->setBrush(background_color);
            background_color_squares[maze_height - 1][maze_width - 1]->setBrush(QColor(48, 12, 97));
            walls[maze_height - 1][maze_width - 1][3]->setPen(Qt::NoPen);
            timer->stop();
        }
    
    
    }
    // ......
    

  • Lifetime Qt Champion

    Good !

    Since you have it working now please mark the thread as solved using the "Topic Tools" button or the three doted menu beside the answer you deem correct so that other forum users may know a solution has been found :-)


Log in to reply