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

📄 childview.cpp

📁 援引别人的经典游戏
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ChildView.cpp : implementation of the CChildView class
//

#include "stdafx.h"
#include "WinMine.h"
#include "ChildView.h"
#include "CustomDlg.h"
#include "WinDlg.h"
#include "RecordDlg.h"

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

enum { MINE = 10, CROSS, EXPLODE, MARK, FLAG, NONE };
enum { PRESSED, WIN, ANGRY, SURPRISE, SMILE };
enum { BASIC, INTERMEDIATE, EXPERT, CUSTOM };
int xmove[] = { -1, 0, 1, -1, 1, -1, 0, 1 };
int ymove[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
TCHAR szSection[] = "扫雷";

/////////////////////////////////////////////////////////////////////////////
// CChildView

CChildView::CChildView()
{
	srand( GetTickCount() );
	
	m_bmCells.LoadBitmap( IDB_CELLS );
	m_bmFaces.LoadBitmap( IDB_FACES );
	m_bmNumber.LoadBitmap( IDB_NUM );

	m_level = AfxGetApp()->GetProfileInt( szSection, "Difficulty", 0 );
	if( m_level >= 3 )		// customize
	{
		m_height = AfxGetApp()->GetProfileInt( szSection, "Height", 8 );
		m_width = AfxGetApp()->GetProfileInt( szSection, "Width", 8 );
		m_nMines = AfxGetApp()->GetProfileInt( szSection, "Mines", 10 );
	}
	m_bMark = AfxGetApp()->GetProfileInt( szSection, "Mark", 1 );
	for( int i = 0; i < 3; i ++ )
	{
		CString strEntry;
		strEntry.Format( "Time%d", i + 1 );
		m_recordTime[i] = AfxGetApp()->GetProfileInt( szSection, strEntry, 999 );
		strEntry.Format( "Name%d", i + 1 );
		m_recordName[i] = AfxGetApp()->GetProfileString( szSection, strEntry, "匿名" );
	}
}


CChildView::~CChildView()
{
	AfxGetApp()->WriteProfileInt( szSection, "Difficulty", m_level );
	AfxGetApp()->WriteProfileInt( szSection, "Height", m_height );
	AfxGetApp()->WriteProfileInt( szSection, "Width", m_width );
	AfxGetApp()->WriteProfileInt( szSection, "Mines", m_nMines );
	AfxGetApp()->WriteProfileInt( szSection, "Mark", m_bMark );
	for( int i = 0; i < 3; i ++ )
	{
		CString strEntry;
		strEntry.Format( "Time%d", i + 1 );
		AfxGetApp()->WriteProfileInt( szSection, strEntry, m_recordTime[i] );
		strEntry.Format( "Name%d", i + 1 );
		AfxGetApp()->WriteProfileString( szSection, strEntry, m_recordName[i] );
	}	
}


BEGIN_MESSAGE_MAP(CChildView,CWnd )
	//{{AFX_MSG_MAP(CChildView)
	ON_WM_PAINT()
	ON_COMMAND(ID_GAME_NEW, OnGameNew)
	ON_WM_CREATE()
	ON_WM_LBUTTONDOWN()
	ON_WM_RBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_RBUTTONUP()
	ON_WM_TIMER()
	ON_COMMAND(ID_GAME_CUSTOMIZE, OnGameCustomize)
	ON_COMMAND(ID_GAME_MARK, OnGameMark)
	ON_UPDATE_COMMAND_UI(ID_GAME_MARK, OnUpdateGameMark)
	ON_COMMAND(ID_GAME_RECORD, OnGameRecord)
	ON_COMMAND(ID_HELP_TOPICS, OnHelpTopics)
	//}}AFX_MSG_MAP
	ON_COMMAND_RANGE(ID_GAME_BASIC, ID_GAME_EXPERT, OnGameLevel)
	ON_UPDATE_COMMAND_UI_RANGE(ID_GAME_BASIC, ID_GAME_CUSTOMIZE, OnUpdateGameLevel)
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CChildView message handlers

BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) 
{
	if (!CWnd::PreCreateWindow(cs))
		return FALSE;

	cs.style &= ~WS_BORDER;
	cs.lpszClass = AfxRegisterWndClass(0, ::LoadCursor(NULL, IDC_ARROW));

	return TRUE;
}

void CChildView::DrawFrame( CDC *pDC )
{
	CRect rc;
	GetClientRect( &rc );
	int w = rc.Width() - 1;
	int h = rc.Height() - 1;
	CPen penDKGray;
	penDKGray.CreatePen( PS_SOLID, 1, RGB(127,127,127) );
	
	pDC->FillSolidRect( 0, 0, w, 55, RGB(191,191,191) );
	pDC->FillSolidRect( CRect(0,55,12,h-12), RGB(191,191,191) );
	pDC->FillSolidRect( CRect(0,h-12,w,h), RGB(191,191,191) );
	pDC->FillSolidRect( CRect(w-11,55,w,h-12), RGB(191,191,191) );

	CPen *ppenOld = (CPen *)(pDC->SelectStockObject( WHITE_PEN ));
	pDC->MoveTo( w-1, 0 );
	pDC->LineTo( 0, 0 );
	pDC->LineTo( 0, h );
	pDC->MoveTo( w-2, 1 );
	pDC->LineTo( 1, 1 );
	pDC->LineTo( 1, h-1 );
	pDC->MoveTo( w-3, 2 );
	pDC->LineTo( 2, 2 );
	pDC->LineTo( 2, h-2 );

	pDC->MoveTo( w-9, 10 );
	pDC->LineTo( w-9, 45 );
	pDC->LineTo( 9, 45 );
	pDC->MoveTo( w-10, 11 );
	pDC->LineTo( w-10, 44 );
	pDC->LineTo( 10, 44 );

	pDC->MoveTo( w-9, 53 );
	pDC->LineTo( w-9, h-9 );
	pDC->LineTo( 9, h-9 );
	pDC->MoveTo( w-10, 54 );
	pDC->LineTo( w-10, h-10 );
	pDC->LineTo( 10, h-10 );
	pDC->MoveTo( w-11, 55 );
	pDC->LineTo( w-11, h-11 );
	pDC->LineTo( 11, h-11 );

	pDC->SelectObject( &penDKGray );
	pDC->MoveTo( w, 1 );
	pDC->LineTo( w, h );
	pDC->LineTo( 1, h );
	pDC->MoveTo( w-1, 2 );
	pDC->LineTo( w-1, h-1 );
	pDC->LineTo( 2, h-1 );
	pDC->MoveTo( w-2, 3 );
	pDC->LineTo( w-2, h-2 );
	pDC->LineTo( 3, h-2 );

	pDC->MoveTo( w-10, 9 );
	pDC->LineTo( 9, 9 );
	pDC->LineTo( 9, 45 );
	pDC->MoveTo( w-11, 10 );
	pDC->LineTo( 10, 10 );
	pDC->LineTo( 10, 44 );

	pDC->MoveTo( w-10, 52 );
	pDC->LineTo( 9, 52 );
	pDC->LineTo( 9, h-9 );
	pDC->MoveTo( w-11, 53 );
	pDC->LineTo( 10, 53 );
	pDC->LineTo( 10, h-10 );
	pDC->MoveTo( w-12, 54 );
	pDC->LineTo( 11, 54 );
	pDC->LineTo( 11, h-11 );

	pDC->SelectObject( ppenOld );
}

void CChildView::DrawCell( CDC *pDC, int row, int col, int cell )
{
	CDC dcMem;
	dcMem.CreateCompatibleDC( pDC );
	CBitmap *pbmOld = (CBitmap *)(dcMem.SelectObject(&m_bmCells));
	if( cell == -1 )
		cell = m_board[row][col];
	pDC->BitBlt( 12+col*16, 55+row*16, 16, 16, &dcMem, 
		0, (15-cell)*16, SRCCOPY );
	dcMem.SelectObject( pbmOld );
}

void CChildView::DrawAdjacentCells( CDC *pDC, int row, int col, int cell )
{
	for( int i = 0; i < 8; i ++ )
	{
		int nextrow = row + ymove[i];
		int nextcol = col + xmove[i];
		if( InBound(nextrow, nextcol) &&
			m_board[nextrow][nextcol] == NONE )
			DrawCell( pDC, nextrow, nextcol, cell );
	}
	if( m_board[row][col] == NONE )
		DrawCell( pDC, row, col, cell );
}


void CChildView::DrawBoard( CDC *pDC )
{
	CDC dcMem;
	dcMem.CreateCompatibleDC( pDC );
	CBitmap *pbmOld = (CBitmap *)(dcMem.SelectObject(&m_bmCells));
	
	for( int row = 0; row < m_height; row ++ )
		for( int col = 0; col < m_width; col ++ )
		{
			pDC->BitBlt( 12+col*16, 55+row*16, 16, 16, &dcMem, 
				0, (15-m_board[row][col])*16, SRCCOPY );
		}
	dcMem.SelectObject( pbmOld );
}

void CChildView::DrawButton( CDC *pDC, int face )
{
	CRect rc;
	GetClientRect( &rc );
	CDC dcMem;
	dcMem.CreateCompatibleDC( pDC );
	CBitmap *pbmOld = (CBitmap *)(dcMem.SelectObject(&m_bmFaces));
	
	pDC->BitBlt( m_rcButton.left, m_rcButton.top, 24, 24, 
		&dcMem, 0, face*24, SRCCOPY );
	
	dcMem.SelectObject( pbmOld );
}

void CChildView::DrawLCD( CDC *pDC, int x, int y, int num )
{
	CDC dcMem;
	dcMem.CreateCompatibleDC( pDC );
	CBitmap *pbmOld = (CBitmap *)(dcMem.SelectObject(&m_bmNumber));
	
	char buf[4];
	sprintf( buf, "%03d", num );
	for( int i = 0; i < 3; i ++ )
	{
		if( buf[i] == '-' )
			pDC->BitBlt( x, y, 13, 23, &dcMem, 0, 0, SRCCOPY );
		else
			pDC->BitBlt( x, y, 13, 23, &dcMem, 0, (11-buf[i]+'0')*23, SRCCOPY );
		x += 13;
	}
	dcMem.SelectObject( pbmOld );
}


void CChildView::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	CDC dcMem;
	dcMem.CreateCompatibleDC( &dc );
	CRect rc;
	GetClientRect( &rc );
	CBitmap bm;
	bm.CreateCompatibleBitmap( &dc, rc.Width(), rc.Height() );
	CBitmap *pbmOld = (CBitmap *)(dcMem.SelectObject(&bm));

	DrawFrame( &dcMem );
	DrawBoard( &dcMem );
	DrawLCD( &dcMem, 17, 16, m_nMinesLeft );
	DrawLCD( &dcMem, rc.Width()-57, 16, m_time );
	if( m_gameState == GS_GAMEOVER )
		DrawButton( &dcMem, ANGRY );
	else if( m_gameState == GS_ACTIVE )
		DrawButton( &dcMem, SMILE );
	else
		DrawButton( &dcMem, WIN );

	dc.BitBlt( 0, 0, rc.Width(), rc.Height(), &dcMem, 0, 0, SRCCOPY );
	dcMem.SelectObject( pbmOld );
}

BOOL CChildView::InBound( int row, int col )
{
	return (row >= 0 && row < m_height &&
			col >= 0 && col < m_width);
}


void CChildView::OnGameNew() 
{
	KillTimer( 1 );
	m_gameState = GS_ACTIVE;

	switch( m_level )
	{
	case BASIC:
		m_width = 8;
		m_height = 8;
		m_nMines = 10;
		break;
	case INTERMEDIATE:
		m_width = 16;
		m_height = 16;
		m_nMines = 40;
		break;
	case EXPERT:
		m_width = 30;
		m_height = 16;
		m_nMines = 99;
		break;
	}
	m_nMinesLeft = m_nMines;
	m_nDug = 0;

	for( int i = 0; i < m_height; i ++ )
		for( int j = 0; j < m_width; j ++ )
		{
			m_mines[i][j] = 0;
			m_board[i][j] = NONE;
		}
	
	for( i = 0; i < m_nMines; )
	{
		int row = rand() % m_height;
		int col = rand() % m_width;
		if( m_mines[row][col] == 0 )
		{
			m_mines[row][col] = 9;
			i ++;
		}
	}

	for( int row = 0; row < m_height; row ++ )
		for( int col = 0; col < m_width; col ++ )
		{
			if( m_mines[row][col] == 0 )
			{
				for( i = 0; i < 8; i ++ )
				{
					int nextrow = row + ymove[i];
					int nextcol = col + xmove[i];
					if( InBound(nextrow, nextcol) &&
						m_mines[nextrow][nextcol] == 9 )
						m_mines[row][col] ++;
				}
			}
		}

	AfxGetMainWnd()->SetWindowPos( NULL, 0, 0, 30+16*m_width, 
		110+16*m_height, SWP_NOMOVE | SWP_NOZORDER );
	CRect rc;
	GetClientRect( &rc );
	m_rcButton.left = (rc.Width()-24)/2;
	m_rcButton.top = 16;
	m_rcButton.right = m_rcButton.left + 24;
	m_rcButton.bottom = m_rcButton.top + 24;
	m_bButtonPressed = FALSE;
	m_lastrow = -1;
	m_time = 0;
	m_bFirst = TRUE;

	Invalidate();
}

int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd ::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	OnGameNew();
	
	return 0;
}

void CChildView::GameOver( int row, int col )
{
	for( int i = 0; i < m_height; i ++ )
		for( int j = 0; j < m_width; j ++ )
		{
			if( m_mines[i][j] == 9 )
			{
				if( m_board[i][j] != FLAG )
					m_board[i][j] = MINE;
			}
			else if( m_board[i][j] == FLAG )
				m_board[i][j] = CROSS;
		}
	m_board[row][col] = EXPLODE;
	m_gameState = GS_GAMEOVER;
	KillTimer( 1 );
	Invalidate();
}

void CChildView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	SetCapture();

	CClientDC dc(this);
	if( m_rcButton.PtInRect(point) )
	{
		m_bButtonPressed = TRUE;
		DrawButton( &dc, PRESSED );
		return;
	}
	
	if( m_gameState != GS_ACTIVE )
		return;

⌨️ 快捷键说明

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