📄 minearea.cpp
字号:
// MineArea.cpp : implementation file
//
#include "stdafx.h"
#include "PushMine.h"
#include "MineArea.h"
#include "PushMineDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CPushMineApp theApp;
extern const int uWidth;
extern const int uHeight;
/////////////////////////////////////////////////////////////////////////////
// CMineArea
CMineArea::CMineArea()
{
pMines = NULL;
pt.x=pt.y=0;
pequahead=NULL;
backGroundBrush.CreateSolidBrush(COLOR_GRAY);
SetBitmap();
ReAssign();
GameInit();
}
CMineArea::~CMineArea()
{
if(pMines)
{
delete[] pMines;
}
if(pequahead)
{
PEQUATION tail=pequahead->prev;
PEQUATION temp=NULL;
while(tail!=pequahead)
{
temp=tail->prev;
delete tail;
tail=temp;
}
delete pequahead;
}
}
BEGIN_MESSAGE_MAP(CMineArea, CStatic)
//{{AFX_MSG_MAP(CMineArea)
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMineArea message handlers
void CMineArea::ReAssign()
{
uTotle = uHeight*uWidth;
if(pMines)
{
delete[] pMines;
}
pMines = new MINE[uTotle];
}
void CMineArea::SetBitmap()
{
BMP_MINEAREA.DeleteObject();
BMP_MINEAREA.LoadBitmap(IDB_BITMAP10);
BMP_NUMBER.DeleteObject();
BMP_NUMBER.LoadBitmap(IDB_BITMAP20);
BMP_BUTTON.DeleteObject();
BMP_BUTTON.LoadBitmap(IDB_BITMAP30);
}
void CMineArea::SetCursorPos(int i, int j)
{
pt.x=i+1;
pt.y=j+1;
Invalidate();
}
void CMineArea::OnPaint()
{
CDC cdc;
CPaintDC dc(this); // device context for painting
CBitmap bitmap;
CBitmap* pOldBitmap;
GetClientRect(&rect);
// Rectangle POS
uRectPosX[0] = rect.right-14;
uRectPosX[1] = rect.right-16;
uRectPosX[2] = rect.right-18;
uRectPosX[3] = rect.right-6;
uRectPosX[4] = rect.right-7;
uRectPosX[5] = rect.right-8;
uRectPosX[6] = RECT_X_0+1;
uRectPosX[7] = RECT_X_1+1;
uRectPosX[8] = RECT_X_1+2;
uRectPosX[9] = rect.right;
uRectPosY[0] = rect.bottom-RECT_Y_1-5;
uRectPosY[1] = rect.bottom-RECT_Y_1-7;
uRectPosY[2] = rect.bottom-RECT_Y_1-9;
uRectPosY[3] = rect.bottom-8;
uRectPosY[4] = rect.bottom-7;
uRectPosY[5] = rect.bottom-6;
uRectPosY[6] = RECT_Y_0+1;
uRectPosY[7] = RECT_Y_1+1;
uRectPosY[8] = RECT_Y_1+2;
uRectPosY[9] = rect.bottom;
// NUMBER pos
uNumPos[0] = rect.right-55;
uNumPos[1] = rect.right-15;
uNumPos[2] = rect.right-54;
uNumPos[3] = rect.right-41;
uNumPos[4] = rect.right-28;
// BUTTON POS
uButtonPos[0] = rect.right/2-12;
uButtonPos[1] = rect.right/2-13;
uButtonPos[2] = rect.right/2+12;
if( !dc.IsPrinting() )
{
if( cdc.CreateCompatibleDC( &dc ) )
{
if(bitmap.CreateCompatibleBitmap(&dc,rect.right,rect.bottom))
{
pOldBitmap = cdc.SelectObject(&bitmap);
cdc.FillRect(&rect,&backGroundBrush);
MyDrawRectangle( (CPaintDC &)cdc );
MyDrawMineArea( (CPaintDC &)cdc );//////
MyDrawButton( (CPaintDC &)cdc );
MyDrawNumber( (CPaintDC &)cdc );
dc.BitBlt(rect.left, rect.top, rect.right, rect.bottom,
&cdc, 0, 0, SRCCOPY);
cdc.SelectObject( pOldBitmap );
bitmap.DeleteObject();
}
}
}
}
void CMineArea::GameInit()
{
uButtonState = BUTTON_NORMAL;
bHitButton = FALSE;
bInButtonRect = FALSE;
uGameState = WAIT;
bFirstClick = TRUE;
ClickNumber = 0;
change=0;
nOldPos = -1;
nNewPos = -1;
bDoubleClick = FALSE;
theApp.uSecends = 0;
bInMineArea = FALSE;
bRBUPOutMineArea = FALSE;
theApp.uRemainMines = theApp.uCustomMineNum;
if(pMines)
{
for(UINT i=0; i<uTotle; i++)
{
pMines[i].uDraw = DRAW_NOT_OPEN;
pMines[i].uState = STATE_EMPTY;
closed[i]=0;
}
}
if(pequahead)
{
PEQUATION tail=pequahead->prev;
PEQUATION temp=NULL;
while(tail!=pequahead)
{
temp=tail->prev;
delete tail;
tail=temp;
}
delete pequahead;
}
pequahead=NULL;
}
void CMineArea::MyDrawRectangle( CPaintDC& dc )// Draw frame
{
// draw side
dc.FillSolidRect(0,0,uRectPosX[9],LINE_WIDTH_0,COLOR_WHITE);
dc.FillSolidRect(0,0,LINE_WIDTH_0,uRectPosY[9],COLOR_WHITE);
//draw small rectangle
dc.Draw3dRect(RECT_X_0, RECT_Y_0, uRectPosX[0],37,
darkColor,COLOR_WHITE);
dc.Draw3dRect(uRectPosX[6],uRectPosY[6],uRectPosX[1],35,
darkColor,COLOR_WHITE);
dc.SetPixel(RECT_X_1, 45,COLOR_GRAY);
dc.SetPixel(uRectPosX[6],44,COLOR_GRAY);
dc.SetPixel(uRectPosX[3],RECT_Y_0, COLOR_GRAY);
dc.SetPixel(uRectPosX[4],uRectPosY[6],COLOR_GRAY);
// draw big rectangle
dc.Draw3dRect(RECT_X_1, RECT_Y_1, uRectPosX[0],
uRectPosY[0],darkColor,COLOR_WHITE);
dc.Draw3dRect(uRectPosX[7],uRectPosY[7],uRectPosX[1],
uRectPosY[1],darkColor,COLOR_WHITE);
dc.Draw3dRect(uRectPosX[8],uRectPosY[8],uRectPosX[2],
uRectPosY[2],darkColor,COLOR_WHITE);
dc.SetPixel(uRectPosX[3],RECT_Y_1, COLOR_GRAY);
dc.SetPixel(uRectPosX[4],uRectPosY[7],COLOR_GRAY);
dc.SetPixel(uRectPosX[5],uRectPosY[8],COLOR_GRAY);
dc.SetPixel(RECT_X_1, uRectPosY[5],COLOR_GRAY);
dc.SetPixel(uRectPosX[7],uRectPosY[4],COLOR_GRAY);
dc.SetPixel(uRectPosX[8],uRectPosY[3],COLOR_GRAY); /**/
}
void CMineArea::MyDrawNumber( CPaintDC& dc )
{
dc.Draw3dRect(16,15,41,25,darkColor,COLOR_WHITE);
dc.Draw3dRect(uNumPos[0],15,41,25,darkColor,COLOR_WHITE);
dc.SetPixel(56,15,COLOR_GRAY);
dc.SetPixel(16,39,COLOR_GRAY);
dc.SetPixel(uNumPos[1],15,COLOR_GRAY);
dc.SetPixel(uNumPos[0],39,COLOR_GRAY);
CDC cdc;
cdc.CreateCompatibleDC(&dc);
cdc.SelectObject(BMP_NUMBER);
UINT num;
// darw remain mine number
num = pt.x/100;
dc.StretchBlt(17,16,13,23,&cdc,0,253-23*num,13, 23, SRCCOPY);
num = pt.x/10%10;
dc.StretchBlt(30,16,13,23,&cdc,0,253-23*num,13, 23, SRCCOPY);
num = pt.x%10;
dc.StretchBlt(43,16,13,23,&cdc,0,253-23*num,13, 23, SRCCOPY);
// draw remain seconds
num = 0/100;
dc.StretchBlt(uNumPos[2],16,13,23,&cdc,0,253-23*num,13, 23, SRCCOPY);
num = pt.y/10%10;
dc.StretchBlt(uNumPos[3],16,13,23,&cdc,0,253-23*num,13, 23, SRCCOPY);
num = pt.y%10;
dc.StretchBlt(uNumPos[4],16,13,23,&cdc,0,253-23*num,13, 23, SRCCOPY);
}
void CMineArea::MyDrawButton( CPaintDC& dc )
{
CDC cdc;
cdc.CreateCompatibleDC(&dc);
cdc.SelectObject(BMP_BUTTON);
dc.StretchBlt(uButtonPos[0],16,24,24,&cdc,0,24*uButtonState,24,24, SRCCOPY);
dc.Draw3dRect(uButtonPos[1],15,26,26,darkColor,darkColor);
dc.SetPixel(uButtonPos[1],40,COLOR_GRAY);
dc.SetPixel(uButtonPos[2],15,COLOR_GRAY);
}
void CMineArea::MyDrawMineArea( CPaintDC& dc )
{
CDC cdc;
cdc.CreateCompatibleDC(&dc);
cdc.SelectObject(BMP_MINEAREA);
for(int i=0; i<uHeight; i++)
for(int j=0; j<uWidth; j++)
{
dc.StretchBlt(MINE_AREA_X+16*j,MINE_AREA_Y+16*i,16,16,&cdc,
0,16*pMines[i*uWidth+j].uDraw,16,16, SRCCOPY);
}
}
void CMineArea::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 CMineArea::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 CMineArea::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;
}
void CMineArea::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 CMineArea::MyInvalidateRect( RECT &rectClick, int pos )
{
rectClick.left = MINE_AREA_X + pos%uWidth*16;
rectClick.right = rectClick.left + 16;
rectClick.top = MINE_AREA_Y + pos/uWidth*16;
rectClick.bottom = rectClick.top + 16;
InvalidateRect(&rectClick);
}
void CMineArea::ProcessLeftRightButtonUp( int pos )
{
// compute round
int around[10];
GetAroundPos( pos, around );
if( pMines[ pos ].uDraw >= DRAW_NUMBER_8 &&
pMines[ pos ].uDraw <= DRAW_NUMBER_1 &&
pMines[ pos ].uState == STATE_OPENED )
{
UINT trueFlag = 0;
UINT falseFlag = 0;
UINT flag = 0;
UINT error[8];
UINT errorNum = 0;
for(UINT i=0; i<(UINT)around[8]; i++)
{
if( pMines[around[i]].uState == STATE_MINE &&
pMines[around[i]].uDraw == DRAW_FLAG )//
{
trueFlag++;
flag++;
}
else if( pMines[around[i]].uState == STATE_MINE &&
pMines[around[i]].uDraw != DRAW_FLAG ) //
{
falseFlag++;
error[errorNum++] = around[i];
}
else if(pMines[around[i]].uState != STATE_MINE &&
pMines[around[i]].uDraw == DRAW_FLAG) //
{
flag++;
falseFlag++;
}
}
if( trueFlag == flag && falseFlag == 0 ) //
{
RECT rectClick;
for( i=0; i<(UINT)around[8]; i++)
{
if( pMines[around[i]].uState != STATE_OPENED )
{
if( pMines[around[i]].uState >= STATE_NUMBER_8 &&
pMines[around[i]].uState <= STATE_NUMBER_1 )
{
pMines[around[i]].uDraw = pMines[around[i]].uState;
ClickNumber++;
pMines[around[i]].uState = STATE_OPENED;
MyInvalidateRect( rectClick, around[i] );
}
else if( pMines[around[i]].uState >= EMPTY_AREA_START )
{
// get and flag empty area
DrawEmptyArea( pMines[around[i]].uState );
}
}
}
Victory(); // is victory
}
else if( falseFlag > 0 ) //
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -