任務描述
完成一個猜數字的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;
}
}
界面設計
- 設計登錄界面(知識點:文本框,按鈕的美化)
- 設計註冊界面
- 設計主界面
- 排行榜界面(表格)
- 遊戲主界面
體現面向對象的特點
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是所有用戶界面對象的基類,被稱爲基礎窗口部件。