// ChildView.cpp : CChildView 类的实现
//
#include "stdafx.h"
#include "llk.h"
#include "ChildView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CChildView
CChildView::CChildView()
{
m_bIsRunning = false ;
m_nTotal = COL * ROW / 2;
m_bSelected = false ;
if( FAILED ( m_Pic.Load( _T("llk.bmp") ) ) )
{
AfxMessageBox( _T("Load pic failed!") );
m_bLoadOK = false ;
}
else
{
m_bLoadOK = true ;
}
}
CChildView::~CChildView()
{
if( m_bLoadOK )
m_Pic.Destroy();
}
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_WM_PAINT()
ON_COMMAND(ID_NEWGAME, &CChildView::OnNewgame)
ON_WM_TIMER()
ON_WM_LBUTTONDOWN()
ON_COMMAND(ID_REFRESH, &CChildView::OnRefresh)
ON_WM_KEYDOWN()
END_MESSAGE_MAP()
// CChildView 消息处理程序
BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
{
if (!CWnd::PreCreateWindow(cs))
return FALSE;
cs.dwExStyle |= WS_EX_CLIENTEDGE;
cs.style &= ~WS_BORDER;
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW),( HBRUSH ) ::GetStockObject( BLACK_BRUSH ), NULL);
return TRUE;
}
void CChildView::OnPaint()
{
CPaintDC dc(this); // 用于绘制的设备上下文
if( m_bIsRunning )
{
if( m_bLoadOK )
{
for(int i= 1 ;i<=ROW ;i++ )
{
for(int j = COL ; j >= 1;j -- )
{
if( m_nCells[i][j] != 0 )
{
int x = j * CELLW ;//+ CELLW ;
int y = i * CELLH ;
// m_Pic.TransparentBlt( dc.m_hDC , x, y ,PICW , PICH , PICW * m_nCells[i+1][ j+1 ],0, PICW ,PICH );
// m_Pic.Draw( dc.m_hDC , x-5, y ,PICW , PICH , PICW * (m_nCells[i][ j ]-1 ),0, PICW ,PICH );
DrawBlock( &dc, x-5 , y , m_nCells[i][j] );
}
}
}
}
else
{
CString msg;
for(int i=1;i<=ROW;i++)
{
for(int j=1;j<=COL;j++)
{
if( m_nCells[i][j] != 0 )
{
msg.Format(_T("%d"), m_nCells[i][j] );
int x = j * CELLW ;//+ CELLW ;
int y = i * CELLH ;//+ CELLH ;
dc.Rectangle( x , y , x + CELLW , y + CELLH );
dc.TextOut( x + 4 , y+ 4, msg );
}
}
}
}
}
}
void CChildView::DrawBlock(CPaintDC *pDC, int x, int y, int id)
{
HBITMAP maskBmp = ::CreateBitmap( PICW, PICH ,1,1,NULL);
HDC pdc = m_Pic.GetDC();
HDC hMemDC = ::CreateCompatibleDC( pdc ) ;
HBITMAP oldBmp = (HBITMAP)::SelectObject(hMemDC,maskBmp);
::SetBkColor( pdc ,RGB(128 , 192 , 128 ));
::BitBlt(hMemDC,0,0,PICW,PICH ,pdc ,PICW * (id -1 ), 0,SRCCOPY);
::BitBlt( pDC->m_hDC ,x ,y , PICW , PICH ,pdc , PICW * ( id - 1 ), 0, SRCINVERT);
::BitBlt( pDC->m_hDC,x, y ,PICW , PICH ,hMemDC,0,0,SRCAND);
::BitBlt( pDC->m_hDC, x ,y, PICW ,PICH , pdc , PICW * (id - 1 ) , 0 ,SRCINVERT);
::SelectObject(hMemDC,oldBmp);
::DeleteObject(maskBmp);
::DeleteDC(hMemDC);
m_Pic.ReleaseDC();
}
void CChildView::OnNewgame()
{
int i,j;
m_Map.GenMap( 1 );
for(i=1; i<ROW + 1 ; i++ )
for(j=1;j<COL+1;j++)
m_nCells[i][j] = m_Map.m_nGrids[i-1][j-1];
for(i=0;i<COL+2;i++)
{
m_nCells[0][i] = 0;
m_nCells[ROW+1][i] = 0;
}
for(i=0;i<ROW+2;i++)
{
m_nCells[i][0] = 0;
m_nCells[i][ COL +1 ] = 0;
}
SetTimer(1 , 10 , NULL );
m_bIsRunning = true;
m_bSelected = false ;
m_nTotal = COL * ROW / 2;
}
void CChildView::OnTimer(UINT_PTR nIDEvent)
{
if( nIDEvent == 1 )
{
InvalidateRect(NULL);
KillTimer( 1 );
}
else
if(nIDEvent == 2 )
{
static int t = 0;
if( t == 0 )
{
DrawLine( true ); //画连线
t ++ ;
}
else
{
if( t > 8 )
{
DrawLine( false ); //清除连线,以及方块
KillTimer( 2 );
t = 0 ;
if( m_nTotal == 0 )
{
AfxMessageBox( _T("恭喜您过关!!" ) );
m_bIsRunning = false ;
}
}
else
t ++ ;
}
}
CWnd::OnTimer(nIDEvent);
}
void CChildView::DrawFocus( int x, int y)
{
CDC *pDC = GetDC();
HBRUSH hbr = (HBRUSH)GetStockObject( NULL_BRUSH );
HBRUSH ob = (HBRUSH)pDC->SelectObject( hbr );
CPen pen( PS_SOLID , 3 , RGB( 100 , 100 , 255 ) );
CPen *op = (CPen *) pDC->SelectObject( &pen);
pDC->Rectangle( x * CELLW+1 , y* CELLH +1 ,( x + 1 ) * CELLW -1 , (y +1 ) * CELLH - 1);
pDC->SelectObject( op );
pDC->SelectObject( ob );
ReleaseDC( pDC );
}
void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
{
if( m_bIsRunning )
{
int cx = point.x / CELLW ;
int cy = point.y / CELLH ;
if ( cx == 0 || cx == COL + 1 || cy == 0 || cy == ROW + 1 )
return ;
if( !m_bSelected ) //没有选择
{
if( m_nCells[ cy ][ cx ] != 0 ) //在方块上点击
{
DrawFocus( cx , cy );
m_SelPoint.x = cx ;
m_SelPoint.y = cy ;
m_bSelected = true ;
CString msg ;
msg.Format( _T("id : %d " ) , m_nCells[ cy ][ cx ] ) ;
GetDC()->TextOutW(0 , 0 , msg );
}
}
else //之前已经点中某方块
{
if( m_nCells[ cy ][ cx ] != 0 && ( cx != m_SelPoint.x || cy != m_SelPoint.y ) ) //不是点的同一个方块
{
CString msg ;
msg.Format( _T("cur id : %d ; org id : %d " ) , m_nCells[ cy ][ cx ], m_nCells[ m_SelPoint.y ][ m_SelPoint.x ] ) ;
GetDC()->TextOutW(0 , 0 , msg );
if( m_nCells[ m_SelPoint.y ][ m_SelPoint.x ] != m_nCells[ cy ][ cx ] || !FindPath( cx,cy ,(int) m_SelPoint.x, (int) m_SelPoint.y ) )
{
CRect rc ;
rc.left = m_SelPoint.x * CELLW -1;
rc.top = m_SelPoint.y * CELLH - 1;
rc.right = rc.left + CELLW + 1;
rc.bottom = rc.top + CELLH + 1;
InvalidateRect(& rc ); //清除先前的选择框
DrawFocus( cx , cy );
m_SelPoint.x = cx;
m_SelPoint.y = cy;
m_bSelected = true;
}
else //可以消除
{
m_bSelected = false ;
DrawFocus( cx , cy );
m_nCells[ m_SelPoint.y ][ m_SelPoint.x ] = 0;
m_nCells[ cy ][ cx ] = 0 ;
m_nTotal -- ;
SetTimer( 2, 20 , NULL );
}
}
}
}
CWnd::OnLButtonDown(nFlags, point);
}
bool CChildView::FindXLine(int x1, int y1, int x2, int y2)
{
bool ret = true ;
int sx = ( x1 > x2 ) ? x2 + 1: x1 +1 ;
int ex = ( x1 > x2 ) ? x1 -1 : x2 -1 ;
for( ; sx <= ex && ret == true ; sx ++ )
if( m_nCells[ y1 ][ sx ] != 0 )
ret = false;
return ret;
}
bool CChildView::FindYLine(int x1, int y1, int x2, int y2)
{
bool ret = true ;
int sy , ey ;
sy = ( y1 > y2 ) ? y2 +1 : y1 + 1 ;
ey = ( y1 > y2 ) ? y1 -1 : y2 -1 ;
for( ; sy <= ey && ret == true ; sy ++ )
if( m_nCells[ sy ][ x1 ] != 0 )
ret = false ;
return ret ;
}
//获取左右两端点
void CChildView::GetXPos(int x1, int y1, int &left, int &right)
{
int t = x1 ;
while( ( t >=1 ) && ( m_nCells[ y1][ t-1 ] == 0 ) )
t -- ;
left = t ;
t = x1 ;
while( ( t < COL + 1) && ( m_nCells[y1][ t+1] == 0 ) )
t ++ ;
right = t ;
}
//获取上下两端点
void CChildView::GetYPos( int x1 , int y1 , int& top ,int& bottom )
{
int t = y1 ;
while( (t >=1) && ( m_nCells[ t-1 ][ x1 ] == 0 ) )
t -- ;
top = t ;
t = y1 ;
while( ( t < ROW + 1 ) && ( m_nCells[ t + 1 ][ x1 ] == 0 ) )
t ++ ;
bottom = t ;
}
bool CChildView::FindPath(int x1, int y1, int x2, int y2)
{
bool ret = false ;
int left1 , right1 ;
int left2 , right2 ;
int left , right ;
GetXPos( x1 , y1 , left1 , right1 );
GetXPos( x2 , y2 , left2 , right2 );
left = left1 > left2 ? left1 : left2 ;
right = right1 > right2 ? right2 : right1 ;
if( left <= right ) // x 方向查找
{
for(int x=left; x<= right && ret == false ; x++ )
{
if( FindYLine( x, y1 , x, y2 ) )
{
m_nX1 = x1 , m_nY1 = y1 , m_nX2 = x2 , m_nY2 = y2 , m_nT = x , m_bHorz = false ;
ret = true ;
}
}
}
if( !ret )
{
int top1 , bottom1 , top2 , bottom2 , top , bottom ;
GetYPos( x1, y1 , top1 , bottom1 );
GetYPos( x2, y2 , top2 , bottom2 );
top = top1 > top2 ? top1 : top2 ;
bottom = bottom1 > bottom2 ? bottom2 : bottom1 ;
if( top <= bottom )
{
for(int y= top ; y<= bottom && ret == false ; y ++ )
{
if( FindXLine( x1 , y