基於第二次數獨遊戲,添加GUI界面

#include<iostream>
#include<cstdlib>
#include<ctime>
#include<fstream>
using namespace std;

ofstream ocout;
int sudo[9][9];
bool set(int x,int y,int val)
{
    if(sudo[x][y]!=0)        //非空
        return false;    
    int x0,y0;
    for(y0=0;y0<9;y0++)        //行衝突
    {
        if(sudo[x][y0]==val)
            return false;
    }
    for(x0=0;x0<9;x0++)        //列衝突  
    {
        if(sudo[x0][y]==val)
            return false;
    }
    for(x0=x/3*3;x0<x/3*3+3;x0++)        //格衝突
    {
        for(y0=y/3*3;y0<y/3*3+3;y0++)
        {
            if(sudo[x0][y0]==val)
                return false;
        }
    }
    sudo[x][y]=val;
    return true;
}

void current(int* cur)     ///0~9隨機序列
{
    int i,j,temp;
    for(int i=0;i<9;i++)
    {
        cur[i]=i;
    }
    for(int i=0;i<9;i++)
    {
        j=rand()%9;
        temp=cur[j];
        cur[j]=cur[i];
        cur[i]=temp;
    }
}

void reset(int x,int y)
{
    sudo[x][y]=0;
}

bool fill(int x,int val)
{
    int cur[9];
    current(cur);    //生成當前行的掃描序列
    for(int i=0;i<9;i++)
    {
        int y=cur[i];
        if(set(x,y,val))    //能夠先把每一行的1填了,再填每一行的2...以此類推
        {
            if(x==8)    //到了最後一行
            {
            if(val==9||fill(0,val+1))    //當前填9則結束,不然從第一行填下一個數
                return true;
            }
            else
            {
                if(fill(x+1,val))    //下一行繼續填當前數
                    return true;    
            }
            reset(x,y);        //回溯
        }
    }
    return false;
}

void digHole(int holeCnt)      //挖空
{
    int x,y;
    for(int i=0;i<2;i++)
        {
            x = rand() % 3;
            y = rand() % 3;
            while( sudo[x][y] == 0 )
            {
                x = rand() % 3;
                y = rand() % 3;
            }
            sudo[x][y]=0;
            sudo[x][y+3]=0;
            sudo[x][y+6]=0;
            sudo[x+3][y]=0;
            sudo[x+3][y+3]=0;
            sudo[x+3][y+6]=0;
            sudo[x+6][y]=0;
            sudo[x+6][y+3]=0;
            sudo[x+6][y+6]=0;
        }
    for (int  j = 0; j < holeCnt; j++ )
    {
        y = rand() % 9;
        y = rand() % 9;
        while(sudo[x][y] == 0 )
        {
            x= rand() % 9;
            y = rand() % 9;
        }
        sudo[x][y] = 0;
    }
}
void clear(int temp[9][9])    //清空
{
    for(int i=0;i<9;i++)
    {
        for(int j=0;j<9;j++)
        {
            temp[i][j]=0;
        }
    }
}

void printsudo()        //輸出到屏幕
{
    for(int x=0;x<9;x++)
    {
        (x%3==0)?(cout<<"  -----------------------\n "):(cout<<" ");
        cout<<"| ";
        for(int y=0;y<9;y++)
        {
        cout<<sudo[x][y]<<" ";
        (y%3==2)?(cout<<"| "):(cout<<"");
        }
        cout<<endl;
    }
    cout<<"  -----------------------\n"<<endl;
}

void printsudotxt()        //輸出到sudotiku.txt
{
    for(int x=0;x<9;x++)
    {
        (x%3==0)?(ocout<<"  -----------------------\n "):(ocout<<" ");
        ocout<<"| ";
        for(int y=0;y<9;y++)
        {
        ocout<<sudo[x][y]<<" ";
        (y%3==2)?(ocout<<"| "):(ocout<<"");
        }
        ocout<<endl;
    }
    ocout<<"  -----------------------\n"<<endl;
}


int main()
{
    srand((unsigned)time(NULL));    //這個是種子函數 爲rand函數提供不一樣的種子 每次運行程序產生不一樣的隨機數,否則rand函數每次運行程序產生的隨機數都是同樣的
    ocout.open("sudotiku.txt");
    cout<<"請輸入數獨棋盤題目個數N (0 < N <= 1000000):"<<endl;
    int N;
    cin>>N;
    cout<<"隨機生成"<<N<<"個不重複的已解答完畢的數獨棋盤以下:"<<endl;
    ocout << "隨機生成"<<N<<"個不重複的已解答完畢的數獨棋盤以下:" << endl;
    for(int i=0;i<N;i++)
    {
        clear(sudo);
        while(!fill(0,1));
        digHole(rand()%31+30);
        printsudo();
        printsudotxt();
    }
    ocout.close();
    return 0;
}

 輸入:數獨棋盤題目個數N (0 < N <= 1000000)ios

 
 

 輸出:隨機生成N個不重複有惟一解的數獨棋盤。挖空處用數字0表示,每一個數獨棋盤中至少要有30個以上的0。每一個棋盤隔一行,輸出須要到文件sudotiku.txt中。git

  基於第二次數獨遊戲,添加GUI界面,實現如下功能: 函數

  1. 生成任意數量的數獨題目並將數獨棋局依次顯示,棋盤上總空格數大於30,小於60,每3*3小棋盤中挖空很多於2個。
  2. 數獨題目有且僅有惟一解。
  3. 用戶能夠在界面上經過編輯輸入完成數獨題目。
  4. 用戶完成數獨題目後能夠獲得正確性反饋。
  5. 友好的使用說明。
 
 
關於GUI界面的代碼,已上傳到Coding,網址:https://coding.net/u/dhlg_201810812001/p/sudo/git

生成數獨的GUI界面以下所示:



點擊自動計算數獨結果,就會生成數獨的惟一解,結果以下:


 
 
經測試,程序能夠正確運行,但如上游戲信息所提示,計算結果最多隻能保存1000個,有必定的侷限性,還需繼續完善。
此次做業相比上次而言,有必定的難度。關於GUI界面,因爲使用不是很熟練,因此只能參考別人的代碼來進行實現,我搜集了CSDN中關於數獨的一些代碼,對於經過MFC來進行繪圖這塊因爲以前沒有接觸過,因此只能借鑑別人的,遇到不懂的語句再去百度,經過不斷學習,對其結構有了必定的理解,達到了可以看懂的地步,但要想本身作出一個界面仍是有必定困難。
整個做業的完成花費了大量時間,大概有一個星期左右,主要是由於對於MFC的使用不熟練,經過本次做業的完成,我又掌握了一項新的技能——MFC的使用,爲之後深刻的學習奠基了一些基礎。
相關文章
相關標籤/搜索