QT 2048

1.先看ui图 和标签

2.代码注意点

子窗口:是标签的父窗口,否则显示不出来16个标签

因为Label继承了QLabel,如果不写QLabel(parent)情况下,不能把ui->widget变成Label的父类

就不能显示16个格子

同步分数的时候,分数大于最高,要best=score否则存储不了

label.h

#ifndef LABEL_H
#define LABEL_H

#include <QLabel>
#include <QWidget>
class Label : public QLabel
{
public:                                 //父类
   explicit  Label(int row,int column,QWidget *parent=0);
    ~Label();
   void setValue(int value);
};

#endif // LABEL_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include"label.h"
#include<QKeyEvent>
#include<iostream>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void randNumber(void);
    int checkStatus(void);
    void sync(void);//数据同步到Label中

    void save(void);
    void load(void);

    void up(void);
    void down(void);
    void left(void);

    void right(void);
    void keyReleaseEvent(QKeyEvent *event);//按键事件
private slots:
   void on_pushButton_clicked();

private:
    Ui::Widget *ui;
    Label *labs[4][4];
    //必须得初始化,不然会产生随机数
    short arr[4][4]={};
    bool is_move;
    int score;
    int best;

};
#endif // WIDGET_H

label.cpp

#include "label.h"
                              //       ui->widget              //必须要实例化
Label::Label(int row,int column,QWidget *parent):QLabel(parent)//?? 把ui->widget变成QLabel
{
    //设置大小,位置,字体的颜色,背景
    //窗口大小      parent=QWidget
    this->resize((parent->width()-50)/4,(parent->height()-50)/4);
    //样式表

    this->setStyleSheet("background-color:rgb(205,193,180);;font: 75 16pt\"Segoe UI Black\"");

    this->setAlignment(Qt::AlignCenter);
    this->move(10+(this->width()+10)*column,10+(this->height()+10)*row);
}

Label::~Label()
{

}
void Label::setValue(int value)
{
    char strValue[11];
    sprintf(strValue,"%d",value);
    this->setText(strValue);

    QString qss = "background-color: rgb(205, 193, 180);font: 75 16pt \"Segoe UI Black\";";
    switch(value)
    {
    case 0:
        qss += "background-color: rgb(205, 193, 180);color:rgb(205, 193, 180);";
        break;
    case 2:
        qss += "background-color: rgb(238, 228, 218);color:rgb(119, 110, 101);";
        break;
    case 4:
        qss += "background-color: rgb(237, 224, 200);color:rgb(119, 110, 101);";
        break;
    case 8:
        qss += "background-color: rgb(242, 177, 121);color:rgb(249, 246, 242);";
        break;
    case 16:
        qss += "background-color: rgb(245, 149, 99);color:rgb(249, 246, 242);";
        break;
    case 32:
        qss += "background-color: rgb(246, 124, 95);color:rgb(249, 246, 242);";
        break;
    case 64:
        qss += "background-color: rgb(246, 94, 59);color:rgb(249, 246, 242);";
        break;
    case 128:
        qss += "background-color: rgb(237, 207, 114);color:rgb(249, 246, 242);";
        break;
    case 256:
        qss += "background-color: rgb(237, 204, 97);color:rgb(249, 246, 242);";
        break;
    case 512:
        qss += "background-color: rgb(237, 200, 80);color:rgb(249, 246, 242);";
        break;
    case 1024:
        qss += "background-color: rgb(237, 197, 63);color:rgb(249, 246, 242);";
        break;
    case 2048:
        qss += "background-color: rgb(237, 194, 46);color:rgb(249, 246, 242);";
        break;
    }
    this->setStyleSheet(qss);

}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
#include<fstream>
#include<QDebug>
#include<QFile>

Widget::Widget(QWidget *parent)
    : QWidget(parent),score(0),best(0)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    for(int row=0;row<4;row++)
    {
        for(int column=0;column<4;column++)
        {                                        //子窗口:是标签的父窗口
            labs[row][column]=new Label(row,column,ui->widget1);
            //labs[row][column]->setText("2");
        }
    }

    // arr[0][0] = 1024;
    // arr[0][1] = 1024;

    // sync();
    // is_move=true;
    // randNumber();
    load();
}

Widget::~Widget()
{
    delete ui;
    if(0 == checkStatus())
        save();
    std::ofstream ofs("best.dat");
    ofs.write((char*)&best,sizeof(best));
    ofs.close();
}

void Widget::randNumber()
{
   // is_move = true;//给个初值,用于测试
    while (is_move)
    {
        int row = rand()%4; //四行四列
        int column = rand()%4;
        if(!arr[row][column])
        {
            arr[row][column]=2;
            sync();
            return;
        }
    }
}


//检查游戏的状态:0继续,1胜利,2,失败
int Widget::checkStatus()
{
    bool flag=false;
    for(int row=0;row<4;row++)
    {
        for(int column=0;column<4;column++)
        {
            if(2048== arr[row][column])
            {
                return 1;
            }
            if(0== arr[row][column])
            {
                flag=true;
            }
        }

    }
    if(flag==true)
        return 0;
    for(int row=0;row<3;row++)
    {
        for(int column=0;column<3;column++)
        {
            if(arr[row][column] == arr[row][column+1]||
                arr[row][column] == arr[row+1][column])
            {
                return 0;
            }
        }
    }
    for(int row=3;row>0;row--)
    {
        for(int column=3;column>0;column--)
        {
            if(arr[row][column] == arr[row][column-1]||
                arr[row][column] == arr[row-1][column])
            {
                return 0;
            }
        }
    }

    return 2;
}

//同步数组,分数,最高分
void Widget::sync()
{
    //同步数组到Label
    for(int row=0;row<4;row++)
    {
        for(int column=0;column<4;column++)
        {
            labs[row][column]->setValue(arr[row][column]);
        }
    }

    //同步分数
    char str[11];
    sprintf(str,"%d",score);
    ui->lab_score->setText(str);

    //最高分
    if(score>best)
    {
        best=score;//不能忘记
        ui->lab_best->setText(str);
    }
}
//写是输出 of

void Widget::save()
{
    std::ofstream ofs("game2048.dat");
    ofs.write((char*)arr,sizeof(arr));
    ofs.write((char*)&score,sizeof(score));
    ofs.close();
}
//读是输入 in

void Widget::load()
{
    std::ifstream ifs("game2048.dat");
    if(ifs.good())
    {
        ifs.read((char*)arr,sizeof(arr));
        ifs.read((char*)&score,sizeof(score));
        ifs.close();
        remove("game2048.dat");
        sync();
    }
    else
    {
        on_pushButton_clicked();
    }

    ifs.open("best.dat");
    if(ifs.good())
    {
        ifs.read((char*)&best,sizeof(best));
    }
    else
    {
        best=0;
    }
    char str[11];
    sprintf(str,"%d",best);
    ui->lab_best->setText(str);
    ifs.close();
}


void Widget::up()
{
    for(int y=0;y<4;y++)
    {
        int end = 0;
        for(int x=1;x<4;x++)
        {
            for(int i=x;i>end;i--)
            {
                if(arr[i][y] && arr[i][y] == arr[i-1][y])
                {
                    arr[i-1][y] *= 2;
                    arr[i][y] = 0;
                    end = i;
                    score += arr[i-1][y];
                    is_move = true;
                }
                else if(arr[i][y] && !arr[i-1][y])
                {
                    arr[i-1][y] = arr[i][y];
                    arr[i][y] = 0;
                    is_move = true;
                }
            }
        }
    }
}

void Widget::down()
{
    for(int y=0;y<4;y++)
    {
        int end = 3;
        for(int x=2;x>=0;x--)
        {
            for(int i=x;i<end;i++)
            {
                if(arr[i][y] && arr[i][y] == arr[i+1][y])
                {
                    arr[i+1][y] *= 2;
                    arr[i][y] = 0;
                    end = i;
                    score += arr[i+1][y];
                    is_move = true;
                }
                else if(arr[i][y] && !arr[i+1][y])
                {
                    arr[i+1][y] = arr[i][y];
                    arr[i][y] = 0;
                    is_move = true;
                }
            }
        }
    }

}

void Widget::left()
{
    for(int x=0;x<4;x++)
    {
        int end = 0;
        for(int y=1;y<4;y++)
        {
            for(int i=y;i>end;i--)
            {
                if(arr[x][i] && arr[x][i] == arr[x][i-1])
                {
                    arr[x][i-1] *= 2;
                    arr[x][i] = 0;
                    end = i;
                    score += arr[x][i-1];
                    is_move = true;
                }
                else if(arr[x][i] && !arr[x][i-1])
                {
                    arr[x][i-1] = arr[x][i];
                    arr[x][i] = 0;
                    is_move = true;
                }
            }
        }
    }
}

void Widget::right()
{
    for(int x=0;x<4;x++)
    {
        int end = 3;
        for(int y=2;y>=0;y--)
        {
            for(int i=y;i<end;i++)
            {
                if(arr[x][i] && arr[x][i] == arr[x][i+1])
                {
                    arr[x][i+1] *= 2;
                    arr[x][i] = 0;
                    end = i;
                    score += arr[x][i+1];
                    is_move = true;
                }
                else if(arr[x][i] && !arr[x][i+1])
                {
                    arr[x][i+1] = arr[x][i];
                    arr[x][i] = 0;
                    is_move = true;
                }
            }
        }
    }
}



void Widget::keyReleaseEvent(QKeyEvent *event)
{
    is_move=false;
    switch(event->key())
    {
    case Qt::Key_Up:up();break;
    case Qt::Key_Down:down();break;
    case Qt::Key_Left:left();break;
    case Qt::Key_Right:right();break;
    }
    randNumber();

    //获取当前游戏状态
    int status = checkStatus();
    if(0 == status)
        return;
    if(1 == status)
    {
        //this->close();//暂时设置赢了的话,关闭窗口
        QMessageBox msgBox;
        msgBox.setText("恭喜游戏胜利");
        msgBox.setInformativeText("还想再来一局吗?");
        msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
        msgBox.setDefaultButton(QMessageBox::Yes);
        int ret = msgBox.exec();
        switch (ret)
        {
        case QMessageBox::Yes:
            on_pushButton_clicked();
            break;
        case QMessageBox::No:
            this->close();
            break;
        }
    }
    if(2 == status)
    {
        //this->close();//暂时设置赢了的话,关闭窗口
        QMessageBox msgBox;
        msgBox.setText("游戏失败");
        msgBox.setInformativeText("还想再来一局吗?");
        msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
        msgBox.setDefaultButton(QMessageBox::Yes);
        int ret = msgBox.exec();
        switch (ret)
        {
        case QMessageBox::Yes:
            on_pushButton_clicked();
            break;
        case QMessageBox::No:
            this->close();
            break;
        }
    }
}

void Widget::on_pushButton_clicked()
{
    memset(arr,0,sizeof(arr));
    score=0;
    is_move=true;
    randNumber();
}

main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值