您好,登錄后才能下訂單哦!
本文小編為大家詳細(xì)介紹“C語言怎么實(shí)現(xiàn)數(shù)獨(dú)游戲”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“C語言怎么實(shí)現(xiàn)數(shù)獨(dú)游戲”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。
寫一個(gè)數(shù)獨(dú)游戲,有以下功能:
1:能隨機(jī)產(chǎn)生題目并給出答案。
2:求解輸入的題目并輸出答案。
參照百度百科等資料可以知道求解數(shù)獨(dú)的主要算法是:1.通過行、列和宮格確定可填數(shù)字。2.所有可行數(shù)字逐一填入得到結(jié)果。本程序求解數(shù)獨(dú)部分也采用這樣的算法。而生成題目的算法是:
隨機(jī)產(chǎn)生一個(gè)長度為9的一維數(shù)組,元素是隨機(jī)產(chǎn)生的1到9的不同數(shù)字。
比如為root = [1, 4, 3, 5, 6 ,7, 8 ,9, 2].
1、先獲得一個(gè)填滿的九宮格accord。
2、假如九宮格accord的第一行為[6, 4, 5, 7, 3, 9, 8, 1, 2], 則可獲得的九宮格squa的第一行第一列元素這樣產(chǎn)生:看accord對應(yīng)元素為6,則看root中6后一位的數(shù)為7,則所求數(shù)字為7。以此類推。
3、根據(jù)難度隨機(jī)去除一定數(shù)量的空格則得到了隨機(jī)產(chǎn)生的數(shù)獨(dú)題目。
下面介紹本程序的主要難點(diǎn)和創(chuàng)新點(diǎn):
1、解數(shù)獨(dú)的遞歸法。首先要定義一個(gè)檢查函數(shù)judge用于判斷某個(gè)數(shù)字在某個(gè)位置是否合適,進(jìn)而根據(jù)找到的遞歸頭即至最后一個(gè)位置后,分是否為0兩種情況,否則,繼續(xù)遞歸。
2、隨機(jī)產(chǎn)生1到9之間的數(shù)。由于編譯器自帶函數(shù)rand會出現(xiàn)元素不變的確點(diǎn),所以使用系統(tǒng)時(shí)間為種子,并引入全局變量index,使得時(shí)間差加大,避免固定不變。
3、定義各種函數(shù)簡化程序。本程序定義了fprintf用于打印九宮格,定義reRank來獲取元素在數(shù)組中位置等,簡化了程序。
結(jié)果
下面是分別選擇1(產(chǎn)生題目)和2(計(jì)算數(shù)獨(dú))后的結(jié)果圖:
代碼:
語言: C
//期末實(shí)驗(yàn)報(bào)告-簡單的數(shù)獨(dú)計(jì)算器 #include <stdio.h> #include <stdlib.h> #include <time.h> long index = 0; //全局變量index是保證每次產(chǎn)生的隨機(jī)元素隨機(jī)性 void main() { void solve(int squa[9][9], int num); void fprintf(int squa[9][9]); int reRank(int root[9], int numb); int myRand(int range); int squa[9][9], accord[9][9]={ //定義用于生成數(shù)獨(dú)的參照數(shù)組 {6, 4, 5, 7, 3, 9, 8, 1, 2}, {2, 1, 8, 6, 4, 5, 9, 7, 3}, {7, 3, 9, 2, 8, 1, 6, 4, 5}, {5, 9, 6, 3, 7, 4, 2, 8, 1}, {4, 8, 7, 5, 1, 2, 3, 6, 9}, {3, 2, 1, 8, 9, 6, 7, 5, 4}, {9, 5, 3, 4, 6, 7, 1, 2, 8}, {8, 7, 2, 1, 5, 3, 4, 9, 6}, {1, 6, 4, 9, 2, 8, 5, 3, 7} }; int root[9], answ[9][9]; //定義用于生成數(shù)組的一維數(shù)組和臨時(shí)數(shù)組 int i, j, k, p = 0; int row; int choose, rtemp, diff; //分別定義選擇變量,難度 char result; printf("———請選擇*1*生成一個(gè)數(shù)獨(dú)——*2*計(jì)算一個(gè)數(shù)獨(dú)———\n"); scanf("%d", &choose); //**************選擇1生成一個(gè)填好的數(shù)獨(dú)**************************** //根據(jù)生成數(shù)獨(dú)題目算法先存入一個(gè)數(shù)獨(dú) if(1 == choose) { //產(chǎn)生范圍為1-9的一維數(shù)組root for(i = 0; i < 9; i++) { root[i] = myRand(9); } for(i = 0; i < 9; i++) { for(j = 0; j < i; j++) { if(root[i]==root[j]) //使root中元素各不相同 root[i] = myRand(9); } } //隨機(jī)產(chǎn)生完整九宮格 for(i=0;i<9;i++) { for(j=0;j<9;j++) { row = reRank(root,accord[i][j]); squa[i][j] = root[(row+1)%9]; } } for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { answ[i][j] = squa[i][j]; } } //根據(jù)不同難度需求處理數(shù)組 printf("————請選擇難度等級:1(低級)--2(中級)--3(高級)————\n"); scanf("%d", &diff); if(diff==1) //難度為低級時(shí)有30個(gè)空格 { for(k=0; k<20;)//; k++) { i = myRand(9)-1; j = myRand(9)-1; if(squa[i][j] != 0) { squa[i][j] = 0; k++; } } } else if(diff==2) //難度為中級時(shí)有50個(gè)空格 { for(k=0; k<30;) { i = myRand(9)-1; j = myRand(9)-1; if(squa[i][j] != 0) { squa[i][j] = 0; k++; } } } else if(diff==3) //難度為中級時(shí)有70個(gè)空格 { for(k=0; k<60;) { i = myRand(9)-1; j = myRand(9)-1; if(squa[i][j] != 0) { squa[i][j] = 0; k++; } } } printf("************題目如下(0表示空格)****************\n"); fprintf(squa); printf("——————Enter鍵顯示答案——————"); fflush(stdin); //除去緩存影響 scanf("%c", &result); if(result == 10) fprintf(answ); } //**************選擇2輸入并計(jì)算一個(gè)數(shù)獨(dú)**************************** else { //*******輸入題目*********************************** printf("*********請輸入題目(空缺以0代替)**********"); printf("\n******||1*2*3*4*5*6*7*8*9\n"); for (i = 0; i < 9; i++) { printf("******%d:", i + 1); for (j = 0; j < 9; j++) { scanf("%d", &squa[i][j]); } } solve(squa, 0); //調(diào)用函數(shù)計(jì)算結(jié)果 } } //定義函數(shù)可以產(chǎn)生隨機(jī)產(chǎn)生1-9的數(shù) int myRand(int range) { srand((unsigned)time( NULL ) + index); index++; return rand()%range + 1; } //定義函數(shù)可以在root中根據(jù)元素找位置 int reRank(int root[9], int numb) { int i; for(i = 0; i < 9; i++) { if(root[i] == numb) return i; } } //解決的第一步:判斷空缺處可填數(shù)字的judge函數(shù) int judge(int squa[9][9], int m, int n, int posb) { int num, gridi, gridj; int gi = m / 3 * 3, gj = n / 3 * 3; //計(jì)算元素的宮格位置 for (num = 0; num < 9; num++) //根據(jù)行元素判斷 { if (squa[m][num] == posb) return 0; } for (num = 0; num < 9; num++) //根據(jù)列元素判斷 { if (squa[num][n] == posb) return 0; } //根據(jù)宮格元素判斷 for (gridi = gi; gridi < gi + 3; gridi++) { for (gridj = gj; gridj < gj + 3; gridj++) { if (squa[gridi][gridj] == posb) return 0; } } return 1; } //定義遞歸函數(shù)solve求得一種結(jié)果 void solve(int squa[9][9], int num) { void fprintf(int squa[9][9]); int posb; int i, j, value; int magic[9][9];//定義臨時(shí)數(shù)組 int sm,sn; sm=num/9; //計(jì)算元素行數(shù) sn=num%9; //計(jì)算元素列數(shù) //將squa中元素賦給magic for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { magic[i][j] = squa[i][j]; } } //判斷位置處元素非0 if (magic[sm][sn] != 0) { if (sm == 8 && sn == 8) //遞歸頭 { printf("————————參考結(jié)果————————\n"); fprintf(magic); } else { solve(magic, num+1); } } else //判斷位置處元素為0 { for (posb = 1; posb <= 9; posb++) { //根據(jù)判斷函數(shù)返回值決定是否賦值 value = judge(magic, sm, sn, posb); if (value) { magic[sm][sn] = posb; if (sm == 8 && sn == 8) //遞歸頭 { printf("————————參考結(jié)果————————\n"); fprintf(magic); } else { solve(magic, num+1); } magic[sm][sn] = 0; } } } } //打印數(shù)組結(jié)果函數(shù)fprintf的定義 void fprintf(int squa[9][9]) { int i,j; for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { printf("%d ", squa[i][j]); if ((j == 2) || (j == 5)) //換列時(shí)加空格 printf(" "); } printf("\n"); if ((i == 2) || (i == 5)) //換行時(shí)加換行符 { printf("\n"); } } }
讀到這里,這篇“C語言怎么實(shí)現(xiàn)數(shù)獨(dú)游戲”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。