溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C語言怎么實(shí)現(xiàn)數(shù)獨(dú)游戲

發(fā)布時(shí)間:2022-03-24 16:27:46 來源:億速云 閱讀:413 作者:iii 欄目:開發(fā)技術(shù)

本文小編為大家詳細(xì)介紹“C語言怎么實(shí)現(xiàn)數(shù)獨(dú)游戲”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“C語言怎么實(shí)現(xiàn)數(shù)獨(dú)游戲”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。

目標(biāo)

寫一個(gè)數(shù)獨(dú)游戲,有以下功能:

1:能隨機(jī)產(chǎn)生題目并給出答案。

2:求解輸入的題目并輸出答案。

實(shí)現(xiàn)說明

參照百度百科等資料可以知道求解數(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í)現(xiàn)數(shù)獨(dú)游戲

C語言怎么實(shí)現(xiàn)數(shù)獨(dú)游戲

代碼:

語言: 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è)資訊頻道。

向AI問一下細(xì)節(jié)

免責(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)容。

AI