基于第二次数独游戏,添加GUI界面

 根据题目要求,由于我第二次作业写得代码没有类,不好调用函数,所以 基于第二次写数独的思想代码进行了重写改动。

Su1.cpp代码(数独代码)

#include "stdafx.h"
#include "Su.h"
#include "Su1.h"

#include <iostream>
#include <ctime>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

CSu::CSu()
{
    int i,j;
    for(i=1;i<10;i++)
        for(j=1;j<10;j++)
            map[i][j] = 0;
}

CSu::CSu(int n) //随机生成n个数字
{
    int i,j;
    for(i=1;i<10;i++)
        for(j=1;j<10;j++)
            map[i][j] = 0;
    srand((unsigned)time(0));

    //每行初始一个
    do
    {
        for(i=1;i<10;i++)
        {
            j = rand()%10;
            map[i][j] = i;
        }
        
    }while (!Check());

    Solve();//填好
    //挖空
    int k = 0; 
    while(1)
    {
        i=rand()%81;
        j=i%9;
        i=i/9;    
        int x = map[i+1][j+1];
        if(x>0)
        {
            map[i+1][j+1] = 0;
            k++;
        }
        if(k == 81-n)
            break;
    }
    
}

CSu::CSu(int data[9][9])
{
    int i,j;
    for(i=1;i<10;i++)
        for(j=1;j<10;j++)
            map[i][j] = data[i-1][j-1];
}

CSu::~CSu()
{
    return;
}


bool CSu::Check()
{
    memset(sqr,false,sizeof(sqr));
    memset(row,false,sizeof(sqr));
    memset(col,false,sizeof(sqr));
    int i,j;

    for(i=1;i<10;i++)
        for(j=1;j<10;j++)
        {
            int temp = map[i][j];
            if( temp != 0)
            {
                if( !row[i][temp] )
                    row[i][temp] = true;
                else 
                    return false;

                if( !col[j][temp])
                    col[j][temp] = true;
                else 
                    return false;

                if( !sqr[(i-1)/3*3+(j-1)/3+1][temp] )
                    sqr[(i-1)/3*3+(j-1)/3+1][temp] = true;
                else
                    return false;
            }
        }
    return true;
}

bool CSu::Solve()
{
    int i,j;
    memset(sqr,false,sizeof(sqr));
    memset(row,false,sizeof(sqr));
    memset(col,false,sizeof(sqr));
    for(i=1;i<=9;i++)
        for(j=1;j<=9;j++)
        {
            if(map[i][j]!=0)
            {
                row[i][map[i][j]]=true;
                col[j][map[i][j]]=true;
                //小正方形被标志为1--9;
                sqr[(i-1)/3*3+(j-1)/3+1][map[i][j]]=true;
            }
        }
    bool ans = DFS();
    return ans;
}


bool CSu::DFS()
{
    int i,j,k;
    for(i=1;i<10;i++)
        for(j=1;j<10;j++)
        {
            if(map[i][j]==0)
            {
                for(k=1;k<=9;k++)
                {
                    if(!row[i][k]&&!col[j][k]&&!sqr[(i-1)/3*3+(j-1)/3+1][k])
                    {
                        map[i][j]=k;
                        row[i][k]=true;
                        col[j][k]=true;
                        sqr[(i-1)/3*3+(j-1)/3+1][k]=true;
                        if(DFS())
                            return true;
                        else
                        {
                            map[i][j]=0;
                            row[i][k]=false;
                            col[j][k]=false;
                            sqr[(i-1)/3*3+(j-1)/3+1][k]=false;
                        }
                    }
                }
                if(k==10)return false;
            }
        }
        return true;
}

Su1.h代码

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CSu  
{
public:
    CSu();
    CSu(int n); //随机生成数独,n个空格含有数字
    CSu(int data[9][9]);
    virtual ~CSu();
    bool Check();
    bool Solve();
    bool DFS();
    int map[10][10];

private:

    bool row[10][10],col[10][10],sqr[10][10];
    


};

#endif 

添加数独题目按钮代码

void CSuDlg::OnButton1() //数独题目按钮
{
    // TODO: Add your control notification handler code here
        int i,j;
    for(i=0;i<81;i++)
    {
        c[i].SetWindowText("0");
        c[i].EnableWindow(1);
    }
    CSu  s(40);
    char str[5];
    int count = 0;
    for(i=1;i<=9;i++)
        for(j=1;j<=9;j++)
        {
            str[0]=s.map[i][j]+'0';
            str[1]='\0';
            c[count].SetWindowText(str);
            if(s.map[i][j]!=0)
                c[count].EnableWindow(0);
            count++;
        }
}

添加解数独按钮代码

void CSuDlg::OnButton2() //解数独按钮
{
    // TODO: Add your control notification handler code here
    
int i,j;
    int result[9][9];
    char buf[5];
    for(i=0;i<81;i++)
    {
        c[i].GetLine(0,buf,5);
        
        int x = atoi(buf);
        
        int l,c,temp;
        temp = i;
        l = temp/9;
        c = temp%9;
        result[l][c] = x;
    }
    
    CSu s(result);
    s.Solve();

    char str[5];
    int count = 0;
    for(i=1;i<=9;i++)
        for(j=1;j<=9;j++)
        {
            str[0]=s.map[i][j]+'0';
            str[1]='\0';
            c[count].SetWindowText(str);

            count++;
        }
    
}

确定按钮代码

void CSuDlg::OnOK() //确定按钮
{
    // TODO: Add extra validation here
    int i;
    int result[9][9];
    char buf[5];
    for(i=0;i<81;i++)
    {
        c[i].GetLine(0,buf,5);
        int x = atoi(buf);
        if(x==0)
        {
            AfxMessageBox("没有填完!!");
            return;
        }
        if(x<0 || x>9)
        {
            AfxMessageBox("请填入0--9以内的数字!!");
            return;
        }
        int l,c,temp;
            
            temp = i;
        l = temp/9;
        c = temp%9;
        result[l][c] = x;
    }
    
    CSu s(result);
    if(s.Check())
        AfxMessageBox("祝贺,成功完成!");
    else 
        AfxMessageBox("很遗憾,解答错误!");

    CDialog::OnOK();
}

程序运行能够出正确结果,如下图:(分别是一开始运行出来的界面,然后是单击“题目“”出现的数独题目,最后是单击“”解数独“”后出现的唯一解数独)

               

 

完整的代码可在https://coding.net/u/dhlg201810812010/p/Su/git查看

 

遇到的问题:

1.不知道怎么建立GUI界面,想起在大学的时候之前用VC++6.0可以自动生成GUI界面,于是就用VC++6.0建立了一个基于“MFC AppWizard[exe]”"基本对话框“”项目工程,建立完成后可以在"Resources"下的"IDD_SU_DIALOG"加控件,对控件也可以进行重命名,形成一个GUI界面,如图:

再往控件加相应的代码。

2.Debug/Su.pch:No such  file or dictory(即找不到预编译文件) (解决办法:对StaAfx.cpp文件重新编译下)

3.在SuDlg.cpp文件编译的时候CSu s(40)报错,提示CSu没有定义类型 (解决办法:在该文件下加入 #include “Su1.h”,因为在Su1.h该文件对CSu有定义)

4.不知道该怎么把第二次作业写的数独代码和这次关联起来,一开始是想这次建个MFC AppWizard[dill]动态调用第二次写的代码,但是我不会,所以就建立了MFC AppWizard[exe]项目工程,然后在头文件新建一个Su1.cpp文件,在源文件新建立Su1.h文件,在这两文件写入之前作业的代码。

心得体会:

这次的作业我觉得难度挺大的,整个作业做下来花费了40个小时,做这个作业曾n次想放弃,然后室友说不能放弃,要坚持到底,然后就开始又硬着头皮开始查资料,思考,和同学交流,虽然这次做作业的过程是挺痛苦的,但是最后整个作业下来收获也是挺大的,从一开始不会创建GUI界面,到会创建GUI界面,会接控件,会给加的控件重命名,给控件加代码实现想要达到的功能,同时这个作业做下来对C++的面向对象与可视化程序设计也有了个更深层次的了解,也重拾了c++里的类、派生和函数调用知识。对自己遇到困难坚持下去的毅力也得到了锻炼,知道了交流的重要性,不能自己蒙着头做,学会交流,在交流中进步。

posted @ 2018-10-14 20:32  默存1  阅读(305)  评论(1编辑  收藏  举报