
有三种难度初级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();
 }
  



















