#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[MAX_STRING][MAX_STRING]; //扫雷游戏区域
size_t nSide; //区域边长
BOOL bMine[MAX_STRING][MAX_STRING]; //记录雷的位置
UINT uMine[MAX_STRING][MAX_STRING]; //记录周围雷的个数
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[i][j] = LAND;
}
}
srand((unsigned)time(NULL));
//下面随机出现nMine颗雷
for (int i=0;i<nMine;i++)
{
int x = rand()%nSide;
int y = rand()%nSide;
if (!bMine[x][y])
{
bMine[x][y] = TRUE;
}
else
{
i--;
}
}
//下面计算每一块周围有多少颗雷
for (int i=0;i<nSide;i++)
{
for (int j=0;j<nSide;j++)
{
if (bMine[i][j]) 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[m][n]) nCounts++;
}
}
//存储雷数nCounts
uMine[i][j] = 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[MAX_STRING][MAX_STRING]); //计算并现出没雷的连续区域
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[i][j],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[x][y])
{
//先显示雷的位置然后退出
for (i=0;i<nSide;i++)
for (j=0;j<nSide;j++)
if (bMine[i][j])
TextOut(hdc,i*WIDTH,j*HEIGHT,TEXT("●"),1);
MessageBox(hwnd,TEXT("游戏结束!"),TEXT("提示"),MB_OK);
ReleaseDC(hwnd,hdc);
DestroyWindow(hwnd);
break;
}
BOOL bRecord[MAX_STRING][MAX_STRING] = {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[MAX_STRING][MAX_STRING]) //计算并现出没雷的连续区域
{
bRecord[x][y] = TRUE;
if (x<0 || x>=nSide || y<0 || y>=nSide) return;
static TCHAR szMine[5]; //为显示雷做准备
//现出当前位置
StringCchPrintf(szMine,5,TEXT(" "));
TextOut(hdc,x*WIDTH,y*HEIGHT,szMine,1);
if (uMine[x][y]>0)
{
StringCchPrintf(szMine,5,TEXT("%d"),uMine[x][y]);
TextOut(hdc,x*WIDTH,y*HEIGHT,szMine,1);
return;
}
//现出上下左右4个方向
if (!bRecord[x][y-1]) SwipeLand(hdc,x,y-1,bRecord);
if (!bRecord[x][y+1]) SwipeLand(hdc,x,y+1,bRecord);
if (!bRecord[x-1][y]) SwipeLand(hdc,x-1,y,bRecord);
if (!bRecord[x+1][y]) SwipeLand(hdc,x+1,y,bRecord);
}