C语言可视化数独游戏 (含源码和开发报告)

前几个月C语言结课,做了个数独游戏的大作业。因为不满足于命令行界面的简陋效果,就现学了Win32 API做了个可视化界面。程序的运行效果图如下:

C语言可视化数独游戏 (含源码和开发报告)

功能概要

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 购买。