Qt 2048

最近在学习Qt,就编个2048练练手,界面是不怎么好看,但算法应该是没什么问题的,要是有哪些可以优化的或者那些有错的地方,帮忙告知一下,3Q。

1.界面:

    界面是新建一个QDialog,然后再里面建一个 QWidget,再往QWidget内添加16个QLabel,在QWdiget的上面添加2个LCDNumber,一个用于显示步数,一个用于显示最大值。界面如图:


2,代码:

  (1) Dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QLabel>
#include <QTime>
#include <QFont>
#include <QPalette>
#include <QObject>
#include <QKeyEvent>
#include <QEvent>
#include <QHash>
#include <QLayout>
#include <QtMath>



namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

  public:

    explicit Dialog(QWidget *parent = 0);
    void newgame(); //开始游戏
    void upmove(); //上移
    void downmove(); //下移
    void leftmove(); //左移
    void rightmove(); //右移
    void upremoveblank();
    void downremoveblank();
    void leftremoveblank();
    void rightremoveblank();
    int testup(); //能否上移测试
    int testdown(); //能否上移测试
    int testright(); //能否上移测试
    int testleft(); //能否上移测试
    int panemax(); //棋盘最大数
    int ifwin(); //判断是否胜利
    int ifGameOver();  //判断是否游戏结束
    void update(const int& t);
    ~Dialog();

protected:
    void keyPressEvent(QKeyEvent *event);

private:
    QWidget * widget;
    int pane[4][4]; //棋盘
    Ui::Dialog *ui;
    QHash<int,QLabel*>labelHash;
    QGridLayout *layout;
};


#endif // DIALOG_H

(2) Dialog.cpp

  

#include "dialog.h"
#include "ui_dialog.h"
#include <QKeyEvent>
#include <QDebug>
#include <QMessageBox>

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    layout = new QGridLayout;
    labelHash.insert(0,ui->label1);
    labelHash.insert(1,ui->label2);
    labelHash.insert(2,ui->label3);
    labelHash.insert(3,ui->label4);
    labelHash.insert(4,ui->label5);
    labelHash.insert(5,ui->label6);
    labelHash.insert(6,ui->label7);
    labelHash.insert(7,ui->label8);
    labelHash.insert(8,ui->label9);
    labelHash.insert(9,ui->label10);
    labelHash.insert(10,ui->label11);
    labelHash.insert(11,ui->label12);
    labelHash.insert(12,ui->label13);
    labelHash.insert(13,ui->label14);
    labelHash.insert(14,ui->label15);
    labelHash.insert(15,ui->label16);

    for(int i=0;i<16;i++)
    {
        labelHash.value(i)->setFrameShape(QLabel::Box);
        labelHash.value(i)->setText(" ");
        layout->addWidget(labelHash.value(i),i/4,i%4,1,1);
    }
    layout->setSpacing(4);
    this->ui->widget->setLayout(layout);
    this->ui->widget->resize(300,300);
    newgame();

}
void Dialog::newgame() //开始游戏
{
     QTime time;
     time = QTime::currentTime();
     qsrand(time.msec()+time.second()*1000);
     for(int i=0;i<=3;i++) //初始化棋盘
        for(int j=0;j<=3;j++)
             pane[i][j]=0;
     int m=qrand()%4;
     int n=qrand()%4;
     int b=qrand()%4;
     int q=qrand()%4;
     pane[m][n]=pane[b][q]=2;
     update(0);

}
void Dialog::upremoveblank()
{
    for(int j=0;j<4;j++){
        int k = 0;
        for(int i=0;i<4;i++){
            if(pane[i][j] != 0)
                pane[k++][j] = pane[i][j];
            }
        while(k<4)
        {
            pane[k][j] = 0;
            k++;
        }
    }
}

void Dialog::downremoveblank()
{
    for(int j=0;j<4;j++){
        int k = 3;
        for(int i=3;i>=0;i--){
            if(pane[i][j] != 0)
                pane[k--][j] = pane[i][j];
            }
        while(k>=0)
        {
            pane[k][j] = 0;
            k--;
        }
    }
}

void Dialog::leftremoveblank()
{
    for(int i=0;i<4;i++){
        int k = 0;
        for(int j=0;j<4;j++){
            if(pane[i][j] != 0)
                pane[i][k++] = pane[i][j];
            }
        while(k<4)
        {
            pane[i][k] = 0;
            k++;
        }
    }
}

void Dialog::rightremoveblank()
{
    for(int i=0;i<4;i++){
        int k = 3;
        for(int j=3;j>=0;j--){
            if(pane[i][j] != 0)
                pane[i][k--] = pane[i][j];
            }
        while(k>=0)
        {
            pane[i][k] = 0;
            k--;
        }
    }
}

void Dialog::upmove() //上移
{
     for(int j=0;j<4;j++){//每一列
         for(int i=0;i<3;i++){
             if(pane[i][j]==pane[i+1][j]){
                 pane[i][j]=pane[i][j]+pane[i+1][j];
                 pane[i+1][j]=0;
                 //移除空格
                 upremoveblank();
             }
         }
     }
}
void Dialog::downmove() //下移
{
   for(int j=0;j<4;j++){//每一列
       for(int i=3;i>=1;i--){
           if(pane[i][j]==pane[i-1][j]){
               pane[i][j]=pane[i][j]+pane[i-1][j];
               pane[i-1][j]=0;
               //移除空格
               downremoveblank();
           }
       }
   }
}
void Dialog::leftmove() //左移
{
   for(int i = 0;i < 4;i++){
       for(int j = 0;j<3;j++){
           if(pane[i][j]==pane[i][j+1]){
               pane[i][j]+=pane[i][j+1];
               pane[i][j+1]=0;
               leftremoveblank();
           }
       }
   }
}
void Dialog::rightmove() //右移
{
    for(int i=0;i<4;i++){
        for(int j=3;j >= 1;j--){
            if(pane[i][j]==pane[i][j-1]){
                pane[i][j]+=pane[i][j-1];
                pane[i][j-1]=0;
                rightremoveblank();
            }
        }
    }
}
int Dialog::testup() //能否上移测试
{
    int flag=0;
    for(int j=0;j<=3;j++)
        for(int i=0;i<3;i++)
        {
            if(pane[i][j] == pane[i+1][j] || pane[i][j] == 0)
            {
                flag=1;
            }
        }
    return flag;
}
int Dialog::testdown() //测试能否下移
{
    int flag=0;
    for(int j=0;j<=3;j++)
        for(int i=3;i>0;i--)
        {
            if(pane[i][j] == pane[i-1][j] || pane[i][j] == 0)
            {
                 flag=1;
            }
        }
    return flag;
}
int Dialog::testleft() //测试能否左移
{
    int flag=0;
    for(int i=0;i<=3;i++)
        for(int j=0;j<3;j++)
        {
           if(pane[i][j] == pane[i][j+1] || pane[i][j] == 0)
            {
                 flag=1;
            }
        }
    return flag;
}
int Dialog::testright() //测试能否右移
{
    int flag=0;
    for(int i=0;i<=3;i++)
        for(int j=3;j>0;j--)
        {
           if(pane[i][j] == pane[i][j-1] || pane[i][j] == 0)
            {
                 flag=1;
            }
        }
    return flag;
}
int Dialog::panemax() //棋盘最大数
{
    int max=pane[0][0];
    for(int i=0;i<=3;i++)
        for(int j=0;j<=3;j++)
            if(pane[i][j]>max)
                max=pane[i][j];
    return max;
}
int Dialog::ifwin() //判断是否胜利
{
    int flag=0;
    if(panemax()==2048)
    {
        QMessageBox::about(this,"Congratulation","You Win!");
        flag=1;
    }
    return flag;
}
int Dialog::ifGameOver()  //判断是否游戏结束
{
    int flag=0;
    if(testup()+ testdown() + testleft() + testright() == 0)
    {
        QMessageBox::about(this,"Failed","Game Over!");
        flag=1;
    }
    return flag;
}

void Dialog::keyPressEvent(QKeyEvent *event)
{
    QTime time;
    static int t = 0;
    time = QTime::currentTime();
    qsrand(time.msec()+time.second()*1000);
    switch (event->key()) {
    case Qt::Key_Up:
        upremoveblank();
        upmove();
        for(int i = 0,timer =0 ; i< 4,timer < 1; i ++){
            if(pane[3][i] == 0)
                if(qrand()%2){
                    pane[3][i] = 2;
                    timer++;
                }
            }
        t++;
        update(t);
        break;
    case Qt::Key_Down:
        downremoveblank();
        downmove();
        for(int i = 0,timer =0 ; i< 4,timer < 1; i ++){
            if(pane[0][i] == 0)
                if(qrand()%2){
                    pane[0][i] = 2;
                    timer++;
                }
        }
         t++;
        update(t);
        break;
    case Qt::Key_Left:
        leftremoveblank();
        leftmove();

       for(int i = 0,timer =0 ; i< 4,timer < 1; i ++){
            if(pane[i][3] == 0)
                if(qrand()%2){
                    pane[i][3] = 2;
                    timer ++;
                }
       }
        t++;
       update(t);
        break;
    case Qt::Key_Right:
        rightremoveblank();
        rightmove();
        for(int i = 0,timer =0 ; i< 4,timer < 1; i ++){
            if(pane[i][0] == 0)
                if(qrand()%2){
                    pane[i][0] = 2;
                    timer++;
                }
        }
         t++;
        update(t);
        break;
    default:
        break;
    }
}

void Dialog::update(const int &t)
{
    ifGameOver();
    ifwin();
    for(int i = 0 ; i < 4 ; i++)
        for(int j = 0; j < 4; j++)
        {
            int p = i*4+j;
            if(pane[i][j])
            {
                labelHash.value(p)->setText(QString::number(pane[i][j]));
            }
            else
                labelHash.value(p)->setText(" ");
            QFont ftt;
            ftt.setPointSize(24);
            labelHash.value(p)->setFont(ftt);
            QPalette pa;
            pa.setColor(QPalette::WindowText,Qt::white);
            labelHash.value(p)->setPalette(pa);
            labelHash.value(p)->setAlignment(Qt::AlignCenter);
            labelHash.value(p)->setStyleSheet("background-color:red");
        }
    ui->lcdNumber->display(QString::number(panemax()));
    ui->lcdNumber_2->display(QString::number(t));
}


Dialog::~Dialog()
{
    delete layout;
    delete widget;
    delete ui;
}

(3) Main.cpp

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

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Dialog *mainwindow = new Dialog;
    mainwindow->exec();

    return a.exec();
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值