zoukankan      html  css  js  c++  java
  • 基于MFC:一个没有经验的数独游戏

    1,coding地址:https://git.coding.net/dhlg_201810812002/SudokuGUI.git 

    #pragma once
    #include "fstream"
    using namespace std;
    class ChessBoard
    {
    public:
        ChessBoard();
        ~ChessBoard();
        int*  getExchangedNum();
        ofstream& printChessBoard(ofstream &);
        void exchange();
    private:
        int exchangedNum[9];//已经交换过的数
        int enumNum[9];
        int chessBoardRelationship[9][9];
    };
    // MFCApplication3.h : PROJECT_NAME 应用程序的主头文件
    //
    
    #pragma once
    
    #ifndef __AFXWIN_H__
        #error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
    #endif
    
    #include "resource.h"        // 主符号
    
    
    // CMFCApplication3App: 
    // 有关此类的实现,请参阅 MFCApplication3.cpp
    //
    
    class CMFCApplication3App : public CWinApp
    {
    public:
        CMFCApplication3App();
    
    // 重写
    public:
        virtual BOOL InitInstance();
    
    // 实现
    
        DECLARE_MESSAGE_MAP()
    };
    
    extern CMFCApplication3App theApp;
    // MFCApplication3Dlg.h : 头文件
    //
    
    #pragma once
    
    
    // CMFCApplication3Dlg 对话框
    class CMFCApplication3Dlg : public CDialogEx
    {
    // 构造
    public:
        CMFCApplication3Dlg(CWnd* pParent = NULL);    // 标准构造函数
    
    // 对话框数据
        enum { IDD = IDD_MFCAPPLICATION3_DIALOG };
    
        protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    
    
    // 实现
    protected:
        HICON m_hIcon;
    
        // 生成的消息映射函数
        virtual BOOL OnInitDialog();
        afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
        afx_msg void OnPaint();
        afx_msg HCURSOR OnQueryDragIcon();
        DECLARE_MESSAGE_MAP()
    public:
        afx_msg void OnBnClickedButton1();
        afx_msg void OnBnClickedButton2();
    };
    #pragma once
    #include "MFCApplication3.h"
    #include "MFCApplication3Dlg.h"
    #include "afxdialogex.h"
    class Question
    {
    public:
        Question();
        ~Question();
        char temp[81];//从文件中读取的数据
        unsigned flg[80];//应该写入问题的数据
    
    };
    #include "stdafx.h"
    #include "ChessBoard.h"
    #include "iostream"
    #include <stdlib.h>
    #include<windows.h>
    #include "fstream"
    using namespace std;
    ChessBoard::ChessBoard()
    {
        int init[9][9] = {
                { 1, 2, 3, 5, 6, 7, 9, 4, 8 },
                { 4, 5, 6, 8, 9, 1, 3, 7, 2 },
                { 7, 8, 9, 2, 3, 4, 6, 1, 5 },
                { 9, 4, 8, 1, 2, 3, 5, 6, 7 },
                { 3, 7, 2, 4, 5, 6, 8, 9, 1 },
                { 6, 1, 5, 7, 8, 9, 2, 3, 4 },
                { 5, 6, 7, 9, 4, 8, 1, 2, 3 },
                { 8, 9, 1, 3, 7, 2, 4, 5, 6 },
                { 2, 3, 4, 6, 1, 5, 7, 8, 9 }
        };
        for (int i = 0; i < 9; i++){
            for (int j = 0; j < 9; j++){
                chessBoardRelationship[i][j] = init[i][j];
            }
        }
        exchange();
    }
    void ChessBoard::exchange(){
        for (int i = 0; i < 9; i++){
            enumNum[i] = i + 1;
        }
        int p = 0;
        for (int i = 0; i < 9; i++){
    
            LARGE_INTEGER nFrequency;
            if (::QueryPerformanceFrequency(&nFrequency))
            {
                LARGE_INTEGER nStartCounter;
                ::QueryPerformanceCounter(&nStartCounter);
                ::srand((unsigned)nStartCounter.LowPart);
            }
    
            p = rand() % (9 - i);
            exchangedNum[i] = enumNum[p];
            enumNum[p] = enumNum[8 - i];
        }
    }
    ChessBoard::~ChessBoard()
    {
    }
    int* ChessBoard::getExchangedNum(){
        return &(exchangedNum[0]);
    }
    ofstream & ChessBoard::printChessBoard(ofstream &file){
        int count = 0;
        int count1 = 0;
        for (int i = 0; i < 9; i++){
            for (int j = 0; j < 9; j++){
                //            cout << exchangedNum[chessBoardRelationship[i][j] - 1] << " ";
                file << exchangedNum[chessBoardRelationship[i][j] - 1] << " ";
                count++;
                if (count % 3 == 0){
                    //                cout << "   ";
                    file << "   ";
                }
            }
            count1++;
            if (count1 % 3 == 0){
                //            cout << endl;
                file << endl;
            }
            //        cout << endl;
            file << endl;
        }
        return file;
    }
    // MFCApplication3.cpp : 定义应用程序的类行为。
    //
    
    #include "stdafx.h"
    #include "MFCApplication3.h"
    #include "MFCApplication3Dlg.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    
    
    // CMFCApplication3App
    
    BEGIN_MESSAGE_MAP(CMFCApplication3App, CWinApp)
        ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
    END_MESSAGE_MAP()
    
    
    // CMFCApplication3App 构造
    
    CMFCApplication3App::CMFCApplication3App()
    {
        // 支持重新启动管理器
        m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
    
        // TODO:  在此处添加构造代码,
        // 将所有重要的初始化放置在 InitInstance 中
    }
    
    
    // 唯一的一个 CMFCApplication3App 对象
    
    CMFCApplication3App theApp;
    
    
    // CMFCApplication3App 初始化
    
    BOOL CMFCApplication3App::InitInstance()
    {
        // 如果一个运行在 Windows XP 上的应用程序清单指定要
        // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
        //则需要 InitCommonControlsEx()。  否则,将无法创建窗口。
        INITCOMMONCONTROLSEX InitCtrls;
        InitCtrls.dwSize = sizeof(InitCtrls);
        // 将它设置为包括所有要在应用程序中使用的
        // 公共控件类。
        InitCtrls.dwICC = ICC_WIN95_CLASSES;
        InitCommonControlsEx(&InitCtrls);
    
        CWinApp::InitInstance();
    
    
        AfxEnableControlContainer();
    
        // 创建 shell 管理器,以防对话框包含
        // 任何 shell 树视图控件或 shell 列表视图控件。
        CShellManager *pShellManager = new CShellManager;
    
        // 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题
        CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
    
        // 标准初始化
        // 如果未使用这些功能并希望减小
        // 最终可执行文件的大小,则应移除下列
        // 不需要的特定初始化例程
        // 更改用于存储设置的注册表项
        // TODO:  应适当修改该字符串,
        // 例如修改为公司或组织名
        SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
    
        CMFCApplication3Dlg dlg;
        m_pMainWnd = &dlg;
        INT_PTR nResponse = dlg.DoModal();
        if (nResponse == IDOK)
        {
            // TODO:  在此放置处理何时用
            //  “确定”来关闭对话框的代码
        }
        else if (nResponse == IDCANCEL)
        {
            // TODO:  在此放置处理何时用
            //  “取消”来关闭对话框的代码
        }
        else if (nResponse == -1)
        {
            TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。
    ");
            TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。
    ");
        }
    
        // 删除上面创建的 shell 管理器。
        if (pShellManager != NULL)
        {
            delete pShellManager;
        }
    
        // 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
        //  而不是启动应用程序的消息泵。
        return FALSE;
    }
    // MFCApplication3Dlg.cpp : 实现文件
    //
    
    #include "stdafx.h"
    #include "MFCApplication3.h"
    #include "MFCApplication3Dlg.h"
    #include "afxdialogex.h"
    #include "Question.h"
    
    
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    
    
    // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
    
    class CAboutDlg : public CDialogEx
    {
    public:
        CAboutDlg();
    
    // 对话框数据
        enum { IDD = IDD_ABOUTBOX };
    
        protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    
    // 实现
    protected:
        DECLARE_MESSAGE_MAP()
    };
    
    CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
    {
    }
    
    void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialogEx::DoDataExchange(pDX);
    }
    
    BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
    END_MESSAGE_MAP()
    
    
    int que[81];//全局变量
    unsigned hwnd[81] = { IDC_EDIT1, IDC_EDIT2, IDC_EDIT3, IDC_EDIT4, IDC_EDIT5, IDC_EDIT6, IDC_EDIT7, IDC_EDIT8, IDC_EDIT9, IDC_EDIT10, IDC_EDIT11, IDC_EDIT12, IDC_EDIT13, IDC_EDIT14, IDC_EDIT15, IDC_EDIT16, IDC_EDIT17, IDC_EDIT18, IDC_EDIT19, IDC_EDIT20, IDC_EDIT21, IDC_EDIT22, IDC_EDIT23, IDC_EDIT24, IDC_EDIT25, IDC_EDIT26, IDC_EDIT27, IDC_EDIT28, IDC_EDIT29, IDC_EDIT30, IDC_EDIT31, IDC_EDIT32, IDC_EDIT33, IDC_EDIT34, IDC_EDIT35, IDC_EDIT36, IDC_EDIT37, IDC_EDIT38, IDC_EDIT39, IDC_EDIT40, IDC_EDIT41, IDC_EDIT42, IDC_EDIT43, IDC_EDIT44, IDC_EDIT45, IDC_EDIT46, IDC_EDIT47, IDC_EDIT48, IDC_EDIT49, IDC_EDIT50, IDC_EDIT51, IDC_EDIT52, IDC_EDIT53, IDC_EDIT54, IDC_EDIT55, IDC_EDIT56, IDC_EDIT57, IDC_EDIT58, IDC_EDIT59, IDC_EDIT60, IDC_EDIT61, IDC_EDIT62, IDC_EDIT63, IDC_EDIT64, IDC_EDIT65, IDC_EDIT66, IDC_EDIT67, IDC_EDIT68, IDC_EDIT69, IDC_EDIT70, IDC_EDIT71, IDC_EDIT72, IDC_EDIT73, IDC_EDIT74, IDC_EDIT75, IDC_EDIT76, IDC_EDIT77, IDC_EDIT78, IDC_EDIT79, IDC_EDIT80, IDC_EDIT81 };
    
    
    // CMFCApplication3Dlg 对话框
    
    
    
    CMFCApplication3Dlg::CMFCApplication3Dlg(CWnd* pParent /*=NULL*/)
        : CDialogEx(CMFCApplication3Dlg::IDD, pParent)
    {
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }
    
    void CMFCApplication3Dlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialogEx::DoDataExchange(pDX);
    }
    
    BEGIN_MESSAGE_MAP(CMFCApplication3Dlg, CDialogEx)
        ON_WM_SYSCOMMAND()
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        ON_BN_CLICKED(IDC_BUTTON1, &CMFCApplication3Dlg::OnBnClickedButton1)
        ON_BN_CLICKED(IDC_BUTTON2, &CMFCApplication3Dlg::OnBnClickedButton2)
    END_MESSAGE_MAP()
    
    
    // CMFCApplication3Dlg 消息处理程序
    
    BOOL CMFCApplication3Dlg::OnInitDialog()
    {
        CDialogEx::OnInitDialog();
    
        // 将“关于...”菜单项添加到系统菜单中。
    
        // IDM_ABOUTBOX 必须在系统命令范围内。
        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
        ASSERT(IDM_ABOUTBOX < 0xF000);
    
        CMenu* pSysMenu = GetSystemMenu(FALSE);
        if (pSysMenu != NULL)
        {
            BOOL bNameValid;
            CString strAboutMenu;
            bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
            ASSERT(bNameValid);
            if (!strAboutMenu.IsEmpty())
            {
                pSysMenu->AppendMenu(MF_SEPARATOR);
                pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
            }
        }
    
        // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
        //  执行此操作
        SetIcon(m_hIcon, TRUE);            // 设置大图标
        SetIcon(m_hIcon, FALSE);        // 设置小图标
    
        // TODO:  在此添加额外的初始化代码
    
        return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
    }
    
    void CMFCApplication3Dlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
        if ((nID & 0xFFF0) == IDM_ABOUTBOX)
        {
            CAboutDlg dlgAbout;
            dlgAbout.DoModal();
        }
        else
        {
            CDialogEx::OnSysCommand(nID, lParam);
        }
    }
    
    // 如果向对话框添加最小化按钮,则需要下面的代码
    //  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
    //  这将由框架自动完成。
    
    void CMFCApplication3Dlg::OnPaint()
    {
        if (IsIconic())
        {
            CPaintDC dc(this); // 用于绘制的设备上下文
    
            SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
    
            // 使图标在工作区矩形中居中
            int cxIcon = GetSystemMetrics(SM_CXICON);
            int cyIcon = GetSystemMetrics(SM_CYICON);
            CRect rect;
            GetClientRect(&rect);
            int x = (rect.Width() - cxIcon + 1) / 2;
            int y = (rect.Height() - cyIcon + 1) / 2;
    
            // 绘制图标
            dc.DrawIcon(x, y, m_hIcon);
        }
        else
        {
            CDialogEx::OnPaint();
        }
    }
    
    //当用户拖动最小化窗口时系统调用此函数取得光标
    //显示。
    HCURSOR CMFCApplication3Dlg::OnQueryDragIcon()
    {
        return static_cast<HCURSOR>(m_hIcon);
    }
    
    
    
    void CMFCApplication3Dlg::OnBnClickedButton1()
    {
        // TODO:  在此添加控件通知处理程序代码
        Question Q;
    
        for (int i = 0; i < 81; i++){
            que[i] = Q.temp[i] - 48;
            SetDlgItemInt(hwnd[i], Q.flg[i], true);
        }
    }
    
    
    void CMFCApplication3Dlg::OnBnClickedButton2()
    {
        // TODO:  在此添加控件通知处理程序代码
        int answer[81];
        int judge = 0;
        for (int i = 0; i < 81; i++){
            answer[i] = GetDlgItemInt(hwnd[i], NULL, true);
            if (answer[i] != que[i]){
                judge = 1;
            }
            if (answer[i] == 0){
                judge = 2; break;
            }
        }
        
        if (judge == 1)MessageBox(TEXT("答案错误"), TEXT("警告"), 0);
        if (judge == 2)MessageBox(TEXT("没有填完"), TEXT("警告"), 0);
        if (judge == 0)MessageBox(TEXT("恭喜你,回答正确"), TEXT("提示"), 0);
        /*switch (judge)
        {
        case 1:MessageBox(TEXT("答案错误"), TEXT("警告"), 0);break;
        case 2:MessageBox(TEXT("没有填完"), TEXT("警告"), 0);
        default:
            break;
        }*/
    }
    #include "stdafx.h"
    #include "Question.h"
    #include "MFCApplication3.h"
    #include "MFCApplication3Dlg.h"
    #include "afxdialogex.h"
    #include "ChessBoard.h"
    
    Question::Question()
    {
        ChessBoard CB;
        int bn = 0;//board number
        //    string s = argv[2];
        //stringstream ss;
        //    ss << s;
        //    ss >> bn;
        bn = 1;
        ofstream file("sudotiku.txt");
        for (int i = 0; i < bn; i++){
            CB.printChessBoard(file);
            CB.exchange();
            file << endl;
        }
        file.close();
        //cout << "执行完毕,请检查";
        //system("pause");
    
        ifstream infile("sudotiku.txt");
        //char temp[81];
        int c = 0;
        while (!infile.eof())
        {
            infile >> temp[c];
            //        cout << temp[c];
            c++;
            if (c > 80)break;
        }
        // TODO:  在此添加控件通知处理程序代码
        //SetWindowText(;
        //CWnd *pWnd = AfxGetMainWnd();//获取会话框指针
        //HWND hHwnd = pWnd->m_hWnd;//获取窗口句柄
        //int ce = GetDlgItemInt( IDC_EDIT1, NULL, true);
        //unsigned int flg[80];
        for (int i = 0; i < 81; i++){
            LARGE_INTEGER nFrequency;
            if (::QueryPerformanceFrequency(&nFrequency))
            {
                LARGE_INTEGER nStartCounter;
                ::QueryPerformanceCounter(&nStartCounter);
                ::srand((unsigned)nStartCounter.LowPart);
            }
            if (rand() % 9 < 4){
                flg[i] = 0;
            }
            else{
                flg[i] = temp[i] - 48;
            }
        }
        //unsigned hwnd[81] = { IDC_EDIT1, IDC_EDIT2, IDC_EDIT3, IDC_EDIT4, IDC_EDIT5, IDC_EDIT6, IDC_EDIT7, IDC_EDIT8, IDC_EDIT9, IDC_EDIT10, IDC_EDIT11, IDC_EDIT12, IDC_EDIT13, IDC_EDIT14, IDC_EDIT15, IDC_EDIT16, IDC_EDIT17, IDC_EDIT18, IDC_EDIT19, IDC_EDIT20, IDC_EDIT21, IDC_EDIT22, IDC_EDIT23, IDC_EDIT24, IDC_EDIT25, IDC_EDIT26, IDC_EDIT27, IDC_EDIT28, IDC_EDIT29, IDC_EDIT30, IDC_EDIT31, IDC_EDIT32, IDC_EDIT33, IDC_EDIT34, IDC_EDIT35, IDC_EDIT36, IDC_EDIT37, IDC_EDIT38, IDC_EDIT39, IDC_EDIT40, IDC_EDIT41, IDC_EDIT42, IDC_EDIT43, IDC_EDIT44, IDC_EDIT45, IDC_EDIT46, IDC_EDIT47, IDC_EDIT48, IDC_EDIT49, IDC_EDIT50, IDC_EDIT51, IDC_EDIT52, IDC_EDIT53, IDC_EDIT54, IDC_EDIT55, IDC_EDIT56, IDC_EDIT57, IDC_EDIT58, IDC_EDIT59, IDC_EDIT60, IDC_EDIT61, IDC_EDIT62, IDC_EDIT63, IDC_EDIT64, IDC_EDIT65, IDC_EDIT66, IDC_EDIT67, IDC_EDIT68, IDC_EDIT69, IDC_EDIT70, IDC_EDIT71, IDC_EDIT72, IDC_EDIT73, IDC_EDIT74, IDC_EDIT75, IDC_EDIT76, IDC_EDIT77, IDC_EDIT78, IDC_EDIT79, IDC_EDIT80, IDC_EDIT81 };
    }
    
    
    Question::~Question()
    {
    }
    
    
    //char* getFlg();
    //unsigned* getHwnd();
    说明:以上均只给出已经修改的文件,未改动的文件由visual studio2013自动生成MFC窗口。
    2,运行截图
    出题:

    未填写完毕:

    答案错误

     

    答案正确:

    3,心得 

    作为一个不但没有任何MFC基础,甚至连C++都没有学完的人,我一度被逼到无法按时完成要去写一个字符“UI”来代替“GUI”的地步。因为先期程序是C++实现的,所以我不得不继续下去,所采用的方法看起来也十分没有逻辑,完全是基于曾经对AWT的学习,所形成的逻辑,遇到问题后查阅相应资料解决。但这不是重点,最终,还是完成了题目规定的所有要求,本次经历最深刻的感受是,你永远无法保证自己能够了解所有问题,学会向他人学习是很有必要的。此外深感对于C++语言的了解太少,对于一门大型的语言来说,你可能无法精通所有的细节,但是你必须了解其基本方向、结构和功能,对于MFC,目前对我来说一本入门教材已经很值得研究了。

    4,性能分析:

    本程序可以秒出题目和答案判断,由于每次只进行一次运算棋盘并依据这个已解答的棋盘出题,所需要的计算量非常小,加上写入文件进行记录和从文件中读取的时间,这些开销也是微不足道的。我们整体的过程是,首先生成一个已经解答的棋盘,将它存储到文件中,再从文件中读取出来,使用随机数控制提示数输出到对话框中,用户填完,进行判断,可是,这些过程并不是一气呵成的,我们必须注意有些地方系统必须停下来等待用户输入。单单从程序响应速度来说,这没有问题,但是本程序并不完美,其界面没有经过任何美化,限于本人水平,也没有完全取消无用的按钮,执行生成题目时有一个异常没有抛出,但是不影响我们忽略它,继续生成正确的题目。

  • 相关阅读:
    Java:类与继承(隐藏和覆盖的问题)
    Java中的static关键字解析
    面向对象(Java中普通代码块,构造代码块,静态代码块区别及代码示例)
    面向对象要点(this关键字)
    急须知道postman RSA加密的方式
    RSA加密原理
    postman获取变量
    Mysql通过cmd访问
    一个简单的postman实例
    sum(coalesce(adjust_value,prediction_value))
  • 原文地址:https://www.cnblogs.com/XieJingcheng/p/9794733.html
Copyright © 2011-2022 走看看