完成一個猜數字的GUI遊戲

任務描述

完成一個猜數字的GUI遊戲。
開始遊戲後,產生一個沒有重複數字的4位隨機數,用戶每猜一個數字,顯示出“完全猜中的數字個數”和“猜中數字但位置錯誤的數字個數”,比如nAmB,數字n表示猜中的位置正確的數字個數,數字m表示數字正確而位置不對的數字個數。例如,正確答案爲5234,如果用戶猜5346,則顯示:1A2B,數字1表示數字5及其位置猜對了,數字3和4這兩個數字猜對了,但是位置沒對,記爲2B。然後,用戶根據遊戲提示的信息繼續猜,直到猜中爲止。同時設計規則,根據猜中的次數計算積分,並可以顯示不同用戶的排行榜

規則設計

一次猜中得100分,2 ~3次猜中得90分,4 ~ 5次猜中得80分,6~7得70分,8 ~9得60分,10 ~11得50分,12 ~13得40分,14 ~15得30分,16 ~17得20分,18及以上得10分

數據庫設計

一個表用戶-users,主碼是user_id並且使默認遞增的。

主要邏輯

  • 1)如何產生沒有重複數字的四位數字,並且判斷不以零開頭。
    //獲取隨機數
    int MainWindow::generateRandomNumber(){
    int tag[]={0,0,0,0,0,0,0,0,0,0};
    int four=0;
    int temp=0;
    
    while(four<1000){
       temp=qrand()%10;//隨機獲取0~9的數字
       if(tag[temp]==0){
           four+=temp;
           four*=10;
           tag[temp]=1;
       }
    }
    return four;
    }
    
  • 2)如何根據玩家猜測的數字給出幾個A和幾個B,返回值是int,一個A是10,一個B是1
    • A的個數通過逐步求餘判斷每個位是否相等
    • B的個數通過求餘獲得玩家猜測數字的每一位,然後用每一位與產生的隨機數的不同位作比較。
//獲得A的個數
int Game_interface::getA(QString quessNumber){
    int quessNum = quessNumber.toInt();
    int resultNum = randomNumber;

    int A = 0;

    //求餘運算
    while(quessNum!=0){
        if(quessNum%10 == resultNum%10){
            A+=10;
        }
        quessNum/=10;
        resultNum/=10;
    }

    return A;
}
//獲得B的個數
int Game_interface::getB(QString quessNumber){
    int quessNum = quessNumber.toInt();
    int resultNum = randomNumber;

    int B = 0;

    int unit = resultNum%10;
    resultNum/=10;
    int ten = resultNum%10;
    resultNum/=10;
    int hundred = resultNum%10;
    resultNum/=10;
    int thousand = resultNum%10;

    while(quessNum!=0){
        switch (getDigits(quessNum)) {
        case 4:
            if(equalsNumbers(quessNum%10,ten,hundred,thousand)){
                B++;
            }
            quessNum/=10;
            break;
        case 3:
            if(equalsNumbers(quessNum%10,unit,hundred,thousand)){
                B++;
            }
            quessNum/=10;
            break;
        case 2:
            if(equalsNumbers(quessNum%10,unit,ten,thousand)){
                B++;
            }
            quessNum/=10;
            break;
        case 1:
            if(equalsNumbers(quessNum%10,unit,ten,hundred)){
                B++;
            }
            quessNum/=10;
            break;
        }
        }

    return B;

    }

  • 3)根據int到向用戶提示是幾個A和幾個B(一共有15種情況,switch case語句)
//記錄每次的猜測結果,並插入到表格中
void Game_interface::guessResult(int result_my,QString quessNumber){

    switch(result_my){
    case 0:
        ui->tableWidget->setItem(rowNumber,0,new QTableWidgetItem(quessNumber));//插入猜測的數字
        ui->tableWidget->setItem(rowNumber,1,new QTableWidgetItem("0A0B"));
        break;
    case 1:
        ui->tableWidget->setItem(rowNumber,0,new QTableWidgetItem(quessNumber));//插入猜測的數字
        ui->tableWidget->setItem(rowNumber,1,new QTableWidgetItem("0A1B"));
        break;
    case 2:
        ui->tableWidget->setItem(rowNumber,0,new QTableWidgetItem(quessNumber));//插入猜測的數字
        ui->tableWidget->setItem(rowNumber,1,new QTableWidgetItem("0A2B"));
        break;
    case 3:
        ui->tableWidget->setItem(rowNumber,0,new QTableWidgetItem(quessNumber));//插入猜測的數字
        ui->tableWidget->setItem(rowNumber,1,new QTableWidgetItem("0A3B"));
        break;
    case 4:
        ui->tableWidget->setItem(rowNumber,0,new QTableWidgetItem(quessNumber));//插入猜測的數字
        ui->tableWidget->setItem(rowNumber,1,new QTableWidgetItem("0A4B"));
        break;
    case 10:
        ui->tableWidget->setItem(rowNumber,0,new QTableWidgetItem(quessNumber));//插入猜測的數字
        ui->tableWidget->setItem(rowNumber,1,new QTableWidgetItem("1A0B"));
        break;

    case 11:
        ui->tableWidget->setItem(rowNumber,0,new QTableWidgetItem(quessNumber));//插入猜測的數字
        ui->tableWidget->setItem(rowNumber,1,new QTableWidgetItem("1A1B"));
        break;
    case 12:
        ui->tableWidget->setItem(rowNumber,0,new QTableWidgetItem(quessNumber));//插入猜測的數字
        ui->tableWidget->setItem(rowNumber,1,new QTableWidgetItem("1A2B"));
        break;
    case 13:
        ui->tableWidget->setItem(rowNumber,0,new QTableWidgetItem(quessNumber));//插入猜測的數字
        ui->tableWidget->setItem(rowNumber,1,new QTableWidgetItem("1A3B"));
        break;
    case 20:
        ui->tableWidget->setItem(rowNumber,0,new QTableWidgetItem(quessNumber));//插入猜測的數字
        ui->tableWidget->setItem(rowNumber,1,new QTableWidgetItem("2A0B"));
        break;
    case 21:
        ui->tableWidget->setItem(rowNumber,0,new QTableWidgetItem(quessNumber));//插入猜測的數字
        ui->tableWidget->setItem(rowNumber,1,new QTableWidgetItem("2A1B"));
        break;
    case 22:
        ui->tableWidget->setItem(rowNumber,0,new QTableWidgetItem(quessNumber));//插入猜測的數字
        ui->tableWidget->setItem(rowNumber,1,new QTableWidgetItem("2A2B"));
        break;
    case 30:
        ui->tableWidget->setItem(rowNumber,0,new QTableWidgetItem(quessNumber));//插入猜測的數字
        ui->tableWidget->setItem(rowNumber,1,new QTableWidgetItem("3A0B"));
        break;
    case 31:
        ui->tableWidget->setItem(rowNumber,0,new QTableWidgetItem(quessNumber));//插入猜測的數字
        ui->tableWidget->setItem(rowNumber,1,new QTableWidgetItem("3A1B"));
        break;
    //猜中游戲結束
    case 40:
        qDebug()<<"恭喜你猜對了!/n你一共猜了"+QString::number(rowNumber+1)+"次";
        QMessageBox::StandardButton reply;
        reply = QMessageBox::information(this, tr("闖關成功!"), "恭喜你猜對了!你最終的得分是"+getScore(rowNumber));
        this->close();
        break;
    }
}

界面設計

  • 設計登錄界面(知識點:文本框,按鈕的美化)
    在這裏插入圖片描述
  • 設計註冊界面
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ZUcMdLYg-1591450305322)(https://s1.ax1x.com/2020/04/15/JCqM5T.png)]
  • 設計主界面
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-WtSJC4OW-1591450305326)(https://s1.ax1x.com/2020/04/15/JCOStf.png)]
  • 排行榜界面(表格)
    在這裏插入圖片描述
  • 遊戲主界面
    在這裏插入圖片描述

體現面向對象的特點

1.封裝

  • 1)將與數據庫的操作封裝到qtODBC中。
class ODBC

    QSqlDatabase db ;
    QSqlQuery result;

    //構造方法
public :ODBC(){
        db = QSqlDatabase::addDatabase("QODBC");
        //輸出可用數據庫
        qDebug()<<"available drivers:";
        QStringList drivers = QSqlDatabase::drivers();
        foreach(QString driver, drivers)
            qDebug()<<driver;


        db.setHostName("127.0.0.1");
        db.setPort(3306);
        db.setDatabaseName("qt_contection_mysql");
        db.setUserName("root");
        db.setPassword("Fxk199959");
        bool ok = db.open();
        if (ok){
            //            QMessageBox::information(this, "infor", "success");
            qDebug()<<"數據庫連接成功!"<<endl;
        }
        else {
            //        QMessageBox::information(this, "infor", "open failed");
            qDebug()<<"error open database because"<<db.lastError().text();
        }

    }

    ~ODBC(){
        db.close();
    }

    //顯示數據庫中表的名稱
    void showTables(){
        //查詢數據庫中所有表的名稱
        QStringList tables = db.tables();
        foreach(QString table, tables)
            qDebug()<<table;
    }

    //通過sql查詢表
public : QList<Users *> selectData(QString sql){

        QList<Users *> message_user;//儲存所有老用戶的信息
        Users *user;//單個老用戶

        //ODBC查詢數據
        result = db.exec(sql);
        while(result.next()){
            int user_id = result.value("user_id").toInt();
            QString name = result.value("name").toString();
            QString password = result.value("password").toString();
            int score = result.value("score").toInt();

            qDebug()<<"user_id:"<<user_id;
            qDebug()<<"name:"<<name;
            qDebug()<<"password:"<<password;
            qDebug()<<"score:"<<score<<endl;

            user = new Users(user_id,name,password,score);

            message_user.insert(0,user);
        }

        return  message_user;

    }

    //插入表
public :void insertData(QString sql){

        //ODBC插入數據
        QSqlQuery insertResult(db);
        bool result_successed = insertResult.exec(sql);

        if(result_successed){
            qDebug()<<"插入成功!";
        }else {
            qDebug()<<"插入失敗!";
        }
    }

    //更新表
public :bool updateData(QString sql){
        //ODBC更新數據
        QSqlQuery updateResul(db);
        bool result_successed2 = updateResul.exec(sql);

        if(result_successed2){
            qDebug()<<"更新成功!"<<endl;
        }else{
            qDebug()<<"更新失敗!"<<endl;
        }

        return result_successed2;
    }
  • 2)封裝了用戶類
class Users{
    int user_id;
    QString name;
    QString  password;
    int score;

public:
    Users(int user_id,QString name,QString password,int score){
        this->name = name;
        this->password = password;
        this->user_id = user_id;
        this->score = score;
    }

    Users(int user_id,QString name,QString password){
        this->name = name;
        this->password = password;
        this->user_id = user_id;
    }

    // 重載運算符( == )
    bool equalUser(const Users* user2)
    {


       if(user_id==user2->user_id&&QString::compare(name,user2->name)==0
       &&QString::compare(password,user2->password)==0){
           return true;
       }
       return false;
    }

    QString getName(){
        return  name;
    }
    int getID(){
        return  user_id;
    }
    int getScore(){
        return  score;
    }

};

2.繼承

在該項目中,所有可視化的界面類都繼承自QWidget類。在qt中QWidget是所有用戶界面對象的基類,被稱爲基礎窗口部件。

3.多態

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章