游戏界面:
(1)扫雷失败界面.
(2)扫雷开始界面
程序代码:
//*********************************************
//@CopyRight by Fuliangliang
//All the right reserved
//If it has some problems
//You can go to my blog:
//http://blog.csdn.net/fuliangliang
//(All the code or other codes you can find)
//or my E-mail:fuliangliang@gmail.com
//for details.
//********************************************
#include <windows.h>
#include <math.h>
#include "resource.h" // 菜单资源头文件
#define SHADOW_WIDTH1 1 //阴影宽度1
#define SHADOW_WIDTH2 2 //阴影宽度2
#define SHADOW_WIDTH3 3 //阴影宽度3
#define ID_TIMER 1 //定时器的id号
#define BORDER 8 //边界的宽度
#define BOX_WIDTH 18//box的宽度
#define BOX_HEIGHT 18 //box的高度
#define RESERVED_AREA 32 //保留区高度
//************************************
//自定义的函数声明
//************************************
//窗口过程函数
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
//绘制边界
void DrawBorder(HDC hdc,int x,int y,int width,int height,int BorderWidth,COLORREF &color1,COLORREF &color2,bool WTop);
//自动打开Boxes
void AutoOpenBoxes(HDC &hdc,int i,int j);
//自动打开时,重绘box矩形区域
void drawRect(HDC &hdc,int x,int y);
//判断周围box是否都打开了
bool allRoundIsOpened(int row,int col);
//初始化box
void InitBox();
//更新当前窗口,并reset
void UpdateTheWindow(HWND &hwnd,int rows,int cols,int mineNO);
//计算当前box周围雷的个数
void ComputeRoundMineNo();
//随机布雷
void RandomSetMines();
//绘制mineRect变量保存雷区
void DrawMineArea(HDC &hdc);
//报告游戏结束
void ReportGameOver(HDC &hdc,HBITMAP &hBitmap1,HBITMAP &hBitmap2);
//绘制显示雷的个数的区域
void DisplayMineNo(HDC &hdc);
//绘制计时显示区域
void DrawTimeArea(HDC &hdc);
//显示计时器时间
void DisplayTime(HDC &hdc);
//绘制重置按钮
void DrawResetButton(HDC &hdc,HBITMAP &hBitmap);
void DisplayADigit(HDC hdc,int iNumber);
//**********************************
//结构体Box,roundMineNO表示周围雷得
//个数containMine表示是否里面是否有
//雷,isOpened表示box是否已经打开
//**********************************
struct Box
{
int roundMineNO;
bool containMine;
bool isOpened;
};
//********************
//全局静态变量声明
//********************
static int mineNumber;//雷的个数
static int ROWS; //行数
static int COLS; //列数
static int iSM_BorderX;//系统boder宽度
static int iSM_BorderY;//系统boder高度
static int iSM_CaptionY; //系统标题栏高度
static int iSM_MenuY;//菜单栏的高度
static int icxSrc,icySrc;//屏幕的大小
static Box **box;//结构体Box的二维指针
static int i,j,numberOpened;//已经打开box的数量
static int time;//计数变量
static HMENU hMenu;
static RECT mineRect;//保存雷区域的RECT
static RECT resetButtonRect;//保存重置“按钮”区域的RECT
static COLORREF color1=RGB(128, 128, 128),//绘制border的shadow区域
color2=RGB(255,255,255),//绘制border的hightlight区域
color3=RGB(192,192,192),//窗体的背景颜色
color4=RGB(120,120,200);//绘制打开的box分割线颜色
static HBITMAP hBitmap1,hBitmap2,hBitmap3,hBitmap4;
//********
//main函数
//********
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("SineWave") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
mineNumber = 10;
ROWS = 10; COLS = 10;
box = new Box* [ROWS];
for(int k=0;k<ROWS;k++)
box[k] = new Box[COLS];
iSM_BorderX = GetSystemMetrics(SM_CXBORDER);
iSM_BorderY = GetSystemMetrics(SM_CYBORDER);
iSM_CaptionY = GetSystemMetrics(SM_CYCAPTION);
iSM_MenuY = GetSystemMetrics(SM_CYMENU);
icxSrc = GetSystemMetrics(SM_CXSCREEN);
icySrc = GetSystemMetrics(SM_CYSCREEN);
int cx = BOX_WIDTH * COLS + 2 * SHADOW_WIDTH3 + 2 * SHADOW_WIDTH2 + 2 * iSM_BorderX + 2 * BORDER;
int cy = BOX_HEIGHT * ROWS + 2 * SHADOW_WIDTH3 + 4 * SHADOW_WIDTH2 + 2 * iSM_BorderY + 3 * BORDER + RESERVED_AREA+iSM_CaptionY+iSM_MenuY;
mineRect.left = SHADOW_WIDTH3+BORDER+SHADOW_WIDTH2;
mineRect.right =mineRect.left + BOX_WIDTH * COLS;
mineRect.top = SHADOW_WIDTH3+2*BORDER+RESERVED_AREA+3*SHADOW_WIDTH2;
mineRect.bottom = mineRect.top + BOX_HEIGHT * ROWS;
resetButtonRect.left = SHADOW_WIDTH3+BORDER+(mineRect.right-mineRect.left)/2-RESERVED_AREA/4;
resetButtonRect.right = resetButtonRect.left + 2 * RESERVED_AREA / 3 + 2;
resetButtonRect.top = SHADOW_WIDTH3+BORDER + RESERVED_AREA / 4 - 2;
resetButtonRect.bottom = resetButtonRect.top + 2 * RESERVED_AREA / 3 + 4;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc= WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
hMenu = LoadMenu (hInstance, MAKEINTRESOURCE (IDR_MENU1)) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox ( NULL, TEXT ("Program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow ( szAppName, TEXT ("扫雷-游戏"),
WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX,
,(icxSrc-cx)/2,(icySrc-cy)/2,
cx, cy,
NULL, hMenu, 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)
{
HDC hdc ;
HBRUSH hBrush;
BITMAP bitmap;
HINSTANCE hInstance;
PAINTSTRUCT ps ;
static bool isLButtonDown=false;
static int m,n,cx,cy;
static RECT grid,rect;
static char szBuffer[2];
POINT pt;
switch (message)
{
case WM_CREATE: //初始化变量
hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
hBitmap1 = LoadBitmap(hInstance,TEXT("FACE1"));
GetObject(hBitmap1,sizeof(BITMAP),&bitmap);
hBitmap2 = LoadBitmap(hInstance,TEXT("FACE2"));
GetObject(hBitmap2,sizeof(BITMAP),&bitmap);
hBitmap3 = LoadBitmap(hInstance,TEXT("FACE3"));
GetObject(hBitmap3,sizeof(BITMAP),&bitmap);
hBitmap4 = LoadBitmap(hInstance,TEXT("MINE"));
GetObject(hBitmap4,sizeof(BITMAP),&bitmap);
InitBox();
RandomSetMines();
ComputeRoundMineNo();
SetTimer(hwnd,ID_TIMER,1000,NULL);
return 0;
case WM_TIMER:
hdc = GetDC(hwnd);
time++;
DisplayTime(hdc);
DeleteDC(hdc);
return 0;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
GetClientRect(hwnd,&rect);
hBrush = CreateSolidBrush(RGB(192,192,192));
SetBkColor(hdc,RGB(192,192,192));
SelectObject(hdc,hBrush);
SelectObject(hdc,GetStockObject(NULL_PEN));
Rectangle(hdc,0,0,rect.right,rect.bottom);
//绘制外边界
DrawBorder(hdc,0,0,rect.right,rect.bottom,SHADOW_WIDTH3,color1,color2,true);
//绘制保留区
DrawBorder(hdc, SHADOW_WIDTH3+BORDER, SHADOW_WIDTH3+BORDER,
BOX_WIDTH * COLS + 2 * SHADOW_WIDTH2, RESERVED_AREA + 2 * SHADOW_WIDTH2, SHADOW_WIDTH2, color1,color2,false);
DrawResetButton(hdc,hBitmap1);
DisplayMineNo(hdc);
DrawTimeArea(hdc);
//绘制内边界
DrawBorder(hdc, SHADOW_WIDTH3+BORDER, SHADOW_WIDTH3+2*BORDER+RESERVED_AREA+2*SHADOW_WIDTH2,
BOX_WIDTH * COLS + 2 * SHADOW_WIDTH2, BOX_HEIGHT*ROWS + 2*SHADOW_WIDTH2, SHADOW_WIDTH2, color1,color2,false);
//绘制雷区的box
DrawMineArea(hdc);
EndPaint(hwnd,&ps);
return 0 ;
case WM_LBUTTONDOWN:
hdc = GetDC(hwnd);
isLButtonDown = true;
DrawResetButton(hdc,hBitmap2);
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
grid.left = mineRect.left;
grid.right = mineRect.right;
grid.top = mineRect.top;
grid.bottom = mineRect.bottom;
if(PtInRect(&resetButtonRect,pt))
{
hdc = GetDC(hwnd);
DrawBorder(hdc,resetButtonRect.left,resetButtonRect.top,resetButtonRect.right - resetButtonRect.left
,resetButtonRect.bottom - resetButtonRect.top,SHADOW_WIDTH2,color1,color2,false);
DeleteDC(hdc);
}
else if(PtInRect(&grid,pt))
{
j = (pt.x - grid.left) / BOX_WIDTH;
i = (pt.y - grid.top) / BOX_HEIGHT;
grid.left += BOX_WIDTH * j;
grid.top += BOX_HEIGHT * i;
grid.right = grid.left + BOX_WIDTH;
grid.bottom = grid.top + BOX_HEIGHT;
DrawBorder(hdc,grid.left,grid.top,BOX_WIDTH-2,BOX_HEIGHT-2,SHADOW_WIDTH2,color3,color3,false);
DrawBorder(hdc,grid.left,grid.top,BOX_WIDTH,BOX_HEIGHT,SHADOW_WIDTH1,color4,color4,false);
}
DeleteDC(hdc);
return 0;
case WM_LBUTTONUP:
static HPEN hPen;
static RECT rect1;
static char szBuffer[2];
hdc = GetDC(hwnd);
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
isLButtonDown = false;
DrawResetButton(hdc,hBitmap1);
if(PtInRect(&resetButtonRect,pt))
{
DrawBorder(hdc,resetButtonRect.left,resetButtonRect.top,resetButtonRect.right - resetButtonRect.left
,resetButtonRect.bottom - resetButtonRect.top,SHADOW_WIDTH2,color1,color2,true);
UpdateTheWindow(hwnd,ROWS,COLS,mineNumber);
return 0;
}
else if(!PtInRect(&mineRect,pt))
return 0;
hPen = CreatePen(PS_SOLID,2,RGB(255,255,0));
SelectObject(hdc,hPen);
SetBkColor(hdc,RGB(192,192,192));
rect1.left = mineRect.left + BOX_WIDTH * j;
rect1.right = rect1.left + BOX_WIDTH;
rect1.top = mineRect.top + BOX_HEIGHT * i;
rect1.bottom = rect1.top + BOX_HEIGHT;
if(!box[i][j].isOpened)
{
if(!box[i][j].containMine)
{
if(box[i][j].roundMineNO != 0)
{
wsprintf(szBuffer,TEXT("%d"),box[i][j].roundMineNO);
//输出周围雷的个数
DrawText(hdc,szBuffer,-1,&rect1,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
}
box[i][j].isOpened = true;
numberOpened ++;
if(numberOpened == ROWS * COLS - mineNumber)
MessageBox (hwnd, TEXT ("祝贺你赢了!"),TEXT("扫雷-游戏"), MB_ICONWARNING) ;
AutoOpenBoxes(hdc,i,j);
}
else
ReportGameOver(hdc,hBitmap3,hBitmap4);
}
DeleteDC(hdc);
return 0;
case WM_MOUSEMOVE:
if(isLButtonDown)
{
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
rect.left = mineRect.left;
rect.right = mineRect.right;
rect.top = mineRect.top;
rect.bottom = mineRect.bottom;
if(PtInRect(&rect,pt))//判断是否在雷区
{
m = i; n = j;
j = (pt.x - rect.left) / BOX_WIDTH;
i = (pt.y - rect.top) / BOX_HEIGHT;
rect.left += BOX_WIDTH * j;
rect.top += BOX_HEIGHT * i;
rect.right = rect.left + BOX_WIDTH;
rect.bottom = rect.top + BOX_HEIGHT;
if(grid.left == rect.left && grid.right==rect.right
&&grid.bottom == rect.bottom && grid.top == rect.top)
return 0;
hdc = GetDC(hwnd);
if(!box[m][n].isOpened)//鼠标移走后,恢复未按下
{
DrawBorder(hdc,grid.left,grid.top,BOX_WIDTH-2,BOX_HEIGHT-2,SHADOW_WIDTH2,color1,color2,true);
DrawBorder(hdc,grid.left,grid.top,BOX_WIDTH,BOX_HEIGHT,SHADOW_WIDTH1,color3,color3,true);
}
//使当前的box成为按下状态
grid.left = rect.left;
grid.right = rect.right;
grid.bottom = rect.bottom;
grid.top = rect.top;
DrawBorder(hdc,grid.left,grid.top,BOX_WIDTH-2,BOX_HEIGHT-2,SHADOW_WIDTH2,color3,color3,true);
DrawBorder(hdc,grid.left,grid.top,BOX_WIDTH,BOX_HEIGHT,SHADOW_WIDTH1,color4,color4,true);
}
DeleteDC(hdc);
}
return 0;
case WM_COMMAND: //响应菜单消息
switch (LOWORD (wParam))
{
case IDM_PLAY:
InitBox();
RandomSetMines();
ComputeRoundMineNo();
InvalidateRect(hwnd,NULL,TRUE);
UpdateWindow(hwnd);
return 0;
case IDM_BEGINER:
UpdateTheWindow(hwnd,10,10,10);
return 0;
case IDM_MEDIUM:
UpdateTheWindow(hwnd,15,15,20);
return 0;
case IDM_SENIOR:
UpdateTheWindow(hwnd,15,20,30);
return 0;
case IDM_EXIT:
SendMessage (hwnd, WM_CLOSE, 0, 0) ;
return 0;
case IDM_ABOUT:
return 0;
}
case WM_DESTROY:
DeleteObject(hBitmap1);
DeleteObject(hBitmap2);
DeleteObject(hBitmap3);
DeleteObject(hBitmap4);
KillTimer(hwnd,ID_TIMER);
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
//绘制边界
void DrawBorder(HDC hdc,int x,int y,int width,int height,int BorderWidth,COLORREF &color1,COLORREF &color2,bool WTop)
{
int i;
HPEN hpen1,hpen2;
hpen1=CreatePen(PS_SOLID, 1, color1);
hpen2=CreatePen(PS_SOLID, 1, color2);
if(WTop)
SelectObject(hdc,hpen2);
else
SelectObject(hdc,hpen1);
for(i = 0; i < BorderWidth; i++)
{
MoveToEx(hdc,x+i,y+i,NULL);
LineTo(hdc,x+width-i,y+i);
MoveToEx(hdc,x+i,y+i,NULL);
LineTo(hdc,x+i,y+height-i);
}
if(WTop)
SelectObject(hdc,hpen1);
else
SelectObject(hdc,hpen2);
for(i = 0; i < BorderWidth; i++)
{
MoveToEx(hdc,x+width-i,y+height-i,NULL);
LineTo(hdc,x+width-i,y+i);
MoveToEx(hdc,x+width-i,y+height-i,NULL);
LineTo(hdc,x+i,y+height-i);
}
DeleteObject(hpen1);
DeleteObject(hpen2);
}
//初始化box
void InitBox()
{
numberOpened = 0;
time = 0;
for(int i=0;i<ROWS;i++)
for(int j=0;j<COLS;j++)
{
box[i][j].containMine = false;
box[i][j].isOpened = false;
box[i][j].roundMineNO = 0;
}
}
//计算周围类的个数
void ComputeRoundMineNo()
{
for(int i=0;i<ROWS;i++)
for(int j=0;j<COLS;j++)
{
if(i>0&&box[i-1][j].containMine==true)
{
box[i][j].roundMineNO++;
}
if(i>0&&j<COLS-1&&box[i-1][j+1].containMine == true)
{
box[i][j].roundMineNO++;
}
if(j<COLS-1&&box[i][j+1].containMine == true)
{
box[i][j].roundMineNO++;
}
if(i<ROWS-1 && j<COLS && box[i+1][j+1].containMine == true)
{
box[i][j].roundMineNO++;
}
if(i<ROWS-1 && box[i+1][j].containMine == true)
{
box[i][j].roundMineNO++;
}
if(i<ROWS-1 && j>0 && box[i+1][j-1].containMine == true)
{
box[i][j].roundMineNO++;
}
if(j>0 && box[i][j-1].containMine == true)
{
box[i][j].roundMineNO++;
}
if(i>0 && j>0 && box[i-1][j-1].containMine == true)
{
box[i][j].roundMineNO++;
}
}
}
//随机布雷
void RandomSetMines()
{
int row,col;
srand((UINT)GetCurrentTime());
for(int i=0;i<mineNumber;)
{
row=rand()%ROWS;
col=rand()%COLS;
if(box[row][col].containMine != true)
{
box[row][col].containMine = true;
i++;
}
}
}
//自动打开box
void AutoOpenBoxes(HDC &hdc,int x,int y)
{
if(x >= 0 && y >= 0 && x < ROWS && y < COLS &&
box[x][y].roundMineNO == 0&& !allRoundIsOpened(x,y))
{
drawRect(hdc,x-1,y);
drawRect(hdc,x-1,y+1);
drawRect(hdc,x,y+1);
drawRect(hdc,x+1,y+1);
drawRect(hdc,x+1,y);
drawRect(hdc,x+1,y-1);
drawRect(hdc,x,y-1);
drawRect(hdc,x-1,y-1);
AutoOpenBoxes(hdc,x-1,y);
AutoOpenBoxes(hdc,x-1,y+1);
AutoOpenBoxes(hdc,x,y+1);
AutoOpenBoxes(hdc,x+1,y+1);
AutoOpenBoxes(hdc,x+1,y);
AutoOpenBoxes(hdc,x+1,y-1);
AutoOpenBoxes(hdc,x,y-1);
AutoOpenBoxes(hdc,x-1,y-1);
}
}
//绘制雷区
void DrawMineArea(HDC &hdc)
{
char szBuffer[2];
int xStart = mineRect.left;
int yStart = mineRect.top;
RECT rect0;
HDC hdcMem;
hdcMem = CreateCompatibleDC(hdc);
SelectObject(hdcMem,hBitmap4);
for(int i = 0; i < ROWS; i++)
{
for(int j = 0; j < COLS; j++)
{
if(!box[i][j].isOpened)
DrawBorder(hdc,xStart,yStart,BOX_WIDTH-2,BOX_HEIGHT-2,SHADOW_WIDTH2,
color1,color2,true);
else
{
DrawBorder(hdc,xStart,yStart,BOX_WIDTH-2,BOX_HEIGHT-2,SHADOW_WIDTH2,
color3,color3,true);
DrawBorder(hdc,xStart,yStart,BOX_WIDTH,BOX_HEIGHT,SHADOW_WIDTH1,
color4,color4,true);
rect0.left = mineRect.left + BOX_WIDTH * j;
rect0.right = rect0.left + BOX_WIDTH;
rect0.top = mineRect.top + BOX_HEIGHT * i;
rect0.bottom = rect0.top + BOX_HEIGHT;
if(box[i][j].containMine)
{
BitBlt(hdc,rect0.left+2,rect0.top+2,BOX_WIDTH-2,BOX_HEIGHT-2,hdcMem,2,2,SRCCOPY);
}
else if(box[i][j].roundMineNO != 0)
{
wsprintf(szBuffer,TEXT("%d"),box[i][j].roundMineNO);
//输出周围雷的个数
DrawText(hdc,szBuffer,-1,&rect0,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
}
}
xStart += BOX_WIDTH;
}
yStart += BOX_HEIGHT;
xStart = SHADOW_WIDTH3+BORDER+SHADOW_WIDTH2;
}
DeleteDC(hdcMem);
}
//更新窗口,并reset
void UpdateTheWindow(HWND &hwnd,int rows,int cols,int mineNO)
{
ROWS = rows;
COLS = cols;
mineNumber = mineNO;
mineRect.left = SHADOW_WIDTH3+BORDER+SHADOW_WIDTH2;
mineRect.right =mineRect.left + BOX_WIDTH * COLS;
mineRect.top = SHADOW_WIDTH3+2*BORDER+RESERVED_AREA+3*SHADOW_WIDTH2;
mineRect.bottom = mineRect.top + BOX_HEIGHT * ROWS;
resetButtonRect.left = SHADOW_WIDTH3+BORDER+(mineRect.right-mineRect.left)/2-RESERVED_AREA/4;
resetButtonRect.right = resetButtonRect.left + 2 * RESERVED_AREA / 3 + 2;
resetButtonRect.top = SHADOW_WIDTH3+BORDER + RESERVED_AREA / 4 - 2;
resetButtonRect.bottom = resetButtonRect.top + 2 * RESERVED_AREA / 3 + 4;
int cx = BOX_WIDTH * COLS + 2 * SHADOW_WIDTH3 + 2 * SHADOW_WIDTH2 + 2 * iSM_BorderX + 2 * BORDER;
int cy = BOX_HEIGHT * ROWS + 2 * SHADOW_WIDTH3 + 4 * SHADOW_WIDTH2 + 2 * iSM_BorderY + 3 * BORDER + RESERVED_AREA+iSM_CaptionY+iSM_MenuY;
box = new Box* [ROWS];
for(int k=0;k<ROWS;k++)
box[k] = new Box[COLS];
InitBox();
RandomSetMines();
ComputeRoundMineNo();
MoveWindow(hwnd,(icxSrc-cx)/2,(icySrc-cy)/2,cx,cy,true);
InvalidateRect(hwnd,NULL,TRUE);
UpdateWindow(hwnd);
}
//自动打开时,重绘box矩形区域
void drawRect(HDC &hdc,int x,int y)
{
RECT rect1;
TCHAR szBuffer[2]={"0"};
if(x<0 || y<0 || x >= ROWS || y >= COLS)
return;
rect1.left = mineRect.left + BOX_WIDTH * y;
rect1.right = rect1.left + BOX_WIDTH;
rect1.top = mineRect.top + BOX_HEIGHT * x;
rect1.bottom = rect1.top + BOX_HEIGHT;
if(!box[x][y].isOpened)
{
DrawBorder(hdc,rect1.left,rect1.top,
BOX_WIDTH-2,BOX_HEIGHT-2,SHADOW_WIDTH2,color3,color3,true);
DrawBorder(hdc,rect1.left,rect1.top,
BOX_WIDTH,BOX_HEIGHT,SHADOW_WIDTH1,color4,color4,true);
if(!box[x][y].containMine && box[x][y].roundMineNO != 0)
{
wsprintf(szBuffer,TEXT("%d"),box[x][y].roundMineNO);
DrawText(hdc,szBuffer,-1,&rect1,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
}
box[x][y].isOpened = true;
numberOpened ++;
if(numberOpened == ROWS * COLS - mineNumber )
{
MessageBox (NULL, TEXT ("祝贺你赢了!"),TEXT("扫雷-游戏"), MB_ICONWARNING) ;
}
}
}
//判断周围的所有box是否已经open
bool allRoundIsOpened(int x,int y)
{
bool flag = true;
if(x > 0 && !box[x-1][y].isOpened)
flag = false;
if(x > 0 && y < COLS-1 && !box[x-1][y+1].isOpened)
flag = false;
if(y < COLS-1 && !box[x][y+1].isOpened)
flag = false;
if(x < ROWS-1 && y< COLS-1 && !box[x+1][y+1].isOpened)
flag = false;
if(x < ROWS-1 && !box[x+1][y].isOpened)
flag = false;
if(x < ROWS-1 && y > 0 && !box[x+1][y-1].isOpened)
flag = false;
if(y > 0 && !box[x][y-1].isOpened)
flag = false;
if(x > 0 && y > 0 && !box[x-1][y-1].isOpened)
flag = false;
return flag;
}
//宣告游戏结束
void ReportGameOver(HDC &hdc,HBITMAP &hBitmap1,HBITMAP &hBitmap2)
{
RECT rect;
HDC hdcMem;
hdcMem = CreateCompatibleDC(hdc);
SelectObject(hdcMem,hBitmap2);
DrawResetButton(hdc,hBitmap1);
for(int k=0;k<ROWS;k++)
for(int l=0;l<COLS;l++)
{
if(box[k][l].containMine)//点到雷后,使所有的lei显现
{
box[k][l].isOpened = true;
rect.left =mineRect.left + BOX_WIDTH * l;
rect.top = mineRect.top + BOX_HEIGHT * k;
rect.right = rect.left + BOX_WIDTH;
rect.bottom = rect.top + BOX_HEIGHT;
DrawBorder(hdc,rect.left,rect.top,BOX_WIDTH-2,BOX_HEIGHT-2,SHADOW_WIDTH2,color3,color3,false);
DrawBorder(hdc,rect.left,rect.top,BOX_WIDTH,BOX_HEIGHT,SHADOW_WIDTH1,color4,color4,false);
BitBlt(hdc,rect.left+2,rect.top+2,BOX_WIDTH-2,BOX_HEIGHT-2,hdcMem,2,2,SRCCOPY);
}
}
DeleteDC(hdcMem);
MessageBox (NULL, TEXT ("游戏结束"),TEXT("扫雷-游戏"), MB_ICONWARNING) ;
}
//绘制显示雷的个数的区域
void DisplayMineNo(HDC &hdc)
{
RECT tempRect;
HPEN hPen;
int t = 0,temp = mineNumber;
HBRUSH hBrush;
tempRect.left = mineRect.left + (mineRect.right - mineRect.left) / 20 ;
tempRect.right = tempRect.left + 52;
tempRect.top = SHADOW_WIDTH3+BORDER+RESERVED_AREA/5;
tempRect.bottom = tempRect.top + 24;
DrawBorder(hdc,tempRect.left,tempRect.top,tempRect.right - tempRect.left ,
tempRect.bottom - tempRect.top ,SHADOW_WIDTH2,color1,color2,false);
hPen = CreatePen(PS_SOLID,3,RGB(0,0,0));
SelectObject(hdc,hPen);
hBrush = CreateSolidBrush(RGB(0,0,0));
SelectObject(hdc,hBrush);
Rectangle(hdc,tempRect.left+2,tempRect.top+2,tempRect.right-1, tempRect.bottom-1 );
for(int i=0;i<3;i++)
{
SetViewportOrgEx(hdc,tempRect.right-15-t ,tempRect.top+2,NULL);
DisplayADigit(hdc,temp%10);
temp /= 10;
t+=15;
}
SetViewportOrgEx(hdc,0,0,NULL);
DeleteObject(hPen);
DeleteObject(hBrush);
}
//绘制计时显示区域
void DrawTimeArea(HDC &hdc)
{
RECT tempRect;
HBRUSH hBrush;
HPEN hPen;
int t = 0;
int temp = time;
tempRect.right = mineRect.right - (mineRect.right - mineRect.left) / 20 ;
tempRect.left = tempRect.right - 52;
tempRect.top = SHADOW_WIDTH3+BORDER+RESERVED_AREA/5;
tempRect.bottom = tempRect.top + 24;
DrawBorder(hdc,tempRect.left,tempRect.top,tempRect.right - tempRect.left ,
tempRect.bottom - tempRect.top ,SHADOW_WIDTH2,color1,color2,false);
hPen = CreatePen(PS_SOLID,3,RGB(0,0,0));
SelectObject(hdc,hPen);
hBrush = CreateSolidBrush(RGB(0,0,0));
SelectObject(hdc,hBrush);
Rectangle(hdc,tempRect.left+2,tempRect.top+2,tempRect.right-1, tempRect.bottom-1 );
for(int i=0;i<3;i++)
{
SetViewportOrgEx(hdc,tempRect.right-15-t ,tempRect.top+2,NULL);
DisplayADigit(hdc,temp%10);
temp /= 10;
t+=15;
}
SetViewportOrgEx(hdc,0,0,NULL);
DeleteObject(hPen);
DeleteObject(hBrush);
}
//显示时间
void DisplayTime(HDC &hdc)
{
RECT tempRect;
HBRUSH hBrush;
HPEN hPen;
int t = 0;
int temp = time;
tempRect.right = mineRect.right - (mineRect.right - mineRect.left) / 20 ;
tempRect.left = tempRect.right - 52;
tempRect.top = SHADOW_WIDTH3+BORDER+RESERVED_AREA/5;
tempRect.bottom = tempRect.top + 24;
hPen = CreatePen(PS_SOLID,3,RGB(0,0,0));
SelectObject(hdc,hPen);
hBrush = CreateSolidBrush(RGB(0,0,0));
SelectObject(hdc,hBrush);
Rectangle(hdc,tempRect.left+2,tempRect.top+2,tempRect.right-1, tempRect.bottom-1 );
for(int i=0;i<3;i++)
{
SetViewportOrgEx(hdc,tempRect.right-15-t ,tempRect.top+2,NULL);
DisplayADigit(hdc,temp%10);
temp /= 10;
t+=15;
}
SetViewportOrgEx(hdc,0,0,NULL);
DeleteObject(hPen);
DeleteObject(hBrush);
}
//绘制重置按钮
void DrawResetButton(HDC &hdc,HBITMAP &hBitmap)
{
int xPos = SHADOW_WIDTH3+BORDER+(mineRect.right-mineRect.left)/2-RESERVED_AREA/4;
int yPos = SHADOW_WIDTH3+BORDER+RESERVED_AREA/4-2;
int width = 2*RESERVED_AREA/3 + 2;
int height = width + 2;
HDC hdcMem;
DrawBorder(hdc, xPos,
yPos,width,height,SHADOW_WIDTH2,color1,color2,true);
hdcMem = CreateCompatibleDC(hdc);
SelectObject(hdcMem,hBitmap);
BitBlt(hdc,xPos+2,yPos+2,width-2,height-2,hdcMem,0,0,SRCCOPY);
DeleteDC(hdcMem);
}
//显示一个八段的数字
void DisplayADigit(HDC hdc,int iNumber)
{
static bool fSevenSegment[11][8] = {
1,1,1,0,1,1,1,0, //0
0,0,1,0,0,1,0,0, //1
1,0,1,1,1,0,1,1, //2
1,0,1,1,0,1,1,1, //3
0,1,1,1,0,1,0,1, //4
1,1,0,1,0,1,1,1, //5
1,1,0,1,1,1,1,1, //6
1,0,1,0,0,1,0,0, //7
1,1,1,1,1,1,1,1, //8
1,1,1,1,0,1,1,1, //9
0,0,0,1,0,0,0,1 //10(负号)
};
static POINT ptSegment[8][4] = {
{1,0,9,0,7,2,3,2}, //0
{0,1,2,3,2,7,0,9}, //1
{8,3,10,1,10,9,8,7}, //2
{1,10,2,9,8,9,9,10}, //3
{0,11,2,13,2,17,0,19}, //4
{8,13,10,11,10,19,8,17}, //5
{1,20,3,18,7,18,9,20}, //6
{1,10,2,11,8,11,9,10} //7
};
int iSeg;
HPEN hPen;
HBRUSH hBrush;
hPen = CreatePen(PS_SOLID,1,RGB(255,0,0));
hBrush = CreateSolidBrush(RGB(255,0,0));
SelectObject(hdc,hPen);
SelectObject(hdc,hBrush);
for(iSeg=0;iSeg<8;++iSeg){
if(fSevenSegment[iNumber][iSeg])
Polygon(hdc,ptSegment[iSeg],4);
}
DeleteObject(hPen);
DeleteObject(hBrush);
}