home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
PROG_C
/
MSVCPUZL.ZIP
/
PUZZLVW.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-09
|
9KB
|
334 lines
// puzzlvw.cpp : implementation of the CPuzzleView class
//
#include "stdafx.h"
#include "afxcoll.h"
#include "puzzle.h"
#include "puzzldoc.h"
#include "puzzlvw.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CPuzzleView
IMPLEMENT_DYNCREATE(CPuzzleView, CView)
BEGIN_MESSAGE_MAP(CPuzzleView, CView)
//{{AFX_MSG_MAP(CPuzzleView)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_COMMAND(ID_RESET, OnReset)
ON_UPDATE_COMMAND_UI(ID_RESET, OnUpdateReset)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPuzzleView construction/destruction
CPuzzleView::CPuzzleView()
{
CRect rect;
m_bCaptured = FALSE;
m_selectedPiece = NULL;
m_board.Add(new CPiece(1,0,2,2)); // The goal piece
m_board.Add(new CPiece(0,0,1,2));
m_board.Add(new CPiece(3,0,1,2));
m_board.Add(new CPiece(0,2,1,2));
m_board.Add(new CPiece(1,2,2,1));
m_board.Add(new CPiece(3,2,1,2));
m_board.Add(new CPiece(1,3,1,1));
m_board.Add(new CPiece(2,3,1,1));
m_board.Add(new CPiece(0,4,1,1));
m_board.Add(new CPiece(3,4,1,1));
ResetPieces();
m_height = 5;
m_width = 4;
//SizeToPuzzle();
}
CPuzzleView::~CPuzzleView()
{
for ( int i=0;i<m_board.GetSize();i++)
delete ((CPiece *)m_board[i]);
}
/////////////////////////////////////////////////////////////////////////////
void CPuzzleView::SizeToPuzzle(void)
{
CFrameWnd* pwndMain = GetParentFrame();
RECT rectMain;
pwndMain->GetWindowRect(&rectMain);
pwndMain->MoveWindow(rectMain.left,rectMain.top,m_width*50,
m_height*50,TRUE);
}
/////////////////////////////////////////////////////////////////////////////
void CPuzzleView::ResetPieces(void)
{
((CPiece*)m_board[0])->SetPos(1,0);
((CPiece*)m_board[1])->SetPos(0,0);
((CPiece*)m_board[2])->SetPos(3,0);
((CPiece*)m_board[3])->SetPos(0,2);
((CPiece*)m_board[4])->SetPos(1,2);
((CPiece*)m_board[5])->SetPos(3,2);
((CPiece*)m_board[6])->SetPos(1,3);
((CPiece*)m_board[7])->SetPos(2,3);
((CPiece*)m_board[8])->SetPos(0,4);
((CPiece*)m_board[9])->SetPos(3,4);
}
/////////////////////////////////////////////////////////////////////////////
// CPuzzleView drawing
void CPuzzleView::OnDraw(CDC* pDC)
{
for ( int i=0;i<m_board.GetSize();i++)
((CPiece *)m_board[i])->draw(pDC);
}
/////////////////////////////////////////////////////////////////////////////
//BOOL CPuzzleView::PreCreateWindow(CREATESTRUCT& cs)
//{
// cs.style = WS_OVERLAPPED | WS_MINIMIZE | WS_SYSMENU | WS_VISIBLE | WS_CHILD;
// cs.x = 0;
// cs.y = 0;
// cs.cx = 200;
// cs.cy = 250;
// return CView::PreCreateWindow(cs);
//}
/////////////////////////////////////////////////////////////////////////////
//void CPuzzleView::OnGetMinMaxInfo(MINMAXINFO FAR *lpMMI)
//{
// lpMMI->ptMaxSize.x = m_width*CPIECE_UNIT;
// lpMMI->ptMaxSize.y = m_height*CPIECE_UNIT;
// lpMMI->ptMinTrackSize.x = m_width*CPIECE_UNIT;
// lpMMI->ptMinTrackSize.y = m_height*CPIECE_UNIT;
//}
/////////////////////////////////////////////////////////////////////////////
// CPuzzleView diagnostics
#ifdef _DEBUG
void CPuzzleView::AssertValid() const
{
CView::AssertValid();
}
void CPuzzleView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CPuzzleDoc* CPuzzleView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPuzzleDoc)));
return (CPuzzleDoc*) m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CPuzzleView message handlers
void CPuzzleView::OnLButtonDown(UINT nFlags, CPoint point)
{
CPiece* p;
// TODO: Add your message handler code here and/or call default
TRACE("entering CPuzzleView::OnLButtonDown - point = %d, %d\n",
point.x,point.y);
for ( int i=0;i<m_board.GetSize();i++)
{
p=(CPiece*)m_board[i];
if (p->PtInPiece(point))
{
//You've found the selected piece
if ( CanMove(p))
{
m_selectedPiece = p;
SetCapture();
p->Move(point);
}
break;
}
}
}
//////////////////////////////////////////////////////////////////////////////
void CPuzzleView::OnLButtonUp(UINT nFlags, CPoint point)
{
CRect oldRect,newRect,invalidRect;
if (m_selectedPiece)
{
CPoint ptSolved(1,3);
oldRect = m_selectedPiece->rectPiece();
m_selectedPiece->Stop(point);
newRect = m_selectedPiece->rectPiece();
invalidRect = oldRect | newRect;
InvalidateRect(invalidRect,TRUE);
ReleaseCapture();
m_selectedPiece = NULL;
//Check for solution
if ( ((CPiece*)m_board[0])->GetPos() == ptSolved )
MessageBox( "Puzzle Solved", "Puzzle" );
}
}
void CPuzzleView::OnMouseMove(UINT nFlags, CPoint point)
{
CRect oldRect,newRect,invalidRect;
if (m_selectedPiece)
{
oldRect = m_selectedPiece->rectPiece();
m_selectedPiece->Move(point);
newRect = m_selectedPiece->rectPiece();
invalidRect = oldRect | newRect;
InvalidateRect(invalidRect,TRUE);
}
}
/////////////////////////////////////////////////////////////////////////////
BOOL CPuzzleView::OnBoard(CPoint& pt,CPiece* p)
{
CSize sz = p->GetSize();
if (pt.x<0)
return FALSE;
if (pt.y<0)
return FALSE;
if (pt.x+sz.cx > m_width)
return FALSE;
if (pt.y+sz.cy > m_height)
return FALSE;
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
BOOL CPuzzleView::Conflict(CPoint& pt,CPiece* p)
{
CSize szP = p->GetSize(); //The size of the selected piece
CRect rectP(pt,szP); //The logical rectangle of the selected piece
// at the target point
CPiece* pTestPc; //The current piece I'm testing against
for (int i=0;i<m_board.GetSize();i++) //Check against each piece
{
if ( (pTestPc = (CPiece *)m_board[i]) != p ) //Except itself
{
CRect rectTest(pTestPc->GetPos(),pTestPc->GetSize());
CRect rectIntersect = rectP & rectTest;
if ( rectIntersect.IsRectEmpty() )
continue; //No conflict with this piece
else
return TRUE; //conflict found
}
}
return FALSE; //no conflict
}
/////////////////////////////////////////////////////////////////////////////
BOOL CPuzzleView::CanMove(CPiece* p)
{
int up,down,left,right;
int i;
//Can the piece move in any of the four directions and if so, how far?
//Can it move up?
up=0;
for ( i=1; i<m_height; i++ ) //Try movin 1 space then 2, etc.
{
CPoint ptTarget = p->GetPos();
ptTarget.y -= i; //Move target point up
if ( OnBoard(ptTarget,p))
if ( !Conflict(ptTarget,p))
{
up = i; //Can move up i units
continue;
}
break; //No need to try another
}
//Can I move right?
right=0;
for ( i=1; i<m_width; i++ ) //Try movin 1 space then 2, etc.
{
CPoint ptTarget = p->GetPos();
ptTarget.x += i; //Move target point to the right
if ( OnBoard(ptTarget,p))
if ( !Conflict(ptTarget,p))
{
right = i; //Can move right i units
continue;
}
break;
}
//Can I move left?
left=0;
for ( i=1; i<m_width; i++ ) //Try movin 1 space then 2, etc.
{
CPoint ptTarget = p->GetPos();
ptTarget.x -= i; //Move target point to the left
if ( OnBoard(ptTarget,p))
if ( !Conflict(ptTarget,p))
{
left = i; //Can move left i units
continue;
}
break;
}
//Can it move down?
down=0;
for ( i=1; i<m_height; i++ ) //Try movin 1 space then 2, etc.
{
CPoint ptTarget = p->GetPos();
ptTarget.y += i; //Move target point up
if ( OnBoard(ptTarget,p))
if ( !Conflict(ptTarget,p))
{
down = i; //Can move up i units
continue;
}
break;
}
p->SetMoveLimits(up,right,down,left);
return up|down|left|right;
}
void CPuzzleView::OnReset()
{
ResetPieces();
InvalidateRect(NULL);
}
void CPuzzleView::OnUpdateReset(CCmdUI* pCmdUI)
{
pCmdUI->Enable();
}