home *** CD-ROM | disk | FTP | other *** search
- #include "stdafx.h"
- #include "math.h"
- #include "limits.h"
- #include "puzzle.h"
- #include "piece.h"
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char BASED_CODE THIS_FILE[] = __FILE__;
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
- // CPiece
- CPiece::CPiece(void)
- {
- m_szLogSize.cx=0;
- m_szLogSize.cy=0;
- m_ptLogPos.x=0;
- m_ptLogPos.y=0;
- m_szActSize.cx=0;
- m_szActSize.cy=0;
- m_ptActPos.x=0;
- m_ptActPos.y=0;
- m_bInMotion = FALSE;
- m_nUpLim = 0;
- m_nDownLim = 0;
- m_nRightLim = 0;
- m_nLeftLim = 0;
- m_xHiliteWidth = GetSystemMetrics(SM_CXBORDER)*3;
- m_yHiliteWidth = GetSystemMetrics(SM_CYBORDER)*3;
- }
- /////////////////////////////////////////////////////////////////////////////
- CPiece::CPiece(int x, int y, int dx, int dy)
- {
- m_szLogSize.cx=dx;
- m_szLogSize.cy=dy;
- m_ptLogPos.x=x;
- m_ptLogPos.y=y;
- m_szActSize.cx=dx*CPIECE_UNIT;
- m_szActSize.cy=dy*CPIECE_UNIT;
- m_ptActPos.x=x*CPIECE_UNIT;
- m_ptActPos.y=y*CPIECE_UNIT;
- m_bInMotion = FALSE;
- m_nUpLim = 0;
- m_nDownLim = 0;
- m_nRightLim = 0;
- m_nLeftLim = 0;
- m_xHiliteWidth = GetSystemMetrics(SM_CXBORDER)*3;
- m_yHiliteWidth = GetSystemMetrics(SM_CYBORDER)*3;
-
- }
- /////////////////////////////////////////////////////////////////////////////
- CPiece::~CPiece(void)
- {}
- //////////////////////////////////////////////////////////////////////////////
- void CPiece::draw(CDC* pDC)
- {
- CRect rect(m_ptActPos,m_szActSize);
- CRect rectHilite;
-
- pDC->SelectStockObject(GRAY_BRUSH);
- pDC->SelectStockObject(NULL_PEN);
- pDC->Rectangle(rect);
- rectHilite = rect;
- rectHilite.right = rectHilite.left+m_xHiliteWidth;
- pDC->SelectStockObject(LTGRAY_BRUSH);
- pDC->Rectangle(rectHilite);
- rectHilite = rect;
- rectHilite.bottom = rectHilite.top+m_yHiliteWidth;
- pDC->Rectangle(rectHilite);
- pDC->SelectStockObject(DKGRAY_BRUSH);
- rectHilite = rect;
- rectHilite.left = rectHilite.right - m_xHiliteWidth;
- pDC->Rectangle(rectHilite);
- rectHilite = rect;
- rectHilite.top = rectHilite.bottom - m_yHiliteWidth;
- pDC->Rectangle(rectHilite);
-
-
- }
- /////////////////////////////////////////////////////////////////////////////
- CSize CPiece::GetSize(void)
- {
- return m_szLogSize;
- }
- /////////////////////////////////////////////////////////////////////////////
- CPoint CPiece::GetPos(void)
- {
- return m_ptLogPos;
- }
- /////////////////////////////////////////////////////////////////////////////
- void CPiece::SetPos(const CPoint& rPT)
- {
- m_ptLogPos = rPT;
- m_ptActPos.x = rPT.x*CPIECE_UNIT;
- m_ptActPos.y = rPT.y*CPIECE_UNIT;
- }
- /////////////////////////////////////////////////////////////////////////////
- void CPiece::SetPos(int x, int y)
- {
- m_ptLogPos.x = x;
- m_ptLogPos.y = y;
- m_ptActPos.x = x*CPIECE_UNIT;
- m_ptActPos.y = y*CPIECE_UNIT;
- }
- /////////////////////////////////////////////////////////////////////////////
- BOOL CPiece::PtInPiece(CPoint& pt)
- {
- CRect rect(m_ptActPos,m_szActSize);
-
- return rect.PtInRect(pt);
- }
- /////////////////////////////////////////////////////////////////////////////
- CRect CPiece::rectPiece(void)
- {
- CRect r(m_ptActPos,m_szActSize);
-
- return r;
- }
- /////////////////////////////////////////////////////////////////////////////
- void CPiece::SetMoveLimits(int up,int right,int down,int left)
- {
- m_nUpLim = up;
- m_nRightLim = right;
- m_nDownLim = down;
- m_nLeftLim = left;
- m_bInMotion = FALSE;
- m_bHoriz = FALSE;
- m_bVert = FALSE;
- }
- /////////////////////////////////////////////////////////////////////////////
- void CPiece::Move(CPoint& rPoint)
- {
-
- if (m_bInMotion)
- {
- int dx;
- int dy;
-
- //Clip point to allowed rectangle
- if ( rPoint.x > m_nMouseRightLim )
- rPoint.x = m_nMouseRightLim;
- else if ( rPoint.x < m_nMouseLeftLim )
- rPoint.x = m_nMouseLeftLim;
- if ( rPoint.y > m_nMouseDownLim )
- rPoint.y = m_nMouseDownLim;
- else if ( rPoint.y < m_nMouseUpLim )
- rPoint.y = m_nMouseUpLim;
-
- dx = rPoint.x - m_ptMouseLast.x;
- dy = rPoint.y - m_ptMouseLast.y;
-
- if (m_bHoriz)
- //We're restricted to the horizontal
- dy=0;
- else if (m_bVert)
- //We're restricted to the vertical
- dx=0;
- else
- {
- //We haven't established the orientation yet
- // If we can only move vertically or horizontally that will be
- // our orientation
- // otherwise the orientation will be in the direction of the
- // greatest change
-
- if ( !m_nRightLim && !m_nLeftLim )
- {
- m_bHoriz = FALSE;
- m_bVert = TRUE;
- dx=0;
- }
- else if ( !m_nUpLim && !m_nDownLim )
- {
- m_bHoriz = TRUE;
- m_bVert = FALSE;
- dy=0;
- }
- else if ( abs(dx) > abs(dy) )
- {
- m_bHoriz = TRUE;
- m_bVert = FALSE;
- dy=0;
- }
- else
- {
- m_bHoriz = FALSE;
- m_bVert = TRUE;
- dx=0;
- }
- }
- m_ptActPos.x += dx;
- m_ptActPos.y += dy;
- m_ptMouseLast = rPoint;
- }
- else
- {
- //Motion hasn't started yet. PREPARE!
- m_ptMouseOrg = rPoint; //Remember where we started
- m_ptMouseLast = rPoint;
- // Calculate mouse limits
- m_nMouseUpLim = rPoint.y - m_nUpLim*CPIECE_UNIT;
- m_nMouseRightLim = rPoint.x + m_nRightLim*CPIECE_UNIT;
- m_nMouseDownLim = rPoint.y + m_nDownLim*CPIECE_UNIT;
- m_nMouseLeftLim = rPoint.x - m_nLeftLim*CPIECE_UNIT;
- m_bHoriz = FALSE; //Don't know the
- m_bVert = FALSE; //direction yet
- m_bInMotion = TRUE;
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- void CPiece::Stop(CPoint& rPoint)
- {
- int OldErr, NewErr, LogPos;
-
- if (m_bHoriz)
- {
- //Find the horizontal logical position which has the least
- // error with respect to the actual position
- OldErr=INT_MAX;
- for (LogPos=0;LogPos<INT_MAX;LogPos++)
- {
- NewErr=abs(m_ptActPos.x-LogPos*CPIECE_UNIT);
- if (NewErr > OldErr)
- {
- m_ptLogPos.x = LogPos-1;
- m_ptActPos.x = m_ptLogPos.x*CPIECE_UNIT;
- break;
- }
- else
- OldErr = NewErr;
- }
- }
- else
- {
- //Find the vertical logical position which has the least
- // error with respect to the actual position
- OldErr=INT_MAX;
- for (LogPos=0;LogPos<INT_MAX;LogPos++)
- {
- NewErr=abs(m_ptActPos.y-LogPos*CPIECE_UNIT);
- if (NewErr > OldErr)
- {
- m_ptLogPos.y = LogPos-1;
- m_ptActPos.y = m_ptLogPos.y*CPIECE_UNIT;
- break;
- }
- else
- OldErr = NewErr;
- }
- }
- m_bInMotion = FALSE;
- }
-