Win32实现迷宫
跟着杨立祥老师的课程,为了完成扫雷的作业,打算先用DFS/BFS实现路径搜索的简单Demo。
生成迷宫:
/* 扫雷程序生成方砖 */ #include <stdio.h> #include <time.h> #include <stdlib.h> #include <windows.h> #include <windowsx.h> #include "resource.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, PSTR szCmdLine, int iCmdshow) { static TCHAR szAppName[] = TEXT("Maze"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("registered error"), szAppName, MB_ICONERROR); } hwnd = CreateWindow(szAppName, TEXT("Mazes"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdshow); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HBITMAP hBitmap; static int cxClient, cyClient, cxSource, cySource, xClick, yClick; static int leftPos, rightPos, topPos, bottomPos; BITMAP bitmap; HDC hdc, hdcMem; PAINTSTRUCT ps; int x, y; HINSTANCE hInstance; switch (message) { case WM_CREATE: PlaySound(TEXT("start.wav"), NULL, SND_FILENAME | SND_ASYNC); srand((unsigned)time(NULL)); hInstance = ((LPCREATESTRUCT)lParam)->hInstance; hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP1)); GetObject(hBitmap, sizeof(BITMAP), &bitmap); cxSource = bitmap.bmWidth; cySource = bitmap.bmHeight / 3; return 0; case WM_SIZE: cxClient = GET_X_LPARAM(lParam); cyClient = GET_Y_LPARAM(lParam); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); hdcMem = CreateCompatibleDC(hdc); SelectObject(hdcMem, hBitmap); //方砖的范围(左上角) topPos = cySource * 2; leftPos = cxSource * 2; for (y = topPos; y <= cyClient - cySource * 3; y += cySource) { for (x = leftPos; x <= cxClient - cxSource * 3; x += cxSource) { if (rand() % 4 == 1) { BitBlt(hdc, x, y, cxSource, cySource, hdcMem, 0, 0, SRCCOPY); } else { BitBlt(hdc, x, y, cxSource, cySource, hdcMem, 0, cySource, SRCCOPY); } } } rightPos = x - cxSource; bottomPos = y - cySource; //左上:右下为出口 BitBlt(hdc, cxSource * 2, cySource * 2, cxSource, cySource, hdcMem, 0, cySource, SRCCOPY); BitBlt(hdc, rightPos, bottomPos, cxSource, cySource, hdcMem, 0, cySource, SRCCOPY); DeleteDC(hdcMem); EndPaint(hwnd, &ps); return 0; case WM_LBUTTONDOWN: xClick = GET_X_LPARAM(lParam); yClick = GET_Y_LPARAM(lParam); //无效区 if (xClick < leftPos || xClick > rightPos + cxSource || yClick < topPos || yClick > bottomPos + cySource) { break; } for (y = topPos; y <= bottomPos; y += cySource) { if (yClick >= y && yClick <= y + cySource) { yClick = y; break; } } for (x = leftPos; x <= rightPos; x += cxSource) { if (xClick >= x && xClick <= x + cxSource) { xClick = x; break; } } hdc = GetDC(hwnd); hdcMem = CreateCompatibleDC(hdc); SelectObject(hdcMem, hBitmap); BitBlt(hdc, xClick, yClick, cxSource, cySource, hdcMem, 0, cySource * 2, SRCCOPY); DeleteDC(hdcMem); ReleaseDC(hwnd, hdc); return 0; case WM_DESTROY: DeleteObject(hBitmap); PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }
效果图:
Keep it simple!