home *** CD-ROM | disk | FTP | other *** search
/ Troubleshooting Netware Systems / CSTRIAL0196.BIN / attach / msj / v10n08 / mfcpart3.exe / TICTAC.CPP < prev    next >
C/C++ Source or Header  |  1995-08-01  |  6KB  |  253 lines

  1. //***************************************************************************
  2. //
  3. //  TicTac demonstrates mouse handling in an MFC program.
  4. //
  5. //***************************************************************************
  6.  
  7. #include <afxwin.h>
  8. #include "tictac.h"
  9.  
  10. CMyApp myApp;
  11.  
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CMyApp member functions
  14.  
  15. BOOL CMyApp::InitInstance ()
  16. {
  17.     m_pMainWnd = new CMainWindow ();
  18.     m_pMainWnd->ShowWindow (m_nCmdShow);
  19.     m_pMainWnd->UpdateWindow ();
  20.     return TRUE;
  21. }
  22.  
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CMainWindow message map and member functions
  25.  
  26. BEGIN_MESSAGE_MAP (CMainWindow, CWnd)
  27.     ON_WM_PAINT ()
  28.     ON_WM_LBUTTONDOWN ()
  29.     ON_WM_LBUTTONDBLCLK ()
  30.     ON_WM_RBUTTONDOWN ()
  31. END_MESSAGE_MAP ()
  32.  
  33. CMainWindow::CMainWindow ()
  34. {
  35.     int nCoords[9][4] = {
  36.          16,  16, 112, 112,
  37.         128,  16, 224, 112,
  38.         240,  16, 336, 112,
  39.          16, 128, 112, 224,
  40.         128, 128, 224, 224,
  41.         240, 128, 336, 224,
  42.          16, 240, 112, 336,
  43.         128, 240, 224, 336,
  44.         240, 240, 336, 336
  45.     };
  46.  
  47.     m_nNextChar = EX;
  48.  
  49.     for (int i=0; i<9; i++) {
  50.         m_nGameGrid[i] = 0;
  51.         m_rect[i].SetRect (nCoords[i][0], nCoords[i][1], nCoords[i][2],
  52.             nCoords[i][3]);
  53.     }
  54.  
  55.     CString myClass = AfxRegisterWndClass (CS_DBLCLKS,
  56.         myApp.LoadStandardCursor (IDC_ARROW),
  57.         (HBRUSH) ::GetStockObject (LTGRAY_BRUSH),
  58.         myApp.LoadStandardIcon (IDI_APPLICATION));
  59.  
  60.     CreateEx (WS_EX_DLGMODALFRAME, myClass, "Tic-Tac-Toe",
  61.         WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
  62.         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  63.         NULL, NULL, NULL);
  64.  
  65.     CRect rect (0, 0, 352, 352);
  66.     CalcWindowRect (&rect);
  67.  
  68.     SetWindowPos (NULL, 0, 0, rect.Width (), rect.Height (),
  69.         SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW);
  70. }
  71.  
  72. void CMainWindow::PostNcDestroy ()
  73. {
  74.     delete this;
  75. }
  76.  
  77. void CMainWindow::OnPaint ()
  78. {
  79.     CPaintDC dc (this);
  80.     DrawBoard (&dc);    
  81. }
  82.  
  83. void CMainWindow::OnLButtonDown (UINT nFlags, CPoint point)
  84. {
  85.     if (m_nNextChar != EX)
  86.         return;
  87.  
  88.     int nPos = GetRectID (point);
  89.     if (nPos == -1)
  90.         return;
  91.         
  92.     if (m_nGameGrid[nPos] != 0)
  93.         return;
  94.  
  95.     m_nNextChar = OH;
  96.     m_nGameGrid[nPos] = EX;
  97.  
  98.     CClientDC dc (this);
  99.     DrawX (&dc, nPos);
  100.  
  101.     CheckForGameOver ();
  102. }
  103.  
  104. void CMainWindow::OnRButtonDown (UINT nFlags, CPoint point)
  105. {
  106.     if (m_nNextChar != OH)
  107.         return;
  108.  
  109.     int nPos = GetRectID (point);
  110.     if (nPos == -1)
  111.         return;
  112.         
  113.     if (m_nGameGrid[nPos] != 0)
  114.         return;
  115.  
  116.     m_nNextChar = EX;
  117.     m_nGameGrid[nPos] = OH;
  118.  
  119.     CClientDC dc (this);
  120.     DrawO (&dc, nPos);
  121.  
  122.     CheckForGameOver ();
  123. }
  124.  
  125. void CMainWindow::OnLButtonDblClk (UINT nFlags, CPoint point)
  126. {
  127.     CClientDC dc (this);
  128.  
  129.     if (dc.GetPixel (point) == RGB (0, 0, 0))
  130.         ResetGame ();
  131. }
  132.  
  133. int CMainWindow::GetRectID (CPoint point)
  134. {
  135.     for (int i=0; i<9; i++) {
  136.         if (m_rect[i].PtInRect (point))
  137.             return i;
  138.     }
  139.     return -1;
  140. }
  141.  
  142. void CMainWindow::DrawBoard (CDC* pDC)
  143. {
  144.     CPen pen (PS_SOLID, 16, RGB (0, 0, 0));
  145.     CPen* pOldPen = pDC->SelectObject (&pen);
  146.  
  147.     pDC->MoveTo (120, 16);
  148.     pDC->LineTo (120, 336);
  149.  
  150.     pDC->MoveTo (232, 16);
  151.     pDC->LineTo (232, 336);
  152.  
  153.     pDC->MoveTo (16, 120);
  154.     pDC->LineTo (336, 120);
  155.  
  156.     pDC->MoveTo (16, 232);
  157.     pDC->LineTo (336, 232);
  158.  
  159.     for (int i=0; i<9; i++) {
  160.         if (m_nGameGrid[i] == EX)
  161.             DrawX (pDC, i);
  162.         else if (m_nGameGrid[i] == OH)
  163.             DrawO (pDC, i);
  164.     }
  165.     pDC->SelectObject (pOldPen);
  166. }
  167.  
  168. void CMainWindow::DrawX (CDC* pDC, int nPos)
  169. {
  170.     CPen pen (PS_SOLID, 16, RGB (255, 0, 0));
  171.     CPen* pOldPen = pDC->SelectObject (&pen);
  172.  
  173.     pDC->MoveTo (m_rect[nPos].left + 16, m_rect[nPos].top + 16);
  174.     pDC->LineTo (m_rect[nPos].right - 16, m_rect[nPos].bottom - 16);
  175.  
  176.     pDC->MoveTo (m_rect[nPos].left + 16, m_rect[nPos].bottom - 16);
  177.     pDC->LineTo (m_rect[nPos].right - 16, m_rect[nPos].top + 16);
  178.     
  179.     pDC->SelectObject (pOldPen);
  180. }
  181.  
  182. void CMainWindow::DrawO (CDC* pDC, int nPos)
  183. {
  184.     CPen pen (PS_SOLID, 16, RGB (0, 0, 255));
  185.     CPen* pOldPen = pDC->SelectObject (&pen);
  186.     pDC->SelectStockObject (NULL_BRUSH);
  187.  
  188.     pDC->Ellipse (m_rect[nPos].left + 16, m_rect[nPos].top + 16,
  189.         m_rect[nPos].right - 16, m_rect[nPos].bottom - 16);
  190.  
  191.     pDC->SelectObject (pOldPen);
  192. }
  193.  
  194. void CMainWindow::CheckForGameOver ()
  195. {
  196.     int nWinner;
  197.  
  198.     if (nWinner = IsWinner ()) {
  199.         CString string = (nWinner == EX) ? "The X's win!" : "The O's win!";
  200.         MessageBox (string, "Game Over", MB_ICONEXCLAMATION | MB_OK);
  201.         ResetGame ();
  202.     }
  203.  
  204.     else if (IsDraw ()) {
  205.         MessageBox ("It's a draw!", "Game Over", MB_ICONEXCLAMATION | MB_OK);
  206.         ResetGame ();
  207.     }
  208. }
  209.  
  210. int CMainWindow::IsWinner ()
  211. {
  212.     static int nPattern[8][3] = {
  213.         0, 1, 2,
  214.         3, 4, 5,
  215.         6, 7, 8,
  216.         0, 3, 6,
  217.         1, 4, 7,
  218.         2, 5, 8,
  219.         0, 4, 8,
  220.         2, 4, 6
  221.     };
  222.  
  223.     for (int i=0; i<8; i++) {
  224.         if ((m_nGameGrid[nPattern[i][0]] == EX) &&
  225.             (m_nGameGrid[nPattern[i][1]] == EX) &&
  226.             (m_nGameGrid[nPattern[i][2]] == EX))
  227.             return EX;
  228.  
  229.         if ((m_nGameGrid[nPattern[i][0]] == OH) &&
  230.             (m_nGameGrid[nPattern[i][1]] == OH) &&
  231.             (m_nGameGrid[nPattern[i][2]] == OH))
  232.             return OH;
  233.     }
  234.     return 0;
  235. }
  236.  
  237. BOOL CMainWindow::IsDraw ()
  238. {
  239.     for (int i=0; i<9; i++) {
  240.         if (m_nGameGrid[i] == 0)
  241.             return FALSE;
  242.     }
  243.     return TRUE;
  244. }
  245.  
  246. void CMainWindow::ResetGame ()
  247. {
  248.     m_nNextChar = EX;
  249.     for (int i=0; i<9; i++)
  250.         m_nGameGrid[i] = 0;
  251.     InvalidateRect (NULL);
  252. }
  253.