///////////////////////////////////////////////////////////////////////////////////////////////////////////
// Lei.cpp
// 扫雷程序源代码 v1.0
//
// 作者:山东大学威海分校数学系 曹祝楼
// Copyrights 2005, All rights reserved
// 最后修改:2005-4-22
///////////////////////////////////////////////////////////////////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <stdlib.h> //rand()函数
#include <stdio.h> //sprintf();
#include <vector>
#include <string>
#include <list>
#include "resource.h"
// 定义 ////////////////////////////////////////////////////////////////////////////////////////////
//窗口结构名称
#define WINDOW_CLASS_NAME "WINCLASS1"
//定义行的个数和列的个数
#define M 10
#define N 10
//定义雷的个数
#define NUM 10
//计时器
#define ID_TIMER1 1
#define WM_USER_Bomb WM_USER+101
#define WM_USER_Success WM_USER+102
using namespace std;
enum st{Init,Open,Sign}; //显示方块,有三种可能,初始,打开,标记有雷
//每一格的状态
typedef struct
{
bool IsEmpty; // 是否有雷,有雷false,无雷true
bool IsUsed; //当前方块是否调用过OpenBlank ,用过true,没有false
st con; //显示方块,有三种可能
int num; //周围八个方向雷的个数
}state;
//排行榜高手的状态
typedef struct
{
char name[12]; //姓名
int grade; //成绩
}hero;
// 全局变量 ////////////////////////////////////////////////////////////////////////////////////////////
//主窗口句柄
HWND hMainWindow = NULL;
//应用程序句柄
HINSTANCE hApp = NULL;
//屏幕的宽度和高度
int HEIGHT;
int WIDTH;
//定义方块的大小,根据当前机器具体设置
int LEN;
//每方块状态
state sPlane[M][N];
//每一格的对应的矩形
RECT Plane[M][N];
//缓冲区
char buffer[80];
//当前还有多少个雷没有扫
int g_Bomb=NUM;
//当前打开了多少方块
int g_Rect=0;
//当前花费的时间
int time=0;
//记录结束时的时间
int time_end;
//高手排行榜
hero top[5];
//当前高手个数
int hero_num=0;
//玩家姓名
char name[12];
//玩家如果能够进入排行榜,记录玩家的排行
int hero_pos;
string a("sssss");
///////////////////////////////////////////////////////////////////////////////////////////////////
///函数声明/////////////////////////////////////////////////////////////////////////////////////////
//读取成绩信息
void ReadScore();
//储存成绩信息
void SaveScore();
//初始化各个方块的物理位置
void InitRect();
//初始化各个方块的状态
void InitPlane();
//画全体方格
void DrawPlane();
//画辅助信息
void DrawInfo();
//统计i,j这个位置周围雷的个数
int Count(int i,int j);
//鼠标左键单击处理函数,打开方块
void OnLButton(int xPos,int yPos);
//鼠标左键双击处理函数,如果当前方块没有雷且周围没有雷
//双击打开周围八个
void OnLButtonDb(int xPos,int yPos);
//鼠标右键单击处理函数,标识一个方块有雷
void OnRButton(int xPos,int yPos);
//鼠标右键双击处理函数,取消一个方块有雷的标识
void OnRButtonDb(int xPos,int yPos);
//打开所有连在一起的空方块(也就是周围没有雷的方块)
int OpenBlank(int i,int j);
//判断当前成绩是否可以进入top 5
bool Top(int grade);
//输入姓名对话框的窗口处理函数
LRESULT CALLBACK NameProc(HWND, UINT, WPARAM, LPARAM);
// 函数实现///// //////////////////////////////////////////////////////////////////////////////
//窗口处理函数
LRESULT CALLBACK WindowProc(HWND hwnd,
UINT msg,
WPARAM wparam,
LPARAM lparam)
{
PAINTSTRUCT ps;
HDC hdc;
switch(msg)
{
case WM_CREATE:
{
// MessageBox(NULL,a.c_str(),"ss",MB_OK);
//创建定时器,每隔1000毫秒也就是1秒产生一个定时信息
SetTimer(hwnd,ID_TIMER1,1000,NULL);
return(0);
} break;
case WM_PAINT:
{
hdc = BeginPaint(hwnd,&ps);
DrawPlane();
DrawInfo();
EndPaint(hwnd,&ps);
return(0);
} break;
case WM_TIMER :
{
//每隔一秒钟time 加1
time+=1;
//重画窗口
DrawInfo();
}
break;
case WM_USER_Bomb:
{
//重画窗口
DrawPlane();
DrawInfo();
KillTimer(hwnd,ID_TIMER1);
MessageBox(hwnd," 遇上炸弹了!","失败",MB_OK);
//重新初始化
InitPlane();
time=0;
g_Bomb=NUM;
g_Rect=0;
SetTimer(hwnd,ID_TIMER1,1000,NULL);
//重画窗口
DrawPlane();
DrawInfo();
}
break;
case WM_USER_Success:
{
//取消定时器
KillTimer(hwnd,ID_TIMER1);
if(Top(time_end))//如果当前成绩可以进入高手排行榜
{
sprintf(buffer,"你用了%d秒,可以进入top 5!",time_end);
MessageBox(hwnd,buffer,"成功",MB_OK);
DialogBox(hApp, (LPCTSTR)IDD_NAME, hwnd, (DLGPROC)NameProc);
}
else
{
sprintf(buffer,"你用了%d秒",time_end);
MessageBox(hwnd,buffer,"成功",MB_OK);
}
//重新初始化
InitPlane();
time=0;
g_Bomb=NUM;
g_Rect=0;
SetTimer(hwnd,ID_TIMER1,1000,NULL);
//重画窗口
DrawInfo();
DrawPlane();
}
break;
case WM_RBUTTONDOWN:
{
int y = LOWORD(lparam);
int x = HIWORD(lparam);
OnRButton(x,y);
//重画窗口
DrawPlane();
DrawInfo();
}break;
case WM_RBUTTONDBLCLK:
{
int x = HIWORD(lparam);
int y = LOWORD(lparam);
OnRButtonDb(x,y);
//重画窗口
DrawPlane();
DrawInfo();
}break;
case WM_LBUTTONDBLCLK:
{
int x = HIWORD(lparam);
int y = LOWORD(lparam);
OnLButtonDb(x,y);
//重画窗口
DrawPlane();
DrawInfo();
}break;
case WM_LBUTTONDOWN:
{
int y = LOWORD(lparam);
int x = HIWORD(lparam);
OnLButton(x,y);
//重画窗口
DrawPlane();
DrawInfo();
}break;
case WM_DESTROY:
{
PostQuitMessage(0);
return(0);
} break;
default:break;
}
return (DefWindowProc(hwnd, msg, wparam, lparam));
}
///////////////////////////////////////////////////////////////////////////////////////////////
//输入姓名对话框的窗口处理函数
LRESULT CALLBACK NameProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDOK:
{
//取得玩家的姓名
HWND hName = GetDlgItem (hDlg, IDC_Name);
GetWindowText(hName,name,11);
//在正确的位置输入玩家的成绩和姓名
top[hero_pos].grade=time_end;
sprintf(top[hero_pos].name,name);
//成绩存入硬盘
SaveScore();
}
case IDCANCEL:
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
}
break;
}
return FALSE;
}
// ///////////////////////////////////////////////////////////////////////////////////////////////
// windows入口函数
int WINAPI WinMain( HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)
{
WNDCLASSEX winclass;
HWND hwnd;
MSG msg;
winclass.cbSize = sizeof(WNDCLASSEX); //结构体变量大小
winclass.style = CS_DBLCLKS | CS_OWNDC |
CS_HREDRAW | CS_VREDRAW; //风格
winclass.lpfnWndProc = WindowProc; //窗口处理函数
winclass.cbClsExtra = 0; //多余Class信息
winclass.cbWndExtra = 0; //多余