自学内容网 自学内容网

2024/9/20 使用QT实现扫雷游戏

有三种难度初级6x6 中级10x10  高级16x16

 

完成游戏

游戏失败后,无法再次完成游戏,只能重新开始一局

对Qpushbutton进行重写

mybutton.h

#ifndef MYBUTTON_H
#define MYBUTTON_H

#include <QObject>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
class mybutton : public QPushButton
{
    Q_OBJECT
public:
    mybutton(QWidget *parent = nullptr);
    void set_value(int hang,int lie);
    //重写鼠标点击事件
protected:
    virtual void    mouseReleaseEvent(QMouseEvent * event);

    //定义两个信号
signals:
    void LeftClicked(int hang,int lie);
    void RightClicked(int hang,int lie);

private:
    int lie;
    int hang;
};

#endif // MYBUTTON_H
 

mybutton.c

#include "mybutton.h"

 mybutton::mybutton(QWidget *parent):
    QPushButton(parent)
{

}

 void mybutton::mouseReleaseEvent(QMouseEvent * event)
 {
     //判断是鼠标左键点击还是右键点击
     if(event->button() ==  Qt::LeftButton)
     {//左键点击了
         emit LeftClicked(hang,lie);
     }
     if(event->button() ==  Qt::RightButton)
     {//右键点击了
         emit RightClicked(hang,lie);
     }
 }
void mybutton::set_value(int hang,int lie)
{
    this->hang=hang;
    this->lie=lie;
}
 

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTimer>
#include "mybutton.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

#define Lei 10 //设置雷占格子的多少

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    void time_out(void);
    int GetThisMine(int hang,int lie,int i,int j);
    void Initbutton(int i,int j);
    void clear_button(int i,int j);
    //定义两个槽函数 用于处理按键左右键点击的信号
public slots:
   void LeftClickedSlots(int hang,int lie);
   void RightClickedSlots(int hang,int lie);
   void on_pushButton_clicked();
   void on_pushButton_2_clicked();
   void on_pushButton_4_clicked();
   void on_pushButton_3_clicked();

private slots:
   void on_pushButton_5_clicked();

private:
    Ui::Widget *ui;
    QTimer *tm1;
    int i,j;
    mybutton *Buttons;
    bool *mine;
    int flag=0;
    int s=0;
    int win=0;
};
#endif // WIDGET_H
 

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "QDebug"
#include <QThread>
#include <QMessageBox>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    tm1 = new QTimer(this);
    //2,绑定定时器时间到槽
    connect(tm1, &QTimer::timeout, this,&Widget::time_out);
    //3.启动定时器
    tm1->start(1000); //定时器时间1000ms
    ui->lcdNumber->display(100);
    this->setWindowTitle("扫雷");
    //设置布局框大小
    ui->gridLayoutWidget->resize(this->size());
    ui->gridLayoutWidget->move(0,0);
}

Widget::~Widget()
{
    delete ui;
    delete []mine;
    delete []Buttons;
}

void Widget::time_out()
{
    //qDebug()<< "定时器时间到";
    int num = ui->lcdNumber->value();
    num -= 1;
    if(num==0)
        tm1->stop(); //停止定时器
    ui->lcdNumber->display(num);
}
void Widget::Initbutton(int i,int j)
{   this->i=i;
    this->j=j;
    Buttons =new mybutton[i*j];
    for(int hang = 0; hang <i; hang++)
        for(int lie =0; lie < j; lie++)
        {
            Buttons[hang*j+lie].set_value(hang,lie);
            Buttons[hang*j+lie].setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);
            //将按钮放到布局中
            ui->gridLayout->addWidget(&Buttons[hang*j+lie], hang+1, lie);
            ui->gridLayout->setRowStretch(hang,0);
            ui->gridLayout->setColumnStretch(lie,0);
            //绑定信号和槽
            connect(&Buttons[hang*j+lie], &mybutton::LeftClicked, this, &Widget::LeftClickedSlots);
            connect(&Buttons[hang*j+lie], &mybutton::RightClicked, this, &Widget::RightClickedSlots);
        }
    //摇雷 ((i*j)/4)个
    srand(time(0));
    mine = new bool[i*j];
    for(int k=0;k<i*j;k++) mine[k]=false;
    for(int k=0;k<((i*j)/Lei);k++)
    {
        while(1){
            int h = rand() % i;
            int l = rand() % j;
            if(!mine[h*j+l])
            {//此处没有雷
                mine[h*j+l] = true;
                break;
            }
        }
    }
//    for(int h=0;h<i*j;h++)
//        qDebug()<<mine[h];
    }
void Widget::clear_button(int i,int j)
{
    for(int hang = 0; hang <i; hang++)
        for(int lie =0; lie < j; lie++)
            ui->gridLayout->removeWidget(&Buttons[hang*j+lie]);
    delete []Buttons;
    s=0;
    win=0;
}

void Widget::on_pushButton_clicked()//低级难度
{
    switch(flag)
    {
    case 0:Initbutton(6,6);break;
    case 1:clear_button(6,6);Initbutton(6,6);break;
    case 2:clear_button(10,10);Initbutton(6,6);break;
    case 3:clear_button(16,16);Initbutton(6,6);break;
    default: qDebug()<<"游戏未开始";
    }
    flag=1;
}


void Widget::on_pushButton_2_clicked()//中级难度
{
    switch(flag)
    {
    case 0:Initbutton(10,10);break;
    case 1:clear_button(6,6);Initbutton(10,10);break;
    case 2:clear_button(10,10);Initbutton(10,10);break;
    case 3:clear_button(16,16);Initbutton(10,10);break;
    default: qDebug()<<"游戏未开始";
    }
    flag=2;
}

void Widget::on_pushButton_4_clicked()//高级难度
{
    switch(flag)
    {
    case 0:Initbutton(16,16);break;
    case 1:clear_button(6,6);Initbutton(16,16);break;
    case 2:clear_button(10,10);Initbutton(16,16);break;
    case 3:clear_button(16,16);Initbutton(16,16);break;
    default: qDebug()<<"游戏未开始";
    }
    flag=3;
}

void Widget::on_pushButton_3_clicked()//重玩
{
    switch(flag)
    {
    case 1:clear_button(6,6);Initbutton(6,6);break;
    case 2:clear_button(10,10);Initbutton(10,10);break;
    case 3:clear_button(16,16);Initbutton(16,16);break;
    default: qDebug()<<"游戏未开始";
    }
}
void Widget::LeftClickedSlots(int hang,int lie)//左击
{
    int n=i,m=j;
    qDebug() << "左键点击:" << hang << lie;
    Buttons[hang*m+lie].setCheckable(true);
    Buttons[hang*m+lie].setChecked(true); //显示为按键按下
    Buttons[hang*m+lie].setDisabled(true); // 按键不能交互
    ui->gridLayoutWidget->update();
    qDebug() << "按键锁定:";
    //显示周围有多少雷
    if(GetThisMine(hang,lie,n,m)==-1){
        Buttons[hang*m+lie].setText(QString::number(-1));
        QMessageBox::information(nullptr, "游戏失败", "恭喜你踩了一个雷");
    }
    //int cnt = GetThisMine(hang,lie,n,m);
    //Buttons[hang*m+lie].setText(QString::number(cnt));

}

void Widget::RightClickedSlots(int hang,int lie)//右击
{
    int n=i,m=j;
    qDebug() << "右键点击:" << hang << lie;
    //标记是雷
    QIcon icon(":/1.png");//使用资源包,相对路径
    if(Buttons[hang*m+lie].icon().isNull())
    {
    Buttons[hang*m+lie].setIcon(icon);
    qDebug()<<n;
    Buttons[hang*m+lie].setIconSize(QSize(Buttons[hang*m+lie].size().width()-20,
                                    Buttons[hang*m+lie].size().height() -20));
    win++;
    if(win==i*j) QMessageBox::information(nullptr, "游戏胜利", "恭喜你完成了游戏");
    return;
    }
    if(!Buttons[hang*m+lie].icon().isNull())
        Buttons[hang*m+lie].setIcon(QIcon());
    win--;

}

//计算hang,lie位置有多少雷
int Widget::GetThisMine(int hang,int lie,int n,int m)
{
    if(mine[hang*m+lie]==true) return -1;
    int cnt = 0;
    for(int i=-1; i<= 1; i++)
        for(int j=-1; j<=1; j++)
        {
            if(  !(i==0 && j==0) )
            {//排除自己
                if( hang+i < 0 || hang+i >= n || lie+j >= m || lie+j < 0 )
                    continue; //排除越界
                if(mine[(hang+i)*m+lie+j]) cnt ++;
            }
        }
    QThread::msleep(50);
    if(s==n*m) return cnt;
    qDebug() << "当前有值:"<<cnt<< s++<<endl;
    Buttons[hang*m+lie].setText(QString::number(cnt));
    Buttons[hang*m+lie].setCheckable(true);
    Buttons[hang*m+lie].setChecked(true); //显示为按键按下
    Buttons[hang*m+lie].setDisabled(true); // 按键不能交互
    ui->gridLayoutWidget->update();
    win++;
    if(win==i*j) QMessageBox::information(nullptr, "游戏胜利", "恭喜你完成了游戏");
    if(cnt==0)
    {
        //四个方向 左 上 右 下
        if(lie-1>=0&&Buttons[hang*m+lie-1].text().isEmpty()){
            qDebug() << "左连:";
            GetThisMine(hang,lie-1,n,m);
        }
        if(hang-1>=0&&Buttons[(hang-1)*m+lie].text().isEmpty()){
            qDebug() << "上连:";
            GetThisMine(hang-1,lie,n,m);
        }
        if(lie+1<m&&Buttons[hang*m+lie+1].text().isEmpty()){
            qDebug() << "右连:";
            GetThisMine(hang,lie+1,n,m);
        }
        if(hang+1<n&&Buttons[(hang+1)*m+lie].text().isEmpty()){
            qDebug() << "下连:";
            GetThisMine(hang+1,lie,n,m);
        }
        //四个角落 左上 右上 左下 右下
        if(hang-1>=0&&lie-1>=0&&Buttons[(hang-1)*m+lie-1].text().isEmpty()){
            qDebug() << "左上连:";
            GetThisMine(hang-1,lie-1,n,m);
        }
        if(hang-1>=0&&lie+1<m&&Buttons[(hang-1)*m+lie+1].text().isEmpty()){
            qDebug() << "右上连:";
            GetThisMine(hang-1,lie+1,n,m);
        }
        if(hang+1<n&&lie-1>=0&&Buttons[(hang+1)*m+lie-1].text().isEmpty()){
            qDebug() << "左下连:";
            GetThisMine(hang+1,lie-1,n,m);
        }
        if(hang+1<n&&lie+1<m&&Buttons[(hang+1)*m+lie+1].text().isEmpty()){
            qDebug() << "右下连:";
            GetThisMine(hang+1,lie+1,n,m);
        }
    }
    return cnt;
}

void Widget::on_pushButton_5_clicked()
{
    //设置布局框大小
    ui->gridLayoutWidget->resize(this->size());
    ui->gridLayoutWidget->move(0,0);
}
 

main.c

#include "widget.h"

#include <QApplication>

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


原文地址:https://blog.csdn.net/qq_45607400/article/details/142393196

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!