当前位置:文档之家› 课程设计扫雷小游戏

课程设计扫雷小游戏

课程设计报告课程名称:面向对象程序设计C++设计题目:扫雷小游戏专业:计算机科学与技术姓名:学号:指导教师:李晓虹2016 年 1 月 6日目录一、系统需求分析 (3)1.1功能需求分析 (3)1.2 运行环境需求 (3)1.3硬件需求 (3)1.4基本素材需求 (4)二、总体设计 (4)三、详细设计 (5)3.1 具体要求如下: (5)3.2游戏流程 (6)四、系统调试 (9)五、结果分析 (9)六、总结 (9)一、系统需求分析随着现在生活节奏的加快,人们在工作学习之余需要一个轻松娱乐的放松环境。

因此我编写此软件的目的,一方面作为初学者来了解C++环境下的小程序开发,另一方面使用户能在娱乐休闲的同时拓展思维能力。

1.1功能需求分析1.2 运行环境需求基本操作系统:win7,win XP1.3硬件需求a.处理器型号:奔腾III及同等型号以上处理器b.内存容量:512MB以上内存(可运行数据库管理系统)c.外存容量:5G以上硬盘空间d.联机或脱机:脱机e.输入及输出设备的型号和数量:鼠标、彩色显示器1.4基本素材需求二、总体设计扫雷是单人计算机游戏。

游戏的用户界面由小方格组成的战场构成。

当游戏开始时,计算机将固定的地雷数随机的放到战场的方格。

此游戏还允许玩家指定战场中的地雷数。

参考Windows 操作系统提供的扫雷游戏,改进扫雷游戏程序,增加以下功能:在主界面中添加一个菜单栏,菜单栏中包括游戏和帮助两个菜单,其中游戏菜单中设置初级、中级、高级、自定义、声音、扫雷英雄榜这几个菜单项,帮助菜单中设置游戏规则和制作人员两个菜单项。

背景说明:a.软件名称:扫雷b.用户:所有扫雷游戏爱好者三、详细设计3.1 具体要求如下:(1)扫雷游戏分为初级、中级和高级三个级别。

单击游戏菜单可以选择“初级”、“中级”和“高级”。

三个等级的区别在于,其雷的总数不一样,分别为40、80、120个雷,在相同数目的格子中,雷的数目愈多,其难度自然就愈大。

(2)选择级别后将出现相应级别的扫雷区域,这时用户使用鼠标左键单击‘“开始”便启动计时器。

(3)用户要揭开某个方块,可左键单击它。

若所揭方块下有雷,用户便输了这一局,若所揭方块下无雷,则显示一个数字,该数字代表方块的周围的8个方块中共有多少颗雷。

(4)如果用户认为某个方块下埋着雷,单击右键可以在方块上标识一个用户认为是雷的图标,即给出一个扫雷标记。

用户每标记出一个扫雷标记(无论用户的标记是否正确),程序将显示的剩余雷数减少一个。

(5)当用户点中雷时,将有提示出现,胜利时,也有提示出现。

游戏的基本步骤为:开始:按左键开始游戏,单击表情按钮或菜单重新开始;左键:按下时,是雷则结束,非雷则显示数字;数字:表示此数字周围一圈八个格子中雷的数目;右键:奇数次按下,则用小红旗标记,表示此处是雷;偶数次按下,表示对上次的否定;结束:左键单击到雷则结束,标记出所有的雷则结束;3.2游戏流程运行截图游戏开始时截图,点击游戏菜单下的“开始”可以运行,或者点击开始。

右边有计时器, 左边是分数。

开始游戏选择游戏难易程度中级低级高级游戏是否胜利失败胜利游戏结束这是游戏中途的截图这是游戏失败的截图四、系统调试在编写程序时,不免会出现这样那样的错误,这时需要我们从各个方向来解决。

在调试这个游戏时,遇到一些语法和逻辑方面的问题。

但是都得到了解决。

五、结果分析能够顺利地运行程序六、总结1.通过设计实验,能综合运用了所学知识,编程解决实际问题,是所学知识掌握得更系统扎实。

2.现自己的知识的欠缺和能力的不足,使我们能够了解自己的不足,能及时补救,使自己得到不断完善。

3.通过设计实验,对所学知识有了更深的理解,了解所学知识在实际生活中的运用。

4.通过这次设计的总结,我会在以后的学习中增强自己理论与实践相结合的能力。

附件:部分程序源代码:DlgCustom.cpp:#include "stdafx.h"#include "mine.h"#include "DlgHero.h"#include "MineWnd.h"#include "MineDefs.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif///////////////////////////////////////////////////////////////////////////// CDlgHero::CDlgHero(CWnd* pParent /*=NULL*/) : CDialog(CDlgHero::IDD, pParent){//{{AFX_DATA_INIT(CDlgHero)m_szBHolder = _T("");m_szEHolder = _T("");m_szBRecord = _T("");m_szERecord = _T("");m_szIHolder = _T("");m_szIRecord = _T("");//}}AFX_DATA_INIT}void CDlgHero::DoDataExchange(CDataExchange* pDX) {CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CDlgHero)DDX_Text(pDX, IDC_B_H, m_szBHolder);DDX_Text(pDX, IDC_E_H, m_szEHolder);DDX_Text(pDX, IDC_B_R, m_szBRecord);DDX_Text(pDX, IDC_E_R, m_szERecord);DDX_Text(pDX, IDC_I_H, m_szIHolder);DDX_Text(pDX, IDC_I_R, m_szIRecord);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CDlgHero, CDialog)//{{AFX_MSG_MAP(CDlgHero)ON_BN_CLICKED(IDC_RESET, OnReset)//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////void CDlgHero::SetBHolder(CString holder){m_szBHolder = holder;}void CDlgHero::SetBRecord(UINT record){m_szBRecord.Format("%d秒", record);}void CDlgHero::SetIHolder(CString holder){m_szIHolder = holder;}void CDlgHero::SetIRecord(UINT record){m_szIRecord.Format("%d秒", record);}void CDlgHero::SetEHolder(CString holder){m_szEHolder = holder;}void CDlgHero::SetERecord(UINT record){m_szERecord.Format("%d秒", record);}void CDlgHero::OnReset(){CMineWnd *pMine = (CMineWnd*)AfxGetMainWnd();pMine->ResetRecord();m_szBHolder = DEFAULT_HOLDER;m_szBRecord.Format("%d秒", DEFAULT_RECORD);m_szIHolder = DEFAULT_HOLDER;m_szIRecord.Format("%d秒", DEFAULT_RECORD);m_szEHolder = DEFAULT_HOLDER;m_szERecord.Format("%d秒", DEFAULT_RECORD);UpdateData(FALSE);}DlgCustom.cpp#include "stdafx.h"#include "mine.h"#include "DlgCustom.h"#include "MineWnd.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CDlgCustom dialogCDlgCustom::CDlgCustom(CWnd* pParent /*=NULL*/) : CDialog(CDlgCustom::IDD, pParent){//{{AFX_DATA_INIT(CDlgCustom)m_uHeight = 0;m_uNumber = 0;m_uWidth = 0;//}}AFX_DATA_INIT}void CDlgCustom::DoDataExchange(CDataExchange* pDX) {CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CDlgCustom)DDX_Text(pDX, IDC_HEIGHT, m_uHeight);DDX_Text(pDX, IDC_NUMBER, m_uNumber);DDX_Text(pDX, IDC_WIDTH, m_uWidth);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CDlgCustom, CDialog) //{{AFX_MSG_MAP(CDlgCustom)//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////void CDlgCustom::OnOK(){UpdateData();if (m_uWidth < 9) m_uWidth = 9;if (m_uWidth > 30) m_uWidth = 30;if (m_uHeight < 9) m_uHeight = 9;if (m_uHeight > 24) m_uHeight = 24;if (m_uNumber < 10) m_uNumber = 10;if (m_uNumber > m_uWidth * m_uHeight) m_uNumber = m_uWidth * m_uHeight - 1;CMineWnd *pMine = (CMineWnd*)AfxGetMainWnd();pMine->SetCustom(m_uWidth, m_uHeight, m_uNumber);CDialog::OnOK();}void CDlgCustom::InitData(UINT xNum, UINT yNum, UINT mNum){m_uWidth = xNum;m_uHeight = yNum;m_uNumber = mNum;}DlgNewRecord.cpp#include "stdafx.h"#include "mine.h"#include "DlgNewRecord.h"#include "MineDefs.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////CDlgNewRecord::CDlgNewRecord(CWnd* pParent /*=NULL*/): CDialog(CDlgNewRecord::IDD, pParent){//{{AFX_DATA_INIT(CDlgNewRecord)m_szName = _T("匿名");m_szDesc = _T("");//}}AFX_DATA_INIT}void CDlgNewRecord::DoDataExchange(CDataExchange* pDX) {CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CDlgNewRecord)DDX_Text(pDX, IDC_EDIT_NAME, m_szName);DDX_Text(pDX, IDC_DESCRIBE, m_szDesc);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CDlgNewRecord, CDialog)//{{AFX_MSG_MAP(CDlgNewRecord)//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////void CDlgNewRecord::SetLevel(UINT level){CString szLevel;if (level == LEVEL_PRIMARY) szLevel = "初级";else if (level == LEVEL_SECONDRY) szLevel = "中级";else if (level == LEVEL_ADV ANCE) szLevel = "高级";m_szDesc.Format("已破%s记录\n\r请留尊姓大名", szLevel); }CString CDlgNewRecord::GetName(){return m_szName;}Mine.cpp#include "stdafx.h"#include "Mine.h"#include "MineDefs.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////BEGIN_MESSAGE_MAP(CMineApp, CWinApp)//{{AFX_MSG_MAP(CMineApp)//}}AFX_MSGEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////CMineApp::CMineApp(){}/////////////////////////////////////////////////////////////////////////////CMineApp theApp;const CString className = _T("MineClass");/////////////////////////////////////////////////////////////////////////////BOOL CMineApp::InitInstance(){SetRegistryKey("CSER_513_2");m_uXMineNum = GetProfileInt(GAME_SETTING, CUSTOM_XNUM, PRIMARY_XNUM);m_uYMineNum = GetProfileInt(GAME_SETTING, CUSTOM_YNUM, PRIMARY_YNUM);//定义并注册MineWnd窗口m_pMineWnd = new CMineWnd();WNDCLASS wc;ZeroMemory(&wc, sizeof(wc));wc.hInstance = AfxGetInstanceHandle();wc.lpfnWndProc = ::DefWindowProc;wc.hbrBackground = NULL;wc.hCursor = LoadCursor(IDC_ARROW);wc.hIcon = LoadIcon(IDR_MAINFRAME);wc.lpszClassName = className;wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);// register the minewnd class//注册窗口if (!AfxRegisterClass(&wc)){AfxMessageBox("注册类失败!");return FALSE;}// get the minewnd coordinates, width and heightUINT uWidth = DEFAULT_FRAME_X + m_uXMineNum * MINE_WIDTH +LINE_WIDTH_0 * 3 + SIDE_WIDTH_0 + SIDE_WIDTH_1;UINT uHeight = DEFAULT_FRAME_Y + m_uYMineNum * MINE_HEIGHT +LINE_WIDTH_0 * 3 + SIDE_WIDTH_0 * 2 + SIDE_WIDTH_1 + SHELL_S_H;UINT uXPos = GetSystemMetrics(SM_CXSCREEN) / 2 - uWidth / 2;UINT uYPos = GetSystemMetrics(SM_CYSCREEN) / 2 - uHeight / 2;//创建窗口if ( !m_pMineWnd->CreateEx( NULL, className, _T("扫雷"), WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,uXPos, uYPos, uWidth, uHeight,NULL, NULL) ){AfxMessageBox("创建主窗口失败!");return FALSE;}// 绑定该窗口为主窗口m_pMainWnd = m_pMineWnd;//显示窗口m_pMineWnd->ShowWindow(SW_NORMAL);return TRUE;}int CMineApp::ExitInstance(){delete m_pMineWnd;return CWinApp::ExitInstance();}Mines.cpp#include "stdafx.h"#include "Mine.h"#include "MineDefs.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////BEGIN_MESSAGE_MAP(CMineApp, CWinApp)//{{AFX_MSG_MAP(CMineApp)//}}AFX_MSGEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////CMineApp::CMineApp(){}/////////////////////////////////////////////////////////////////////////////CMineApp theApp;const CString className = _T("MineClass");/////////////////////////////////////////////////////////////////////////////BOOL CMineApp::InitInstance(){SetRegistryKey("CSER_513_2");m_uXMineNum = GetProfileInt(GAME_SETTING, CUSTOM_XNUM, PRIMARY_XNUM);m_uYMineNum = GetProfileInt(GAME_SETTING, CUSTOM_YNUM, PRIMARY_YNUM);//定义并注册MineWnd窗口m_pMineWnd = new CMineWnd();WNDCLASS wc;ZeroMemory(&wc, sizeof(wc));wc.hInstance = AfxGetInstanceHandle();wc.lpfnWndProc = ::DefWindowProc;wc.hbrBackground = NULL;wc.hCursor = LoadCursor(IDC_ARROW);wc.hIcon = LoadIcon(IDR_MAINFRAME);wc.lpszClassName = className;wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);// register the minewnd class//注册窗口if (!AfxRegisterClass(&wc)){AfxMessageBox("注册类失败!");return FALSE;}// get the minewnd coordinates, width and heightUINT uWidth = DEFAULT_FRAME_X + m_uXMineNum * MINE_WIDTH +LINE_WIDTH_0 * 3 + SIDE_WIDTH_0 + SIDE_WIDTH_1;UINT uHeight = DEFAULT_FRAME_Y + m_uYMineNum * MINE_HEIGHT +LINE_WIDTH_0 * 3 + SIDE_WIDTH_0 * 2 + SIDE_WIDTH_1 + SHELL_S_H;UINT uXPos = GetSystemMetrics(SM_CXSCREEN) / 2 - uWidth / 2;UINT uYPos = GetSystemMetrics(SM_CYSCREEN) / 2 - uHeight / 2;//创建窗口if ( !m_pMineWnd->CreateEx( NULL, className, _T("扫雷"),WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,uXPos, uYPos, uWidth, uHeight,NULL, NULL) ){AfxMessageBox("创建主窗口失败!");return FALSE;}// 绑定该窗口为主窗口m_pMainWnd = m_pMineWnd;//显示窗口m_pMineWnd->ShowWindow(SW_NORMAL);return TRUE;}int CMineApp::ExitInstance(){AfxMessageBox("A");delete m_pMineWnd;return CWinApp::ExitInstance();}MineWnds.cpp#include "stdafx.h"#include "Mine.h"#include "MineWnd.h"#include "MineDefs.h"#include "Mmsystem.h"#include "DlgNewRecord.h"#include "DlgHero.h"#include "DlgCustom.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifextern CMineApp theApp;#define ID_TIMER_EVENT WM_USER + 1/////////////////////////////////////////////////////////////////////////////CMineWnd::CMineWnd(){m_pSndDead = NULL;m_pSndVictory = NULL;m_pSndClock = NULL;m_uTimer = 0;m_brsBG.CreateSolidBrush(COLOR_GRAY);LoadConfig();if (m_bSoundful) LoadWaveSrc();InitGame();}CMineWnd::~CMineWnd(){FreeMines();FreeWaveSrc();SaveConfig();}BEGIN_MESSAGE_MAP(CMineWnd, CWnd)//{{AFX_MSG_MAP(CMineWnd)ON_WM_PAINT()ON_WM_SHOWWINDOW()ON_WM_TIMER()ON_WM_LBUTTONUP()ON_WM_RBUTTONUP()ON_WM_LBUTTONDOWN()ON_WM_RBUTTONDOWN()ON_WM_MOUSEMOVE()ON_COMMAND(IDM_START, OnMemuStart)ON_COMMAND(IDM_PRIMARY, OnMemuPrimary) ON_COMMAND(IDM_SECOND, OnMemuSecond)ON_COMMAND(IDM_ADV ANCE, OnMemuAdvance) ON_COMMAND(IDM_CUSTOM, OnMemuCustom) ON_COMMAND(IDM_MARK, OnMemuMark)ON_COMMAND(IDM_COLOR, OnMemuColor)ON_COMMAND(IDM_SOUND, OnMemuSound)ON_COMMAND(IDM_EXIT, OnMemuExit)ON_COMMAND(IDM_HELP_LIST, OnMemuHelpList) ON_COMMAND(IDM_HELP_FIND, OnMemuHelpFind) ON_COMMAND(IDM_HELP_USE, OnMemuHelpUse) ON_COMMAND(IDM_ABOUT, OnMemuAbout)ON_WM_KEYDOWN()ON_WM_INITMENU()ON_WM_CLOSE()ON_COMMAND(IDM_HERO, OnMemuHero)ON_COMMAND(IDM_CHEAT, OnMemuCheat)//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////////载入配置//void CMineWnd::LoadConfig(){//----------获取本地目录-------------*/char exeFullPath[MAX_PA TH];CString strPath;GetModuleFileName(NULL, exeFullPath, MAX_PATH);strPath = CString(exeFullPath);strPath = strPath.Left(strPath.ReverseFind('\\'));//-----------------------------------*/strPath += "\\config.ini";char strPrimary[80];char strSecond[80];char strAdvance[80];m_uXNum = GetPrivateProfileInt("WINDOW","XNum", 10,strPath);m_uYNum = GetPrivateProfileInt("WINDOW","YNum", 10,strPath);m_uMineNum = GetPrivateProfileInt("MINE","MineNum", 10,strPath);m_uLevel = GetPrivateProfileInt("MINE","Level", 0,strPath);m_uPrimary = GetPrivateProfileInt("SCORE","Primary", 999,strPath);m_uSecond = GetPrivateProfileInt("SCORE","Second", 999,strPath);m_uAdvance = GetPrivateProfileInt("SCORE","Advance", 999,strPath);GetPrivateProfileString("HOLDER","PrimaryHolder", "匿名",strPrimary,80,strPath);GetPrivateProfileString("HOLDER","SecondHolder", "匿名",strSecond,80,strPath);GetPrivateProfileString("HOLDER","AdvanceHolder", "匿名",strAdvance,80,strPath);m_szPrimary = strPrimary;m_szSecond = strSecond;m_szAdvance = strAdvance;m_bMarkful = GetPrivateProfileInt("CONFIG","Markful", 0,strPath);m_bColorful = GetPrivateProfileInt("CONFIG","Colorful", 1,strPath);m_bSoundful = GetPrivateProfileInt("CONFIG","Soundful", 1,strPath);}//// 保存//void CMineWnd::SaveConfig(){//----------获取本地目录-------------*/char exeFullPath[MAX_PA TH];CString strPath;GetModuleFileName(NULL, exeFullPath, MAX_PATH);strPath = CString(exeFullPath);strPath = strPath.Left(strPath.ReverseFind('\\'));//-----------------------------------*/strPath += "\\config.ini";//雷区行列数CString strXNum,strYNum;//雷数选择级别CString strMineNum,strLevel;//记录保持分数CString strPrimary,strSecond,strAdvance;//记录保持者CString strPrimaryHolder,strSecondHolder,strAdvanceHolder;//其他配置CString strMarkful,strColorful,strSoundful;strXNum.Format("%u",m_uXNum);strYNum.Format("%u",m_uYNum);strMineNum.Format("%u",m_uMineNum);strLevel.Format("%u",m_uLevel);strPrimary.Format("%u",m_uPrimary);strSecond.Format("%u",m_uSecond);strAdvance.Format("%u",m_uAdvance);strPrimaryHolder.Format("%s",m_szPrimary);strSecondHolder.Format("%s",m_szSecond);strAdvanceHolder.Format("%s",m_szAdvance);strMarkful.Format("%d",m_bMarkful);strColorful.Format("%d",m_bColorful);strSoundful.Format("%d",m_bSoundful);WritePrivateProfileString("WINDOW","XNum", strXNum,strPath);WritePrivateProfileString("WINDOW","YNum", strYNum,strPath);WritePrivateProfileString("MINE","MineNum", strMineNum,strPath);WritePrivateProfileString("MINE","Level", strLevel,strPath);WritePrivateProfileString("SCORE","Primary", strPrimary,strPath);WritePrivateProfileString("SCORE","Second", strSecond,strPath);WritePrivateProfileString("SCORE","Advance", strAdvance,strPath);WritePrivateProfileString("HOLDER","PrimaryHolder", strPrimaryHolder,strPath);WritePrivateProfileString("HOLDER","SecondHolder", strSecondHolder,strPath);WritePrivateProfileString("HOLDER","AdvanceHolder", strAdvanceHolder,strPath);WritePrivateProfileString("CONFIG","Markful", strMarkful,strPath);WritePrivateProfileString("CONFIG","Colorful", strColorful,strPath);WritePrivateProfileString("CONFIG","Soundful", strSoundful,strPath);}////载入位图//void CMineWnd::LoadBitmap(){if (m_bColorful){m_clrDark = COLOR_DARK_GRAY;m_bmpMine.DeleteObject();m_bmpMine.LoadBitmap(IDB_MINE_COLOR);m_bmpNumber.DeleteObject();m_bmpNumber.LoadBitmap(IDB_NUM_COLOR);m_bmpButton.DeleteObject();m_bmpButton.LoadBitmap(IDB_BTN_COLOR);}else{m_clrDark = COLOR_BLACK;m_bmpMine.DeleteObject();m_bmpMine.LoadBitmap(IDB_MINE_GRAY);m_bmpNumber.DeleteObject();m_bmpNumber.LoadBitmap(IDB_NUM_GRAY);m_bmpButton.DeleteObject();m_bmpButton.LoadBitmap(IDB_BTN_GRAY);}}//// 游戏的初始化//void CMineWnd::InitGame(){//位图的初始化LoadBitmap();m_nLeaveNum = m_uMineNum;m_uSpendTime = 0;m_uBtnState = BUTTON_NORMAL;m_uGameState = GS_W AIT;if (m_uTimer){KillTimer(ID_TIMER_EVENT);m_uTimer = 0;}m_pNewMine = NULL;m_pOldMine = NULL;FreeMines();//初始化地图for (UINT i = 0; i<m_uYNum; i++){for (UINT j = 0; j<m_uXNum; j++){m_pMines[i][j].uRow = i;m_pMines[i][j].uCol = j;m_pMines[i][j].uState = STA TE_NORMAL;m_pMines[i][j].uAttrib = ATTRIB_EMPTY;m_pMines[i][j].uOldState = STA TE_NORMAL;}}}//// 布雷//void CMineWnd::LayMines(UINT row, UINT col){//埋下随机种子srand( (unsigned)time( NULL ) );UINT i, j;for(UINT index = 0; index < m_uMineNum;){//取随即数i = rand() % m_uYNum;j = rand() % m_uXNum;if (i == row && j == col) continue;if(m_pMines[i][j].uAttrib != ATTRIB_MINE){m_pMines[i][j].uAttrib = ATTRIB_MINE;//修改属性为雷index++;}}}////雷方块拓展(对于周围无雷的空白区域)//void CMineWnd::ExpandMines(UINT row, UINT col){UINT i, j;UINT minRow = (row == 0) ? 0 : row - 1;UINT maxRow = row + 2;UINT minCol = (col == 0) ? 0 : col - 1;UINT maxCol = col + 2;UINT around = GetAroundNum(row, col);m_pMines[row][col].uState = 15 - around;m_pMines[row][col].uOldState = 15 - around;// “打开”该区域,重绘DrawSpecialMine(row, col);//对周围一个雷都没有的空白区域if (around == 0){for (i = minRow; i < maxRow; i++){for (j = minCol; j < maxCol; j++){//对于周围可以拓展的区域进行的规拓展if (!(i == row && j == col) &&m_pMines[i][j].uState == STATE_NORMAL&& m_pMines[i][j].uAttrib != ATTRIB_MINE){if (!IsInMineArea(i, j)) continue;ExpandMines(i, j);}}}}}//// 获取某个小方块区域相邻8个区域的雷个数//UINT CMineWnd::GetAroundNum(UINT row, UINT col){UINT i, j;UINT around = 0;UINT minRow = (row == 0) ? 0 : row - 1;UINT maxRow = row + 2;UINT minCol = (col == 0) ? 0 : col - 1;UINT maxCol = col + 2;for (i = minRow; i < maxRow; i++){for (j = minCol; j < maxCol; j++){if (!IsInMineArea(i, j)) continue;if (m_pMines[i][j].uAttrib == ATTRIB_MINE) around++;}}return around;}//// 获取某个小方块区域相邻8个区域的已标志状态数//UINT CMineWnd::GetAroundFlags(UINT row, UINT col){UINT i, j;UINT flags = 0;UINT minRow = (row == 0) ? 0 : row - 1;UINT maxRow = row + 2;UINT minCol = (col == 0) ? 0 : col - 1;UINT maxCol = col + 2;for (i = minRow; i < maxRow; i++){for (j = minCol; j < maxCol; j++){if (!IsInMineArea(i, j)) continue;if (m_pMines[i][j].uState == STATE_FLAG) flags++;}}return flags;}////判断是否为雷//BOOL CMineWnd::IsMine(UINT row, UINT col){return (m_pMines[row][col].uAttrib == ATTRIB_MINE);}//判断是否在雷区域BOOL CMineWnd::IsInMineArea(UINT row, UINT col){return (row >= 0 && row < m_uYNum && col >= 0 && col < m_uXNum); }//// 失败处理//void CMineWnd::Dead(UINT row, UINT col){//按钮所在的区域CRect rcBtn(m_uBtnRect[1], 15, m_uBtnRect[2], 39);//雷区所在的区域CRect rcMineArea(MINE_AREA_LEFT, MINE_AREA_TOP,MINE_AREA_LEFT + m_uXNum * MINE_WIDTH,MINE_AREA_TOP + m_uYNum * MINE_HEIGHT);UINT i, j;if (m_pMines[row][col].uAttrib == ATTRIB_MINE){//失败--点中雷for (i = 0; i < m_uYNum; i++){for (j = 0; j < m_uXNum; j++){m_pMines[row][col].uState = STA TE_BLAST;m_pMines[row][col].uOldState = STA TE_BLAST;if (m_pMines[i][j].uAttrib == A TTRIB_MINE&& m_pMines[i][j].uState != STA TE_FLAG) {m_pMines[i][j].uState = STA TE_MINE;m_pMines[i][j].uOldState = STA TE_MINE;}}}}else {//失败--错误雷for (i = 0; i < m_uYNum; i++){for (j = 0; j < m_uXNum; j++){m_pMines[row][col].uState = STA TE_ERROR;m_pMines[row][col].uOldState = STA TE_ERROR;if (m_pMines[i][j].uAttrib == ATTRIB_MINE&& m_pMines[i][j].uState != STA TE_FLAG) {m_pMines[i][j].uState = STA TE_MINE;m_pMines[i][j].uOldState = STA TE_MINE;}}}}//失败处理InvalidateRect(rcMineArea);m_uBtnState = BUTTON_DEAD;InvalidateRect(rcBtn);m_uGameState = GS_DEAD;if (m_uTimer != 0){//将定时器去激活KillTimer(ID_TIMER_EVENT);m_uTimer = 0;if (m_bSoundful){//失败声音播放sndPlaySound((LPCTSTR)LockResource(m_pSndDead), SND_MEMORY | SND_ASYNC | SND_NODEFAULT);}}//// 胜利判断并处理//BOOL CMineWnd::Victory(){UINT i, j;CRect rcBtn(m_uBtnRect[1], 15, m_uBtnRect[2], 39);// 检测是否胜利for (i = 0; i < m_uYNum; i++){for (j = 0; j < m_uXNum; j++){if (m_pMines[i][j].uState == STATE_NORMAL) return FALSE;if (m_pMines[i][j].uState == STATE_DICEY) return FALSE;}}//胜利则作胜利处理m_uBtnState = BUTTON_VICTORY;m_uGameState = GS_VICTORY;Invalidate();if (m_uTimer != 0){//将定时器去激活KillTimer(ID_TIMER_EVENT);m_uTimer = 0;}//胜利声音if (m_bSoundful){sndPlaySound((LPCTSTR)LockResource(m_pSndVictory),SND_MEMORY | SND_ASYNC | SND_NODEFAULT);}//英雄榜UINT uRecord;if (m_uLevel == LEVEL_PRIMARY) uRecord = m_uPrimary;else if (m_uLevel == LEVEL_SECONDRY) uRecord = m_uSecond;else if (m_uLevel == LEVEL_ADV ANCE) uRecord = m_uAdvance;if (uRecord > m_uSpendTime){CDlgNewRecord dlg;dlg.SetLevel(m_uLevel);dlg.DoModal();switch(m_uLevel){case LEVEL_PRIMARY:m_uPrimary = m_uSpendTime;m_szPrimary = dlg.GetName();break;case LEVEL_SECONDRY:m_uSecond = m_uSpendTime;m_szSecond = dlg.GetName();break;case LEVEL_ADV ANCE:m_uAdvance = m_uSpendTime;m_szAdvance = dlg.GetName();break;case LEVEL_CUSTOM:return TRUE;default:break;}OnMemuHero();}return TRUE;}//// 鼠标右键,根据原先不同的标记作状态循环修改// 以便用户可以修改其原先标志//void CMineWnd::OnLRBtnDown(UINT row, UINT col){UINT i, j;UINT minRow = (row == 0) ? 0 : row - 1;UINT maxRow = row + 2;UINT minCol = (col == 0) ? 0 : col - 1;UINT maxCol = col + 2;for (i = minRow; i < maxRow; i++){for (j = minCol; j < maxCol; j++){if (!IsInMineArea(i, j)) continue;// if (i == row && j == col) continue;if (m_pMines[i][j].uState == STATE_NORMAL){m_pMines[i][j].uState = STA TE_EMPTY;}else if (m_pMines[i][j].uState == STA TE_DICEY){m_pMines[i][j].uState = STA TE_DICEY_DOWN;}}}}void CMineWnd::OnLRBtnUp(UINT row, UINT col){UINT i, j;UINT minRow = (row == 0) ? 0 : row - 1;UINT maxRow = row + 2;UINT minCol = (col == 0) ? 0 : col - 1;UINT maxCol = col + 2;for (i = minRow; i < maxRow; i++){for (j = minCol; j < maxCol; j++){if (!IsInMineArea(i, j)) continue;// if (i == row && j == col) continue;if (m_pMines[i][j].uOldState == STATE_NORMAL){m_pMines[i][j].uState = STA TE_NORMAL;}else if (m_pMines[i][j].uOldState == STA TE_DICEY){m_pMines[i][j].uState = STA TE_DICEY;}}}// Invalidate();}//展开拓展周围8个方向void CMineWnd::OpenAround(UINT row, UINT col){//如果周围相邻的标志雷数!= 周围相邻的雷数则返回if (GetAroundFlags(row, col) != GetAroundNum(row, col)) return;UINT i, j;UINT around = 0;UINT minRow = (row == 0) ? 0 : row - 1;UINT maxRow = row + 2;UINT minCol = (col == 0) ? 0 : col - 1;UINT maxCol = col + 2;for (i = minRow; i < maxRow; i++){for (j = minCol; j < maxCol; j++){if (!IsInMineArea(i, j)) continue;if (m_pMines[i][j].uState == STATE_NORMAL){//如果该区域为正常区域//拓展该雷区ExpandMines(i, j);around = GetAroundNum(i, j);m_pMines[i][j].uState = 15 - around;m_pMines[i][j].uOldState = 15 - around;}}}// 判断是否胜利,是则将地图中所有雷标识出来if (Victory()){for (i = 0; i < m_uYNum; i++){for (j = 0; j < m_uXNum; j++){if (m_pMines[i][j].uAttrib == ATTRIB_MINE){m_pMines[i][j].uState = STA TE_FLAG;m_pMines[i][j].uOldState = STA TE_FLAG;}}}m_nLeaveNum = 0;Invalidate();}}BOOL CMineWnd::ErrorAroundFlag(UINT row, UINT col){//如果周围相邻的标志雷数!= 周围相邻的雷数则返回if (GetAroundFlags(row, col) != GetAroundNum(row, col)) return FALSE;UINT i, j;UINT minRow = (row == 0) ? 0 : row - 1;UINT maxRow = row + 2;UINT minCol = (col == 0) ? 0 : col - 1;UINT maxCol = col + 2;for (i = minRow; i < maxRow; i++){for (j = minCol; j < maxCol; j++){if (!IsInMineArea(i, j)) continue;if (m_pMines[i][j].uState == STATE_FLAG){if (m_pMines[i][j].uAttrib != ATTRIB_MINE){Dead(i, j);return TRUE;}}}}return FALSE;}void CMineWnd::OpenByCheat(){UINT i, j;for (i = 0; i < m_uYNum; i++){for (j = 0; j < m_uXNum; j++){if (m_pMines[i][j].uState == STATE_FLAG) continue;OpenAround(i, j);}}}void CMineWnd::FreeMines(){// if (m_pMines) {// delete[] m_pMines;// m_pMines = NULL;// }// for (UINT row = 0; row<m_uYNum; row++) {// if (m_pMines[row]) {// delete []m_pMines[m_uXNum];// delete m_pMines[row];// }// }}void CMineWnd::SizeWindow( void ){UINT uWidth = DEFAULT_FRAME_X + m_uXNum * MINE_WIDTH +LINE_WIDTH_0 * 3 + SIDE_WIDTH_0 + SIDE_WIDTH_1;UINT uHeight = DEFAULT_FRAME_Y + m_uYNum * MINE_HEIGHT +LINE_WIDTH_0 * 3 + SIDE_WIDTH_0 * 2 + SIDE_WIDTH_1 + SHELL_S_H;SetWindowPos(&wndTopMost, 0, 0, uWidth, uHeight,SWP_NOZORDER | SWP_NOMOVE | SWP_NOCOPYBITS); //SWP_NOCOPYBITS does not do function???GetClientRect(&m_rcClient);// Button Positionm_uBtnRect[0] = m_rcClient.right / 2 - 12; // the left side of the start(state) button without 3d borderm_uBtnRect[1] = m_rcClient.right / 2 - 13; // the left side of the start(state) button with 3d borderm_uBtnRect[2] = m_rcClient.right / 2 + 12; // the right side of the start(state) button// Number Positionm_uNumRect[0] = m_rcClient.right - 55; // the left side of the spend time rect with 3d borderm_uNumRect[1] = m_rcClient.right - 15; // the right side of the spend time。

相关主题