主要功能描述:

运行程序后对话框会显示一个9x9的待输入数独区域,并提供随机生成数独和生成数独按钮,生成数独按钮后会创建数独并随机显示其中一个至数独区域,随机生成数独会从已生成的数独中随机获取一个并显示至界面,目前只是框架功能。

主要用到的类功能如下:

SudukuFile,数独与文件之间的存取类,提供写接口与读接口。

Suduku ,数独的生成与处理类,提供CreateSuduku,set与get数独元素,get随机数独的接口。

DrawPad ,数独绘制类,绘制数独矩形区域的边框,绘制数独的数字,接受dlg的单击消息产生可编辑框并依据编辑框输入值改变数独显示。

dlg,MFC的dlg派生类,初始化按钮、边框等对话框属性。

SudukuFile类文件操作函数如下:

bool SudukuFile::WriteSudukuToFile(int data[9][9], char* filename)

{
//目的不明确导致的含糊函数,这里需要的是指针不为NULL且文件不存在

if(!CheckFileStatus(filename, FILE_NOT_EXIT))

return false;

FILE* writefile;

int err = fopen_s(&writefile, filename, "w");

if(err != 0)

{
return false;
}

strncpy_s(m_filelist[curindex], MAX_FILENAME, filename, strlen(filename));

curindex++;

int offset = '1' - 1;

for(int r = 0; r < 9; r++)

{

for(int c = 0; c < 9; c++)

{

fputc(data[r][c] + offset, writefile);

}

fputc('\n', writefile);

}

fclose(writefile);

return true;

}

bool SudukuFile::GetSudukuFromFile(char* filename, int data[9][9])

{

//需要文件指针不为NULL,且文件存在,解决方法:扩展参数,判断目的

if(!CheckFileStatus(filename, FILE_EXIT))

return false;

FILE* readfile;
int err = fopen_s(&readfile, filename, "r");

if(err != 0)

{
return false;
}

int result = 0;

int offset = '1' - 1;

for(int r = 0; r < 9; r++)

{

for(int c = 0; c < 9; c++)

{

if((result = fgetc(readfile)) != EOF)

{
data[r][c] = result - offset;
}

}

if((result = fgetc(readfile)) == '\n')

{
continue;
}

else

{
fclose(readfile);
return false;
}

}

fclose(readfile);

return true;

}

Suduku类增加了严谨suduku判断,即每一个3x3的区域都是1-9.

bool Suduku::CheckRigorousSuduku(int r, int c)

{

for(int po = 1; po <= 9; po++)

{

int ret = false;

for(int row = r; row < r + 3; row++)

{

for(int col = c; col < r + 3; col++)

{

if(m_chess[row][col] == po)

ret = true;

}

}

if(ret == false)

return ret;

}

return true;

}

DrawPad类主要函数,重载了picture控件的OnPaint函数用来绘制数独的矩形边框,OnPaint函数还会调用Draw函数来绘制数独矩形的背景和数字;Draw函数遍历9x9的数独格子来绘制对应的背景和数字;重载了OnLButtonDown函数来接受对话框传来的单击消息,收到单击消息后会创建一个可供输入的编辑框;重载了OnEnChangeText,当编辑框的数值发生改变时会调用该函数将输入数值传给suduku;这里需要注意的是:OnEnChangeText需要手动与编辑框控件关联。

void DrawPad::OnPaint()

{

CPaintDC dc(this);

// device context for painting

CPen red10pen(PS_DOT, 10, #ff0000);

dc.SelectObject(red10pen);

CRect rect;

GetClientRect(rect);

dc.Rectangle(rect);

m_height = (rect.bottom - rect.top - 28)/9;

m_weight = (rect.right - rect.left - 28)/9;

CPen red2pen(PS_DOT, 2, #ff0000);

CPen red4pen(PS_DOT, 4, #ff0000);

dc.SelectObject(red4pen);

dc.Rectangle(rect.left+10, rect.top+10, rect.right-10, rect.bottom-10);

dc.SelectObject(red2pen);

for(int row = 0; row < 9; row++)

{

for(int col = 0; col < 9; col++)

{

int left = col * m_weight+1 + 17;

int top = row * m_height+1 + 14;

int bottom = (row + 1) * m_height - 2 + 14;

int right = (col + 1) * m_weight - 2 + 17;

CRect rect;

rect.bottom = bottom;

rect.left = left;

rect.right = right;

rect.top = top;

dc.Rectangle(rect);

}

}

Initialize();

Draw();

// TODO: 在此处添加消息处理程序代码

// 不为绘图消息调用

CStatic::OnPaint()

}

void DrawPad::OnLButtonDown(UINT nFlags, CPoint point)

{

// TODO: 在此添加消息处理程序代码和/或调用默认值

GetRowCol(point);

Initialize();

if(m_edit != NULL)

delete m_edit;

m_edit = new CEdit;

m_edit->Create(ES_CENTER, m_rect[m_row][m_col], this, IDC_INPUT);
m_edit->SetFont(&m_font);
m_edit->SetFocus();
m_edit->ShowWindow(true);
CStatic::OnLButtonDown(nFlags, point);

}

void DrawPad::OnEnChangeText()

{

CString str;

m_edit->GetWindowTextW(str);

m_suduku.Set(m_row, m_col, _ttoi(str));

}

void DrawPad::Draw()

{

CDC *pDC = GetDC();

for(int r = 0; r < 9; r++)

{

for(int c = 0; c < 9; c++)

{

pDC->FillSolidRect(m_rect[r][c], #850000);

if(m_suduku.Get(r, c) != 0)

{

CString str;

str.Format(_T("%d"),m_suduku.Get(r, c));

CFont font = CFont();

font.CreateFontW(40, 0, 0, 0, FW_BOLD, FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_SWISS, _T("Arival"));

pDC->SelectObject(&font);

pDC->DrawText(str, m_rect[r][c],DT_CENTER|DT_VCENTER|DT_SINGLELINE);

}

}

}

}

消息关联方法:ON_EN_CHANGE(IDC_INPUT, &DrawPad::OnEnChangeText)

CXDoctorDlg类中重载了OnLButtonDown,判断游戏是否开始,如果游戏开始,且点击区域为picture控件时向picture发送左键单击消息。

void CXDoctorDlg::OnLButtonDown(UINT nFlags, CPoint point)

{

// TODO: 在此添加消息处理程序代码和/或调用默认值

CRect rect;

m_DrawPad.GetWindowRect(&rect);

ScreenToClient(rect);

if(!rect.PtInRect(point))

{
return;
}

int x = point.x - rect.left;

int y = point.y - rect.top;

if(m_start)

{

m_DrawPad.SetFocus();

m_DrawPad.SendMessage(WM_LBUTTONDOWN, IDC_DRAWPAD, MAKELONG(x, y));

}

//CDialogEx::OnLButtonDown(nFlags, point);

}

真是水的拿自己没办法,断断续续这么久还只有基础功能,数独生成的递归函数到底哪里bug导致死循环还是不明了,路过的各位还请多多指教,邮箱:believing_dan@hotmail.com

MFC实现数独(2)的更多相关文章

  1. MFC实现数独(1)

    雨天纷纷扰扰,数月里每日有雨,这个夏天不热,写这个数独的动机很简单:实践是最好的成长方式,想要获得自信,必有这么一遭,我躲不过.至于决定记录成博客,则是因为很久没有写文章,经常感觉脑海里很空白,屡次开 ...

  2. 蓝桥杯---数独(模拟 || dfs)

    [编程题](满分33分) "数独"是当下炙手可热的智力游戏.一般认为它的起源是"拉丁方块",是大数 学家欧拉于1783年发明的. 如图[1.jpg]所示:6x6 ...

  3. 数独GUI程序项目实现

    数独GUI程序项目实现 导语:最近玩上了数独这个游戏,但是找到的几个PC端数独游戏都有点老了...我就想自己做一个数独小游戏,也是一个不错的选择. 前期我在网上简单地查看了一些数独游戏的界面,代码.好 ...

  4. vs2010静态链接MFC库报链接错误

    由于需要将MFC程序在其它电脑上运行,所以需要将动态链接的MFC改成静态链接,本以为很简单,没想到链接的时候出现下面的链接错误: uafxcw.lib(afxmem.obj) : error LNK2 ...

  5. MFC中成员变量的声明顺序与析构顺序

    第一次用博客,第一篇随笔,就写今天遇到的一个问题吧. 在VS2008的MFC对话框程序,窗口成员变量的声明顺序与其析构顺序相反,即,先声明的变量后析构,后声明的变量先析构.未在其他模式下测试. cla ...

  6. VC中的MFC到底是什么?

    1. 微软基础类库(英语:Microsoft Foundation Classes,简称MFC)是一个微软公司提供的类库(class libraries),以C++类的形式封装了Windows API ...

  7. MFC&Halcon之实时视频监控

    上一篇实现了在MFC的窗体内显示图片,本篇介绍如何在MFC窗体内实时显示摄像头的影像. 要实现的功能是点击一个“开始”按钮,可以显示影像,再点击“停止”按钮,可以停止显示. 因为实时显示影像需要在一个 ...

  8. LintCode389.判断数独是否合法

    LintCode简单题:判断数独是否合法 问题描述: 请判定一个数独是否有效. 该数独可能只填充了部分数字,其中缺少的数字用 . 表示. 注意事项: 一个合法的数独(仅部分填充)并不一定是可解的.我们 ...

  9. MFC快速入门 - 菜单

    本文仅用于学习交流,商业用途请支持正版!转载请注明:http://www.cnblogs.com/mxbs/p/6231104.html 打开VS2010,依次打开File – New – Proje ...

随机推荐

  1. js 时间转成时间戳对比;My97DatePicker日历控件时间格式;Date.parse Firefox火狐浏览器返回Nan的解决办法

    有个情况,我在显示时间的时候是需要显示为  2013年8月15日 14时28分15秒 但是假如我用js去获取到这个时间,并且想进行时间对比的时候,这个时间2013年8月15日 14时28分15秒根本就 ...

  2. 完整cocos2d-x编译Andriod应用过程

    作者:何卫 转载请注明,原文链接:http://www.cnblogs.com/hewei2012/p/3366969.html 其他平台移植:http://cocos2d.cocoachina.co ...

  3. .NET/ASP.NET Routing路由(深入解析路由系统架构原理)http://wangqingpei557.blog.51cto.com/1009349/1312422

    阅读目录: 1.开篇介绍 2.ASP.NET Routing 路由对象模型的位置 3.ASP.NET Routing 路由对象模型的入口 4.ASP.NET Routing 路由对象模型的内部结构 4 ...

  4. K2 blackpearl 安装

    转:http://blog.csdn.net/gxiangzi/article/details/8432188 K2是国外的一款BPM引擎,基于MS的Workflow,关于它的详细介绍在我之前一片博客 ...

  5. C#中的值类型(value type)与引用类型(reference type)的区别

    ylbtech- .NET-Basic:C#中的值类型与引用类型的区别 C#中的值类型(value type)与引用类型(reference type)的区别 1.A,相关概念返回顶部     C#中 ...

  6. UI篇--布局问题

    1.android:layout_marginRight 不起作用解决方法 今天想在RelativeLayout的左右分别放上一个按钮, 左边按钮用marginLeft="10dp" ...

  7. CXF之一 基础理论介绍

    WebService介绍   WebService让一个程序可以透明地调用互联网程序,不用管具体的实现细节.只要WebService公开了服务接口,远程客户端就可以调用服务.WebService是基于 ...

  8. Windows 窗体最小化和隐藏的区别及恢复

    应用程序有托盘图标,窗体最小化或者隐藏窗体时,点击托盘图标需要恢复窗体显示,并且恢复之前的现实状体,正常大小或者最大化显示.例如:最大化显示窗体时,点击最小化按钮,窗体最小化,点击托盘图标将最大化显示 ...

  9. ORA-15041: diskgroup space exhausted

    今天在做一个备份的时候,出现磁盘耗尽的错误,具体如下: RMAN-00571: =========================================================== ...

  10. 【暑假】[实用数据结构]UVAlive 3135 Argus

    UVAlive 3135 Argus Argus Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %l ...