⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 minewnd.cpp

📁 这是一个关于扫雷游戏的代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// MineWnd.cpp : implementation file
//

#include "stdafx.h"
#include "mine.h"
#include "MineWnd.h"
#include "HeroDlg.h"
#include "CustomDlg.h"
#include "RecordDlg.h"
#include "Mmsystem.h"

#pragma comment(lib, "Winmm.lib")

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

extern  CMineApp theApp;
UINT& 	uWidth = theApp.uCustomWidth;
UINT& 	uHeight = theApp.uCustomHeight;

/////////////////////////////////////////////////////////////////////////////
// CMineWnd 

CMineWnd::CMineWnd()
{	
	bLoadWavRes = FALSE;
	pBlastWavMem = NULL;
	pWinWavMem = NULL;
	pCountWavMem = NULL;	
	pMines = NULL;
	m_nTimer = 0;	

	backGroundBrush.CreateSolidBrush(COLOR_GRAY);
	if(theApp.bColor)
		darkColor = COLOR_DARK_GRAY;
	else 
		darkColor = COLOR_BLACK;
	SetBitmap();	
	if(theApp.bSound)
	{	
		LoadWavRes();		
	}		
	
	ReAssign();
	GameInit();	
}

CMineWnd::~CMineWnd()
{
	FreeWavRes();
	if(pMines)
	{
		delete[] pMines;
	}
}

///////////////////////////////////////////////////////////////////////
// my functions

void CMineWnd::GameInit()
{	
	uButtonState = BUTTON_NORMAL;
	bHitButton = FALSE; 
	bInButtonRect = FALSE;
	uGameState = WAIT;
	bFirstClick = TRUE;
	ClickNumber = 0;	
	nOldPos = -1;
    nNewPos = -1;
	bDoubleClick = FALSE;
	theApp.uSecends = 0;
	bInMineArea = FALSE;
	bRBUPOutMineArea = FALSE;
	theApp.uRemainMines = theApp.uCustomMineNum;

	if(m_nTimer)
	{
		KillTimer( ID_TIMER_EVENT );
		m_nTimer = 0;
	}
	if(pMines)
	{
		for(UINT i=0; i<uTotle; i++)
		{
			pMines[i].uDraw = DRAW_NOT_OPEN;
			pMines[i].uState = STATE_EMPTY;
		}
	}
}

void CMineWnd::ReAssign()
{
	uTotle = uHeight*uWidth;
	if(pMines)
	{
		delete[] pMines;
	}
	pMines = new MINE[uTotle];	
}


void CMineWnd::FreeWavRes()
{
	if(pBlastWavMem)
	{
		FreeResource(pBlastWavMem);
		pBlastWavMem = NULL;		
	}
	if(pWinWavMem)
	{
		FreeResource(pWinWavMem);	
		pWinWavMem = NULL;		
	}
	if(pCountWavMem)
	{
		FreeResource(pCountWavMem);		
		pCountWavMem = NULL;
	}
	bLoadWavRes = FALSE;
}

void CMineWnd::LoadWavRes()
{
	HMODULE hmod = AfxGetResourceHandle(); 
	
	HRSRC hSndResource = FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE3),_T("WAVE"));
	pBlastWavMem = LoadResource(hmod,hSndResource);
	
	hSndResource = FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE2),_T("WAVE"));
	pWinWavMem = LoadResource(hmod,hSndResource);
	
	hSndResource = FindResource(hmod,MAKEINTRESOURCE(IDR_WAVE1),_T("WAVE"));
	pCountWavMem = LoadResource(hmod,hSndResource);
	
	bLoadWavRes = TRUE;
}


void CMineWnd::SetMineUp(int pos)
{
	RECT rectClick;
	if(pMines[pos].uDraw == DRAW_EMPTY &&
		pMines[pos].uState != STATE_OPENED)
	{
		pMines[pos].uDraw =  DRAW_NOT_OPEN;
	}
	else if(pMines[pos].uDraw == DRAW_QUESTION_MARK)
	{
		pMines[pos].uDraw = DRAW_QUESTION_MARK_FLAG;
	}
	MyInvalidateRect( rectClick, pos );
}

void CMineWnd::SetMineDown( int pos )
{
	RECT rectClick;
	
	if(pMines[pos].uDraw == DRAW_NOT_OPEN)
	{
		pMines[pos].uDraw = DRAW_EMPTY;
	}
	else if(pMines[pos].uDraw == DRAW_QUESTION_MARK_FLAG)
	{
		pMines[pos].uDraw = DRAW_QUESTION_MARK;
	}	
	MyInvalidateRect( rectClick, pos );
}

void CMineWnd::SetMineUpEx( int posArray[], int num )
{	
	RECT rectClick;
	for(int i=0; i<=num; i++)
	{
		if(pMines[posArray[i]].uDraw == DRAW_EMPTY && 
			pMines[posArray[i]].uState != STATE_OPENED)  //
		{
			pMines[posArray[i]].uDraw =  DRAW_NOT_OPEN;
		}
		else if(pMines[posArray[i]].uDraw == DRAW_QUESTION_MARK)
		{
			pMines[posArray[i]].uDraw = DRAW_QUESTION_MARK_FLAG;
		}
		MyInvalidateRect( rectClick, posArray[i] );			
	}		
}

void CMineWnd::SetMineDownEx( int posArray[], int num )
{
	RECT rectClick;
	for(int i=0; i<=num; i++)
	{
		if(pMines[posArray[i]].uDraw == DRAW_NOT_OPEN)
		{
			pMines[posArray[i]].uDraw = DRAW_EMPTY ;
		}
		else if(pMines[posArray[i]].uDraw == DRAW_QUESTION_MARK_FLAG)
		{
			pMines[posArray[i]].uDraw = DRAW_QUESTION_MARK;
		}
		MyInvalidateRect( rectClick, posArray[i] );	
	}
}

void CMineWnd::ChangeFlag( int pos ) // 
{
	RECT rectClick;
	CRect rectMineNum(17,16,55,38);
	
	if(pMines[pos].uDraw == DRAW_FLAG)
	{ 
		if(theApp.bMarked)
			pMines[pos].uDraw = DRAW_QUESTION_MARK_FLAG;
		else
			pMines[pos].uDraw = DRAW_NOT_OPEN;
		theApp.uRemainMines++;
		InvalidateRect(rectMineNum);	
	}
	else if(pMines[pos].uDraw == DRAW_NOT_OPEN)
	{
		pMines[pos].uDraw = DRAW_FLAG;
		theApp.uRemainMines--; 
		InvalidateRect(rectMineNum);	
	}
	else if(pMines[pos].uDraw == DRAW_QUESTION_MARK_FLAG)
	{
		pMines[pos].uDraw = DRAW_NOT_OPEN;
	}
	MyInvalidateRect( rectClick, pos );	
}

void CMineWnd::FlagAllMine()
{
	RECT rectClick;	
	for(UINT i=0; i<uTotle; i++)
	{	
		if(pMines[i].uState == STATE_MINE && 
			pMines[i].uDraw == DRAW_BLAST )
		{		
		}
		else if(pMines[i].uState == STATE_MINE &&
			pMines[i].uDraw != DRAW_FLAG )
		{  
			pMines[i].uDraw = DRAW_MINE;			
		}
		else if( pMines[i].uState != STATE_MINE
			&& pMines[i].uDraw == DRAW_FLAG) // flag error
		{
			pMines[i].uDraw = DRAW_ERROR_FLAG;		
		}	
		else
		{
			continue;			
		}
		MyInvalidateRect( rectClick, i );	
	}
}

void CMineWnd::GetAroundPos( UINT i, int around[9])   
{
	UINT j = 0;
	int cmp_i = (int)i;
	int cmp_w = (int)uWidth;
	if(cmp_i>cmp_w && cmp_i%cmp_w>0)    
		around[j++] = cmp_i-cmp_w-1;
	if(cmp_i-cmp_w >= 0)    
		around[j++] = cmp_i-cmp_w;
	if(cmp_i>cmp_w-1 && (cmp_i+1)%cmp_w>0)    
		around[j++] = cmp_i-cmp_w+1;
	if(cmp_i%cmp_w > 0)        
        around[j++] = cmp_i-1;
	if((cmp_i+1)%cmp_w>0)  
		around[j++] = cmp_i+1;
	if(cmp_i<=((int)uHeight-1)*cmp_w && cmp_i%cmp_w>0) 
		around[j++] = cmp_i+cmp_w-1;
	if(cmp_i+cmp_w<(int)uTotle)     
        around[j++] = cmp_i+cmp_w;	
	if(cmp_i<((int)uHeight-1)*cmp_w && (cmp_i+1)%cmp_w>0)
		around[j++] = cmp_i+cmp_w+1;	
	around[8] = j;
}

int CMineWnd::GetStation(int x,int y)  // 
{
	int	m = x - MINE_AREA_X;
	int	n = y - MINE_AREA_Y;	
	
	if( m<0 || (UINT)m>uWidth*16 ||
		n<0 || (UINT)n>uHeight*16 )
	{
		return -1;
	}
	m = m/16;
	n = n/16;
	return m+n*uWidth;      
}

void CMineWnd::SetMine( int pos ) //
{	
	srand( (unsigned)time( NULL ) );
	int temp;
	for( UINT i=0; i<theApp.uCustomMineNum; )
	{		
		temp = rand()%uTotle;	
		if( pMines[temp].uState != STATE_MINE && temp != pos ) //pos
		{
			pMines[temp].uState = STATE_MINE;
			i++;
		}
	}	
}

void CMineWnd::SetNumbers() // 
{
	UINT i,j;
	int around[9];
	for( i=0; i<uTotle; i++ )
	{
		if( pMines[i].uState == STATE_MINE )
		{
			GetAroundPos( i, around );   
			for(j=0; j<(UINT)around[8]; j++)
			{
				if( pMines[ around[j] ].uState != STATE_MINE )			
					pMines[ around[j] ].uState--;			
			}
		}
	}
}


void CMineWnd::GetEmptyAreas()
{
	int sp = 0;
	int around[9];
	int *pStack = new int[uTotle];
	ZeroMemory(pStack, sizeof(int)*uTotle);
	UINT emptyAreaNum = EMPTY_AREA_START;	
	
	for(UINT i=0; i<uTotle; i++)
	{
		if( pMines[i].uState == STATE_EMPTY )
		{			
			pStack[sp++] = i;
			while(1)
			{
				if( pMines[i].uState == STATE_EMPTY )				
					pMines[i].uState = emptyAreaNum;		
				if( sp == 0 )
				{
					emptyAreaNum++;
					break;
				}
				GetAroundPos( i, around );
				for(int j=0; j<around[8]; j++)
				{
					if( pMines[around[j]].uState == STATE_EMPTY )
						break;
				}
				if( j<around[8] )
				{
					i = around[j];
					pStack[++sp] = i;					
				}
				else
					i = pStack[sp--];
			}
		}
	}
	delete[] pStack;
}


void CMineWnd::DrawEmptyArea( UINT areaFlag )
{
	RECT rectClick;
	int around[9];
	for(UINT i=0; i<uTotle; i++)
	{   
		if( pMines[i].uState == areaFlag ) // flag the same empty area 
		{
			pMines[i].uDraw = DRAW_EMPTY;			
			pMines[i].uState = STATE_OPENED;
			ClickNumber++;
			MyInvalidateRect( rectClick, i );
			
            GetAroundPos( i, around );
			for(int j=0; j<around[8]; j++)
			{
				if( pMines[around[j]].uState >= STATE_NUMBER_8 &&
					pMines[around[j]].uState <= STATE_NUMBER_1 &&
					pMines[around[j]].uState != STATE_OPENED)
				{
					pMines[around[j]].uDraw = pMines[around[j]].uState;
					pMines[around[j]].uState = STATE_OPENED;
					ClickNumber++;
					MyInvalidateRect( rectClick, around[j] );					
				}
			}			
		}
	}
}

BOOL CMineWnd::Victory()
{
	if( ClickNumber == uTotle-theApp.uCustomMineNum )
	{
		uGameState = VICTORY;
		KillTimer( ID_TIMER_EVENT );
		m_nTimer = 0;
		
		uButtonState = BUTTON_VICTORY;
		CRect rectButton(uButtonPos[1],15,uButtonPos[2],42);
		InvalidateRect( rectButton );
		
		theApp.uRemainMines = 0;
        CRect rectMineNum(17,16,55,38);
        InvalidateRect( rectMineNum );

		RECT rectClick;
		for(UINT i=0; i<uTotle; i++)
		{
			if(pMines[i].uState == STATE_MINE && 
				pMines[i].uDraw != DRAW_FLAG )
			{  
				pMines[i].uDraw = DRAW_FLAG;
				MyInvalidateRect( rectClick, i );
			}				
		}		
		sndPlaySound((LPCSTR)LockResource(pWinWavMem),
			SND_MEMORY | SND_ASYNC | SND_NODEFAULT);		
		
		if( theApp.uGameLevel == LEVEL_PRIMARY )
		{
			if( theApp.uSecends >= theApp.uPrimaryRecord )
			{
				return TRUE;			
			}
			theApp.uPrimaryRecord = theApp.uSecends;
		}
		else if( theApp.uGameLevel == LEVEL_SECONDARY )
		{
			if( theApp.uSecends >= theApp.uSecondaryRecord )
			{
				return TRUE;				
			}
			theApp.uSecondaryRecord = theApp.uSecends;
		}
		else if( theApp.uGameLevel == LEVEL_ADVANCED  )
		{
			if( theApp.uSecends >= theApp.uAdvancedRecord )
			{	
				return TRUE;
			}
			theApp.uAdvancedRecord = theApp.uSecends;
		}
		else  // custom
		{
			return TRUE;
		}

		CRecordDlg recordDlg;			
		recordDlg.DoModal();		
		CHeroDlg heroDlg;
		heroDlg.DoModal(); 	
		
		return TRUE;
	}	
	return FALSE;	
}


void CMineWnd::MyInvalidateRect( RECT &rectClick, int pos )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -