cuibaowenown2 发表于 2014-7-26 14:50:34

Windows编程写了个扫雷,但是退出的时候会出现Stack Overflow求解决

#define UNICODE
#include <Windows.h>
#include <strsafe.h>
#include <windowsx.h>
#include <time.h>

#define HEIGHT 15
#define WIDTH 15
#define MAX_STRING 256

#define LAND L'○'
#define MINE L'●'
#define SAFE L' '

TCHAR szMatrix;                //扫雷游戏区域
size_t nSide;                        //区域边长
BOOL bMine;        //记录雷的位置
UINT uMine;        //记录周围雷的个数
int nMine;        //记录雷的个数

LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR szCmdLine,INT nCmdShow)
{
        static TCHAR szClassName[] = TEXT("MyClass");
        WNDCLASS wndclass;
        HWND hwnd;
        MSG msg;

        wndclass.cbClsExtra = 0;
        wndclass.cbWndExtra = 0;
        wndclass.hbrBackground = (HBRUSH)GetStockObject(DC_BRUSH);
        wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
        wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
        wndclass.hInstance = hInstance;
        wndclass.lpfnWndProc = WindowProc;
        wndclass.lpszClassName = szClassName;
        wndclass.lpszMenuName = NULL;
        wndclass.style = CS_HREDRAW | CS_VREDRAW;
       
        if (!RegisterClass(&wndclass))
        {
                MessageBox(NULL,TEXT("本程序必须在WINNT下运行!"),TEXT("警告"),MB_OK);
                return 0;
        }

        nSide = 20;
        nMine = 40;
        for (int i=0;i<nSide;i++)
        {
                for (int j=0;j<nSide;j++)
                {
                        szMatrix = LAND;
                }
        }

        srand((unsigned)time(NULL));
        //下面随机出现nMine颗雷
        for (int i=0;i<nMine;i++)
        {
                int x = rand()%nSide;
                int y = rand()%nSide;
                if (!bMine)
                {
                        bMine = TRUE;
                }
                else
                {
                        i--;
                }
        }
        //下面计算每一块周围有多少颗雷
        for (int i=0;i<nSide;i++)
        {
                for (int j=0;j<nSide;j++)
                {
                        if (bMine)        continue;                //当前块是雷
                        int nCounts = 0;
                        for (int m=i-1;m<=i+1;m++)
                        {
                                if (m<0 || m>=nSide)        continue;
                                for (int n=j-1;n<=j+1;n++)
                                {
                                        if (n<0 || n>=nSide)        continue;
                                        if (bMine)        nCounts++;
                                }
                        }
                        //存储雷数nCounts
                        uMine = nCounts;
                }
        }

        hwnd = CreateWindow(szClassName,
                                                TEXT("BY:落叶"),
                                                WS_OVERLAPPEDWINDOW,
                                                CW_USEDEFAULT,
                                                CW_USEDEFAULT,
                                                CW_USEDEFAULT,
                                                CW_USEDEFAULT,
                                                NULL,
                                                NULL,
                                                hInstance,
                                                NULL);

        ShowWindow(hwnd,nCmdShow);
        UpdateWindow(hwnd);

        while (GetMessage(&msg,NULL,0,0))
        {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
        }

        return msg.wParam;
}

void SwipeLand(HDC hdc,int x,int y,BOOL bRecord);        //计算并现出没雷的连续区域

LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;

        int i,j;        //循环变量
        int xPos,yPos;        //记录鼠标位置
        int x,y;        //记录地雷下标

        switch (uMsg)
        {
                case WM_PAINT:
                        hdc = BeginPaint(hwnd,&ps);
                        //绘制扫雷区域
                        for (i=0;i<nSide;i++)
                        {
                                for (j=0;j<nSide;j++)
                                {
                                        TextOut(hdc,i*WIDTH,j*HEIGHT,&szMatrix,1);
                                }
                        }
                        EndPaint(hwnd,&ps);
                        break;
                case WM_LBUTTONUP:
                        xPos = GET_X_LPARAM(lParam);
                        yPos = GET_Y_LPARAM(lParam);
                        x = xPos/WIDTH;
                        y = yPos/HEIGHT;
                        if (y < nSide && x < nSide)
                        {
                                hdc = GetDC(hwnd);
                                //判断是否有雷
                                if (bMine)
                                {
                                        //先显示雷的位置然后退出
                                        for (i=0;i<nSide;i++)
                                                for (j=0;j<nSide;j++)
                                                        if (bMine)
                                                                TextOut(hdc,i*WIDTH,j*HEIGHT,TEXT("●"),1);
                                        MessageBox(hwnd,TEXT("游戏结束!"),TEXT("提示"),MB_OK);
                                        ReleaseDC(hwnd,hdc);
                                        DestroyWindow(hwnd);
                                        break;
                                }
                                BOOL bRecord = {FALSE};        //记录是否已遍历
                                SwipeLand(hdc,x,y,bRecord);
                                ReleaseDC(hwnd,hdc);
                        }
                        break;
                case WM_CLOSE:
                        if (IDYES == MessageBox(hwnd,TEXT("确认退出扫雷?"),TEXT("提示"),MB_YESNO | MB_ICONINFORMATION))
                                DestroyWindow(hwnd);
                        break;
                case WM_DESTROY:
                        PostQuitMessage(0);
                        break;
                default:
                        return DefWindowProc(hwnd,uMsg,wParam,lParam);
        }

        return 0;
}

void SwipeLand(HDC hdc,int x,int y,BOOL bRecord)        //计算并现出没雷的连续区域
{
        bRecord = TRUE;
        if (x<0 || x>=nSide || y<0 || y>=nSide)        return;
        static TCHAR szMine;        //为显示雷做准备
        //现出当前位置
        StringCchPrintf(szMine,5,TEXT(" "));
        TextOut(hdc,x*WIDTH,y*HEIGHT,szMine,1);
        if (uMine>0)
        {
                StringCchPrintf(szMine,5,TEXT("%d"),uMine);
                TextOut(hdc,x*WIDTH,y*HEIGHT,szMine,1);
                return;
        }
        //现出上下左右4个方向
        if (!bRecord)        SwipeLand(hdc,x,y-1,bRecord);
        if (!bRecord)        SwipeLand(hdc,x,y+1,bRecord);
        if (!bRecord)        SwipeLand(hdc,x-1,y,bRecord);
        if (!bRecord)        SwipeLand(hdc,x+1,y,bRecord);
}

ZX-走样 发表于 2014-7-26 18:01:33

好高端,大气

『浴火凤凰』 发表于 2014-7-28 20:09:13

好流弊的样子

DK.M 发表于 2014-8-7 00:44:39

我也在写。。不过是淡季后图片的重绘问题。。

智商是硬伤 发表于 2015-8-13 17:53:18

把问题顶起来{:7_146:}
页: [1]
查看完整版本: Windows编程写了个扫雷,但是退出的时候会出现Stack Overflow求解决