所以我只是制作一个所谓的简单程序来开始使用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;
}
答案 0 :(得分:0)
在“睡觉之后”想出来。它与游戏内存中的位置以及访问位置有关。游戏必须在主窗口类中进行实例化,以便主窗口的其他部分使用它。
此外,仅为其他人提供未来的建议。 LCD对象没有更新有两个原因:
update()
个功能。因此,如果您编写update()
而不是updateLCD()
,编译器就不会惊慌失措。