📄 childview.cpp
字号:
// 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 + -