home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / MSVCPUZL.ZIP / PUZZLVW.CPP < prev    next >
C/C++ Source or Header  |  1993-11-09  |  9KB  |  334 lines

  1. // puzzlvw.cpp : implementation of the CPuzzleView class
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "afxcoll.h"
  6. #include "puzzle.h"
  7.  
  8. #include "puzzldoc.h"
  9. #include "puzzlvw.h"
  10.  
  11. #ifdef _DEBUG
  12. #undef THIS_FILE
  13. static char BASED_CODE THIS_FILE[] = __FILE__;
  14. #endif
  15.  
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CPuzzleView
  18.  
  19. IMPLEMENT_DYNCREATE(CPuzzleView, CView)
  20.  
  21. BEGIN_MESSAGE_MAP(CPuzzleView, CView)
  22.     //{{AFX_MSG_MAP(CPuzzleView)
  23.     ON_WM_LBUTTONDOWN()
  24.     ON_WM_LBUTTONUP()
  25.     ON_WM_MOUSEMOVE()
  26.     ON_COMMAND(ID_RESET, OnReset)
  27.     ON_UPDATE_COMMAND_UI(ID_RESET, OnUpdateReset)
  28.     //}}AFX_MSG_MAP
  29. END_MESSAGE_MAP()
  30.  
  31. /////////////////////////////////////////////////////////////////////////////
  32. // CPuzzleView construction/destruction
  33.  
  34. CPuzzleView::CPuzzleView()
  35. {
  36. CRect rect;
  37.  
  38.   m_bCaptured = FALSE;
  39.   m_selectedPiece = NULL;
  40.   
  41.   m_board.Add(new CPiece(1,0,2,2)); // The goal piece
  42.   m_board.Add(new CPiece(0,0,1,2));
  43.   m_board.Add(new CPiece(3,0,1,2));
  44.   m_board.Add(new CPiece(0,2,1,2));
  45.   m_board.Add(new CPiece(1,2,2,1));
  46.   m_board.Add(new CPiece(3,2,1,2));
  47.   m_board.Add(new CPiece(1,3,1,1));
  48.   m_board.Add(new CPiece(2,3,1,1));
  49.   m_board.Add(new CPiece(0,4,1,1));
  50.   m_board.Add(new CPiece(3,4,1,1));
  51.  
  52.   ResetPieces();
  53.  
  54.   m_height = 5;
  55.   m_width  = 4;
  56.   
  57.   //SizeToPuzzle();
  58.   
  59.   
  60. }
  61.  
  62. CPuzzleView::~CPuzzleView()
  63. {
  64.     for ( int i=0;i<m_board.GetSize();i++)
  65.       delete ((CPiece *)m_board[i]);
  66. }
  67. /////////////////////////////////////////////////////////////////////////////
  68. void CPuzzleView::SizeToPuzzle(void)
  69. {
  70. CFrameWnd* pwndMain = GetParentFrame();
  71. RECT rectMain;
  72.  
  73.   pwndMain->GetWindowRect(&rectMain);
  74.   pwndMain->MoveWindow(rectMain.left,rectMain.top,m_width*50,
  75.                        m_height*50,TRUE);
  76. }
  77. /////////////////////////////////////////////////////////////////////////////
  78. void CPuzzleView::ResetPieces(void)
  79. {
  80.   ((CPiece*)m_board[0])->SetPos(1,0);
  81.   ((CPiece*)m_board[1])->SetPos(0,0);
  82.   ((CPiece*)m_board[2])->SetPos(3,0);
  83.   ((CPiece*)m_board[3])->SetPos(0,2);
  84.   ((CPiece*)m_board[4])->SetPos(1,2);
  85.   ((CPiece*)m_board[5])->SetPos(3,2);
  86.   ((CPiece*)m_board[6])->SetPos(1,3);
  87.   ((CPiece*)m_board[7])->SetPos(2,3);
  88.   ((CPiece*)m_board[8])->SetPos(0,4);
  89.   ((CPiece*)m_board[9])->SetPos(3,4);
  90. }
  91. /////////////////////////////////////////////////////////////////////////////
  92. // CPuzzleView drawing
  93.  
  94. void CPuzzleView::OnDraw(CDC* pDC)
  95. {
  96.     for ( int i=0;i<m_board.GetSize();i++)
  97.       ((CPiece *)m_board[i])->draw(pDC);
  98. }
  99. /////////////////////////////////////////////////////////////////////////////
  100. //BOOL CPuzzleView::PreCreateWindow(CREATESTRUCT& cs)
  101. //{
  102. //  cs.style = WS_OVERLAPPED | WS_MINIMIZE | WS_SYSMENU | WS_VISIBLE | WS_CHILD;
  103. //  cs.x  = 0;
  104. //  cs.y  = 0;
  105. //  cs.cx = 200;
  106. //  cs.cy = 250;
  107. //  return CView::PreCreateWindow(cs);
  108. //}
  109. /////////////////////////////////////////////////////////////////////////////
  110. //void CPuzzleView::OnGetMinMaxInfo(MINMAXINFO FAR *lpMMI)
  111. //{
  112. //  lpMMI->ptMaxSize.x = m_width*CPIECE_UNIT;
  113. //  lpMMI->ptMaxSize.y = m_height*CPIECE_UNIT;
  114. //  lpMMI->ptMinTrackSize.x = m_width*CPIECE_UNIT;
  115. //  lpMMI->ptMinTrackSize.y = m_height*CPIECE_UNIT;
  116. //}
  117. /////////////////////////////////////////////////////////////////////////////
  118. // CPuzzleView diagnostics
  119.  
  120. #ifdef _DEBUG
  121. void CPuzzleView::AssertValid() const
  122. {
  123.     CView::AssertValid();
  124. }
  125.  
  126. void CPuzzleView::Dump(CDumpContext& dc) const
  127. {
  128.     CView::Dump(dc);
  129. }
  130.  
  131. CPuzzleDoc* CPuzzleView::GetDocument() // non-debug version is inline
  132. {
  133.     ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPuzzleDoc)));
  134.     return (CPuzzleDoc*) m_pDocument;
  135. }
  136.  
  137. #endif //_DEBUG
  138.  
  139. /////////////////////////////////////////////////////////////////////////////
  140. // CPuzzleView message handlers
  141.  
  142. void CPuzzleView::OnLButtonDown(UINT nFlags, CPoint point)
  143. {
  144. CPiece* p;
  145.  
  146.     // TODO: Add your message handler code here and/or call default
  147.     
  148.     TRACE("entering CPuzzleView::OnLButtonDown - point = %d, %d\n",
  149.           point.x,point.y);
  150.           
  151.     for ( int i=0;i<m_board.GetSize();i++)
  152.       {
  153.       p=(CPiece*)m_board[i];
  154.       if (p->PtInPiece(point))
  155.         {
  156.         //You've found the selected piece
  157.         if ( CanMove(p))
  158.           {
  159.           m_selectedPiece = p;
  160.           SetCapture();
  161.           p->Move(point);
  162.           }  
  163.         break;
  164.         }
  165.       }
  166.       
  167. }
  168. //////////////////////////////////////////////////////////////////////////////
  169. void CPuzzleView::OnLButtonUp(UINT nFlags, CPoint point)
  170. {
  171. CRect oldRect,newRect,invalidRect;
  172.  
  173.     if (m_selectedPiece)
  174.       {
  175.       CPoint ptSolved(1,3);
  176.       
  177.       oldRect = m_selectedPiece->rectPiece();    
  178.       m_selectedPiece->Stop(point);
  179.       newRect = m_selectedPiece->rectPiece();
  180.       invalidRect = oldRect | newRect;
  181.       InvalidateRect(invalidRect,TRUE);
  182.       ReleaseCapture();
  183.       m_selectedPiece = NULL;
  184.       //Check for solution
  185.       if ( ((CPiece*)m_board[0])->GetPos() == ptSolved )
  186.         MessageBox( "Puzzle Solved", "Puzzle" );
  187.       }
  188. }
  189.  
  190. void CPuzzleView::OnMouseMove(UINT nFlags, CPoint point)
  191. {
  192. CRect oldRect,newRect,invalidRect;
  193.  
  194.  
  195.   if (m_selectedPiece)
  196.     {
  197.     oldRect = m_selectedPiece->rectPiece();    
  198.     m_selectedPiece->Move(point);
  199.     newRect = m_selectedPiece->rectPiece();
  200.     invalidRect = oldRect | newRect;
  201.     InvalidateRect(invalidRect,TRUE);
  202.     }
  203.  
  204. }
  205. /////////////////////////////////////////////////////////////////////////////
  206. BOOL CPuzzleView::OnBoard(CPoint& pt,CPiece* p)
  207. {
  208. CSize sz = p->GetSize();
  209.     
  210.     if (pt.x<0)
  211.        return FALSE;
  212.     if (pt.y<0)
  213.        return FALSE;
  214.     if (pt.x+sz.cx > m_width)
  215.        return FALSE;
  216.     if (pt.y+sz.cy > m_height)
  217.        return FALSE;
  218.        
  219.     return TRUE;             
  220. }
  221. /////////////////////////////////////////////////////////////////////////////
  222. BOOL CPuzzleView::Conflict(CPoint& pt,CPiece* p)
  223. {
  224. CSize szP = p->GetSize(); //The size of the selected piece
  225. CRect rectP(pt,szP);      //The logical rectangle of the selected piece 
  226.                           //  at the target point
  227. CPiece* pTestPc;          //The current piece I'm testing against
  228.     
  229.     for (int i=0;i<m_board.GetSize();i++) //Check against each piece
  230.         {
  231.         if ( (pTestPc = (CPiece *)m_board[i]) != p ) //Except itself
  232.            {
  233.            CRect rectTest(pTestPc->GetPos(),pTestPc->GetSize()); 
  234.            CRect rectIntersect = rectP & rectTest;
  235.              if ( rectIntersect.IsRectEmpty() )
  236.                continue; //No conflict with this piece
  237.              else
  238.                return TRUE; //conflict found
  239.            }
  240.         }
  241.     return FALSE; //no conflict
  242. }
  243.  
  244. /////////////////////////////////////////////////////////////////////////////
  245. BOOL CPuzzleView::CanMove(CPiece* p)
  246. {
  247. int up,down,left,right;
  248. int i;    
  249.  
  250.   //Can the piece move in any of the four directions and if so, how far?
  251.  
  252.   //Can it move up?
  253.   up=0;
  254.   for ( i=1; i<m_height; i++ ) //Try movin 1 space then 2, etc.
  255.       {
  256.       CPoint ptTarget = p->GetPos();
  257.  
  258.         ptTarget.y -= i; //Move target point up
  259.         if ( OnBoard(ptTarget,p))
  260.           if ( !Conflict(ptTarget,p))
  261.             {
  262.             up = i; //Can move up i units
  263.             continue;
  264.             }
  265.         break; //No need to try another    
  266.       }     
  267.  
  268.  
  269.   //Can I move right?
  270.   right=0;
  271.   for ( i=1; i<m_width; i++ ) //Try movin 1 space then 2, etc.
  272.       {
  273.       CPoint ptTarget = p->GetPos();
  274.  
  275.         ptTarget.x += i; //Move target point to the right
  276.         if ( OnBoard(ptTarget,p))
  277.           if ( !Conflict(ptTarget,p))
  278.             {
  279.             right = i; //Can move right i units
  280.             continue;
  281.             }
  282.         break;    
  283.       }
  284.  
  285.   //Can I move left?
  286.   left=0;
  287.   for ( i=1; i<m_width; i++ ) //Try movin 1 space then 2, etc.
  288.       {
  289.       CPoint ptTarget = p->GetPos();
  290.  
  291.         ptTarget.x -= i; //Move target point to the left
  292.         if ( OnBoard(ptTarget,p))
  293.           if ( !Conflict(ptTarget,p))
  294.             {
  295.             left = i; //Can move left i units
  296.             continue;
  297.             }
  298.         break;    
  299.       }
  300.  
  301.  
  302.   //Can it move down?
  303.   down=0;
  304.   for ( i=1; i<m_height; i++ ) //Try movin 1 space then 2, etc.
  305.       {
  306.       CPoint ptTarget = p->GetPos();
  307.  
  308.         ptTarget.y += i; //Move target point up
  309.         if ( OnBoard(ptTarget,p))
  310.           if ( !Conflict(ptTarget,p))
  311.             {
  312.             down = i; //Can move up i units
  313.             continue;
  314.             }            
  315.         break;    
  316.       }
  317.  
  318.   p->SetMoveLimits(up,right,down,left);
  319.  
  320.   return up|down|left|right;
  321.  
  322. }
  323.  
  324. void CPuzzleView::OnReset()
  325. {
  326.     ResetPieces();
  327.     InvalidateRect(NULL);
  328. }
  329.  
  330. void CPuzzleView::OnUpdateReset(CCmdUI* pCmdUI)
  331. {
  332.     pCmdUI->Enable();    
  333. }
  334.