MFC实现数独(1)
雨天纷纷扰扰,数月里每日有雨,这个夏天不热,写这个数独的动机很简单:实践是最好的成长方式,想要获得自信,必有这么一遭,我躲不过。至于决定记录成博客,则是因为很久没有写文章,经常感觉脑海里很空白,屡次开口却不知道想说什么!我在迷茫啊。
这是一篇记录摸索过程的文章,主要记录遇到的问题,适合毫无基础的共同探讨,也请路过的高手多指点。
思路很简单:
①数独随机生成算法,打算采用递归遍历方式,满足条件的保存下来,内存数组保存或者写入文件。
②MFC实现矩形区域绘制背景和文本,主要是CDC方法的调用。
③指定区域生成一个可供输入的编辑框,可设置文本的格式和范围。
目前只写到这里,先附上代码,其余部分待完工后会附上。
数独生成算法:
这个编辑器不智能啊,代码的格式全毁了,InitSudoku是主递归函数,设计思路是,用行、列作为渐变参数,当生成了9*9的数独时会return;unConflict用来检测当前数字是否和已经生成的数独冲突。
void sudoku::InitSudoku(int row, int col)
{
if(row == 8 && col == 9)
{
return;
}
if(col == 9)
{
row += 1;
col = 0;
}
int bEye = false;
for(int i = 1; i <= 9; i++)
{
if(unConflict(row, col, i))
{
Matrix[row][col].SetNumber(i);
InitSudoku(row, col+1);
}
}
}
bool sudoku::unConflict(int row, int col, int num)
{
int unValidValue[SIZE*2] = {};
int loop = 0;
for(int i = 0; i < row; i++)
{
unValidValue[i] = Matrix[i][col].GetNumber();
loop = i;
}
loop += 1;
for(int j = 0; j < col; j++)
{
unValidValue[loop] = Matrix[row][j].GetNumber();
loop++;
}
bool bEye = true;
for(int index = 0; index < SIZE*2; index++)
{
if(num == unValidValue[index] && unValidValue[index] != 0)
bEye = false;
}
return bEye;
}
绘制一个矩形区域并打印指定格式的文本,DrawText绘制文本的时候遇到了问题,不能垂直居中,查资料的时候发现DT_VCENTER|DT_SINGLELINE必须同时使用,否则窗口无法定位矩形的高度,试验解决之。
void CmfcsudukuDlg::OnBnClickedButtonDraw()
{
// TODO: 在此添加控件通知处理程序代码
CRect rect = CRect(50, 50, 100, 130);
CDC *pDC = GetDC();
pDC->FillSolidRect(rect, RGB(230, 230, 230));
CString val;
val.Format(_T("%d"), 8);
pDC->SetTextColor(RGB(255, 255, 255));
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(val, rect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
return;
}
创造一个文本输入的编辑框并定义编辑框的文本格式,edit->SetFont这个函数需要注意一下,如果传递的CFont不是成员变量或者全局变量会导致该函数无效,我只验证了成员变量可以使字体生效,未验证全局变量是否可以生效。font作为参数时字体不改变,m_font传递会生效字体。
void CmfcsudukuDlg::OnBnClickedButtonInput()
{
// TODO: 在此添加控件通知处理程序代码
CRect rect = CRect(50, 50, 100, 130);
CString val;
val.Format(_T("%d"),6);
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"));
m_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"));
CEdit *edit = new CEdit;
edit->Create(ES_CENTER ,rect, this, IDC_INPUT);
edit->SetFont(&m_font);
edit->SetFocus();
edit->ShowWindow(true);
edit->SetWindowTextW(val);
}
未完待续......持续更新中