Qt应用程序在后端崩溃

时间:2016-04-06 22:26:23

标签: c++ qt user-interface

所以我只是制作一个所谓的简单程序来开始使用Qt。我从之前的一些练习中预先制作了2048年的后端,并且它本身运行得很好。无论方向如何,程序都会在if(!t->sameAs(board[t->pos-dimen]) && board[t->pos-dimen]->value != 0){或类似的can*Direction*()函数行崩溃。此外,程序不会抛出有用的错误。需要改变什么,或者后端需要如何实施呢?

的main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    game* g = new game();

    g->printBoard();

    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QKeyEvent>
#include "game.h"


namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void keyPressEvent(QKeyEvent *);

private:
    Ui::MainWindow *ui;
    game* g;
    void updateLCD();
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    update();
}

MainWindow::~MainWindow()
{
    delete g;
    delete ui;
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Up)
    {
        g->moveUp();
        updateLCD();
    }
    if(event->key() == Qt::Key_Down)
    {
        g->moveDown();
        updateLCD();
    }
    if(event->key() == Qt::Key_Left)
    {
        g->moveLeft();
        updateLCD();
    }
    if(event->key() == Qt::Key_Right)
    {
        g->moveRight();
        updateLCD();
    }
}

void MainWindow::updateLCD(){
    ui->LCD00->display(g->getTile(0));
    ui->LCD10->display(g->getTile(1));
    ui->LCD20->display(g->getTile(2));
    ui->LCD30->display(g->getTile(3));
    ui->LCD01->display(g->getTile(4));
    ui->LCD11->display(g->getTile(5));
    ui->LCD21->display(g->getTile(6));
    ui->LCD31->display(g->getTile(7));
    ui->LCD02->display(g->getTile(8));
    ui->LCD12->display(g->getTile(9));
    ui->LCD22->display(g->getTile(10));
    ui->LCD32->display(g->getTile(11));
    ui->LCD30->display(g->getTile(12));
    ui->LCD31->display(g->getTile(13));
    ui->LCD32->display(g->getTile(14));
    ui->LCD33->display(g->getTile(15));
}

game.h

#ifndef game_hpp
#define game_hpp

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

class game{

private:
    const static int TOTALTILES = 16;

    struct tile{
        int pos;
        bool hasVal = false;
        int value = 0;
        int dimen;
        bool sameAs(tile* t){ return t->value == value; }
    };

    tile* board[TOTALTILES];

    bool allLeft();
    bool allRight();
    bool allUp();
    bool allDown();
    void generate();

    bool canUp(tile*);
    bool canLeft(tile*);
    bool canRight(tile*);
    bool canDown(tile*);

    void moveTileUp(tile*);
    void moveTileDown(tile*);
    void moveTileLeft(tile*);
    void moveTileRight(tile*);

    int dimen;

public:
    game();
    void moveUp();
    void moveDown();
    void moveLeft();
    void moveRight();
    void printBoard();

    int getTile(int i);
};

#endif /* game_hpp */

game.cpp

#include <iostream>
#include "game.h"

game::game(){
    dimen = log2(TOTALTILES);

    srand(time(NULL));

    for(int i = 0; i < TOTALTILES; i++){
        board[i] = new tile();
        board[i]->pos = i;
        board[i]->dimen = dimen;
    }
    generate();
    generate();
}

void game::moveUp(){
    if(!allUp()){
        while(!allUp()){
            for(int i = 0; i < TOTALTILES; i++){
                moveTileUp(board[i]);
            }
        }
        generate();
    }
}

void game::moveDown(){
    if(!allDown()){

        while(!allDown()){
            for(int i = TOTALTILES - 1; i >= 0; i--){
                moveTileDown(board[i]);
            }
        }
        generate();
    }
}

void game::moveLeft(){
    if(!allLeft()){
        while(!allLeft()){
            for(int i = 0; i < TOTALTILES; i++){
                moveTileLeft(board[i]);
            }
        }
        generate();
    }
}

void game::moveRight(){
    if(!allRight()){
        while(!allRight()){
            for(int i = 0; i < TOTALTILES; i++){
                moveTileRight(board[i]);
            }
        }
        generate();
    }
}

void game::moveTileUp(tile* t){
    if(canUp(t)){
        tile* other = board[t->pos-dimen];
        if(t->sameAs(other)){
            other->value++;
            t->value = 0;
        } else {
            other->value = t->value;
            t->value = 0;
        }
    }
}

void game::moveTileDown(tile* t){
    if(canDown(t)){
        tile* other = board[t->pos+dimen];
        if(t->sameAs(other)){
            other->value++;
            t->value = 0;
        } else {
            other->value = t->value;
            t->value = 0;
        }
    }
}

void game::moveTileLeft(tile* t){
    if(canLeft(t)){
        tile* other = board[t->pos-1];
        if(t->sameAs(other)){
            other->value++;
            t->value = 0;
        } else {
            other->value = t->value;
            t->value = 0;
        }
    }
}

void game::moveTileRight(tile* t){
    if(canRight(t)){
        tile* other = board[t->pos+1];
        if(t->sameAs(other)){
            other->value++;
            t->value = 0;
        } else {
            other->value = t->value;
            t->value = 0;
        }
    }
}

void game::printBoard(){
    for(int i = 0; i < dimen; i++){
        for(int j = 0; j < dimen; j++){
            if(board[(i*dimen) + j]->value == 0){
                std::cout << "- ";
            } else std::cout << pow(2, board[(i*dimen) + j]->value) << " ";
        }
        std::cout << std::endl;
    }
}

void game::generate(){
    bool ungenerated = true;
    int pos = rand() % 16;

    while(ungenerated){
        if(board[pos]->value == 0){
            if(rand() % (TOTALTILES/2) == 0){
                if(rand() % 2 == 0) board[pos]->value = 1;
                else board[pos]->value = 2;
                ungenerated = false;
            }
        }

        pos = rand() % 16;
    }
}

bool game::allUp(){
    for(int i = 0; i < TOTALTILES; i++){
        if(canUp(board[i])){
            return false;
        }
    }
    return true;
}

bool game::allDown(){
    for(int i = 0; i < TOTALTILES; i++){
        if(canDown(board[i])){
            return false;
        }
    }
    return true;
}

bool game::allLeft(){
    for(int i = 0; i < TOTALTILES; i++){
        if(canLeft(board[i])){
            return false;
        }
    }
    return true;
}

bool game::allRight(){
    for(int i = 0; i < TOTALTILES; i++){
        if(canRight(board[i])){
            return false;
        }
    }
    return true;
}

bool game::canUp(tile* t){
    if(t->value == 0) return false;
    else {
        if(t->pos < dimen){
            return false;
        }
        if(!t->sameAs(board[t->pos-dimen]) && board[t->pos-dimen]->value != 0){
            return false;
        }
        return true;
    }
}

bool game::canDown(tile* t){
    if(t->value == 0) return false;
    else {
        if(t->pos >= TOTALTILES-dimen){
            return false;
        }
        if(!t->sameAs(board[t->pos+dimen]) && board[t->pos+dimen]->value != 0){
            return false;
        }
        return true;
    }
}

bool game::canLeft(tile* t){
    if(t->value == 0) return false;
    else {
        if(t->pos % dimen == 0){
            return false;
        }
        if(!t->sameAs(board[t->pos-1]) && board[t->pos-1]->value != 0){
            return false;
        }
        return true;
    }
}

bool game::canRight(tile* t){
    if(t->value == 0) return false;
    else {
        if(t->pos % dimen == (dimen - 1)){
            return false;
        }
        if(!t->sameAs(board[t->pos+1]) && board[t->pos+1]->value != 0){
            return false;
        }
        return true;
    }
}

int game::getTile(int i){
    int ret = pow(2,board[i]->value);

    if(ret > 0) return ret;
    else return 0;
}

1 个答案:

答案 0 :(得分:0)

在“睡觉之后”想出来。它与游戏内存中的位置以及访问位置有关。游戏必须在主窗口类中进行实例化,以便主窗口的其他部分使用它。

此外,仅为其他人提供未来的建议。 LCD对象没有更新有两个原因:

  • 小部件中有update()个功能。因此,如果您编写update()而不是updateLCD(),编译器就不会惊慌失措。
  • 您必须使用'this'调用对象上的函数。程序需要知道这个更新发生在它正在调用的项目上。