C语言可视化数独游戏 (含源码和开发报告)
前几个月C语言结课,做了个数独游戏的大作业。因为不满足于命令行界面的简陋效果,就现学了Win32 API做了个可视化界面。程序的运行效果图如下:
功能概要
1. 按右侧的上下键可以切换数独图。数独图存在文件目录map下,运行程序会自动读取目录下全部数独图。
2. 按右下方的Go按钮,可以快速解出最终答案。这里的解题算法采用深搜直接暴力**。
3. 选中数独图上的某一格,其行、列、九宫格会加深颜色,以做提示。
解题代码
/* 使用solveSudoku算法解数独 */
int solveSudoku(pNode *p, int depth) { //深度为地图坐标x*9+y;函数返回值为布尔值0、1,表示是否解出
int i, j, x, y;
int book[10]; //标记该位置各位数可否填入
x = depth / 9; //坐标x
y = depth % 9; //坐标y
if (depth == 81) return 1; //到达地图最后位置,返回真if (p->solution[x][y] == 0) { //如果该位置待填入数字
memset(book, 0, sizeof(book)); //初始化book数组for (i = 0; i < 9; i++) { //在book中标记行、列、九宫格中出现数字
book[p->solution[x][i]] = 1;
book[p->solution[i][y]] = 1;
}
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
book[p->solution[x / 3 * 3 + i][y / 3 * 3 + j]] = 1;for (i = 1; i <= 9; i++) //遍历填入可填入的数字,递归下一个深度
if (book[i] == 0) {
p->solution[x][y] = i;
if (solveSudoku(p, depth + 1)) return 1;
p->solution[x][y] = 0;
}
return 0; //遍历完所有数字仍未解出,返回假
}
else { //如果该位置有数字
if (solveSudoku(p, depth + 1)) return 1;
return 0;
}
}
绘制窗口
/* 窗口绘制函数 */
void drawScene(HWND hWnd)
{
HDC hdc;
HPEN hpen;
HBRUSH hbrush;
HFONT hfont;
PAINTSTRUCT ps;int i, j;
hdc = BeginPaint(hWnd, &ps);
/* 绘制数独图圆角底板 */
hbrush = CreateSolidBrush(RGB(106, 106, 106));
hpen = CreatePen(PS_NULL, 1, 0);
SelectObject(hdc, hpen);
SelectObject(hdc, hbrush);
RoundRect(hdc, x, y, x + 9 * squareWidth, y + 9 * squareWidth, 20, 20);/* 如果选中,绘制选中小格及其行、列、九宫格 */
if ((iMouse >= 0) && (iMouse <= 8) && (jMouse >= 0) && (jMouse <= 8)) {
hbrush = CreateSolidBrush(RGB(97, 97, 97));
hpen = CreatePen(PS_NULL, 1, 0);
SelectObject(hdc, hpen);
SelectObject(hdc, hbrush);
Rectangle(hdc, x + iMouse * squareWidth, y, x + (iMouse + 1)*squareWidth, y + 9 * squareWidth);
Rectangle(hdc, x, y + jMouse * squareWidth, x + 9 * squareWidth, y + (jMouse + 1)*squareWidth);
Rectangle(hdc, x + iMouse / 3 * 3 * squareWidth, y + jMouse / 3 * 3 * squareWidth, x + (iMouse / 3 + 1) * 3 * squareWidth, y + (jMouse / 3 + 1) * 3 * squareWidth);
hbrush = CreateSolidBrush(RGB(65, 224, 170));
hpen = CreatePen(PS_NULL, 1, 0);
SelectObject(hdc, hpen);
SelectObject(hdc, hbrush);
Rectangle(hdc, x + iMouse * squareWidth, y + jMouse * squareWidth, x + (iMouse + 1)*squareWidth, y + (jMouse + 1)*squareWidth);
}/* 绘制九宫格分割线 */
hpen = CreatePen(PS_SOLID, 1, RGB(76, 76, 76));
SelectObject(hdc, hpen);
for (i = 1; i < 9; i++) {
MoveToEx(hdc, x, y + i * squareWidth, NULL);
LineTo(hdc, x + 9 * squareWidth, y + i * squareWidth);
MoveToEx(hdc, x + i * squareWidth, y, NULL);
LineTo(hdc, x + i * squareWidth, y + 9 * squareWidth);
}
hpen = CreatePen(PS_SOLID, 3, RGB(76, 76, 76));
SelectObject(hdc, hpen);
for (i = 1; i < 3; i++) {
MoveToEx(hdc, x, y + i * squareWidth * 3, NULL);
LineTo(hdc, x + 9 * squareWidth, y + i * squareWidth * 3);
MoveToEx(hdc, x + i * squareWidth * 3, y, NULL);
LineTo(hdc, x + i * squareWidth * 3, y + 9 * squareWidth);
}/* 如果解题按钮已点击,绘制数独答案数字 */
hfont = CreateFont(squareWidth, 2 * squareWidth / 5, 0, 0, 400, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SCRIPT, TEXT("Calibri"));
SelectObject(hdc, hfont);
SetBkMode(hdc, TRANSPARENT);
TCHAR cha[2] = { 0 };
if (solved == 1) {
SetTextColor(hdc, RGB(160, 191, 180));
for (i = 0; i < 9; i++)
for (j = 0; j < 9; j++) {
_itow(p->solution[i][j], cha, 10);
TextOut(hdc, x + squareWidth / 3 + i * squareWidth, y + j * squareWidth, cha, 1);
}
}/* 绘制数独原题数字 */
SetTextColor(hdc, RGB(230, 230, 230));
for (i = 0; i < 9; i++)
for (j = 0; j < 9; j++)
if (p->map[i][j] != 0) {
_itow(p->map[i][j], cha, 10);
TextOut(hdc, x + squareWidth / 3 + i * squareWidth, y + j * squareWidth, cha, 1);
}EndPaint(hWnd, &ps);
}
下载源码及报告:C语言数独游戏大作业(含报告/Win32可视化)
或添加微信号 innoin 购买。