2016-04-06 268 views
-1

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

的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; 
} 
+0

您应该使用调试器来查看崩溃行中使用的所有相关变量的值。另外,也许你可以发布Ui :: MainWindow生成的C++源代码,以便我可以尝试在这里重现你的问题? –

+0

另外,我不知道你发送给程序的输入是什么样的(例如鼠标点击和键盘事件)以使其崩溃。您应该尝试通过直接从'main'调用游戏对象上的函数来使其崩溃。然后你可以摆脱MainWindow,这使得其他人更容易重现你的程序。 –

回答

0

想通了之后 '上睡觉。'它必须处理游戏记忆中的位置以及它被访问的位置。游戏必须的主窗口类中实例化,以便主窗口的其他部分使用它。

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

  • 有一个update()函数构建到窗口小部件中。因此,如果编写update()而不是比如说updateLCD(),那么编译器不会吓坏了。
  • 您必须使用'this'在对象上调用函数。程序需要知道这个更新发生在它被调用的项目上。