NQueenDlg.cpp
上传用户:hncsjd
上传日期:2022-07-08
资源大小:3772k
文件大小:8k
源码类别:

其他智力游戏

开发平台:

Visual C++

  1. // NQueenDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "NQueen.h"
  5. #include "NQueenDlg.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CAboutDlg dialog used for App About
  13. class CAboutDlg : public CDialog
  14. {
  15. public:
  16. CAboutDlg();
  17. // Dialog Data
  18. //{{AFX_DATA(CAboutDlg)
  19. enum { IDD = IDD_ABOUTBOX };
  20. //}}AFX_DATA
  21. // ClassWizard generated virtual function overrides
  22. //{{AFX_VIRTUAL(CAboutDlg)
  23. protected:
  24. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  25. //}}AFX_VIRTUAL
  26. // Implementation
  27. protected:
  28. //{{AFX_MSG(CAboutDlg)
  29. //}}AFX_MSG
  30. DECLARE_MESSAGE_MAP()
  31. };
  32. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  33. {
  34. //{{AFX_DATA_INIT(CAboutDlg)
  35. //}}AFX_DATA_INIT
  36. }
  37. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  38. {
  39. CDialog::DoDataExchange(pDX);
  40. //{{AFX_DATA_MAP(CAboutDlg)
  41. //}}AFX_DATA_MAP
  42. }
  43. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  44. //{{AFX_MSG_MAP(CAboutDlg)
  45. // No message handlers
  46. //}}AFX_MSG_MAP
  47. END_MESSAGE_MAP()
  48. /////////////////////////////////////////////////////////////////////////////
  49. // CNQueenDlg dialog
  50. CNQueenDlg::CNQueenDlg(CWnd* pParent /*=NULL*/)
  51. : CDialog(CNQueenDlg::IDD, pParent)
  52. {
  53. //{{AFX_DATA_INIT(CNQueenDlg)
  54. m_e = _T("");
  55. //}}AFX_DATA_INIT
  56. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  57. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  58. }
  59. void CNQueenDlg::DoDataExchange(CDataExchange* pDX)
  60. {
  61. CDialog::DoDataExchange(pDX);
  62. //{{AFX_DATA_MAP(CNQueenDlg)
  63. DDX_Text(pDX, IDC_EDIT1, m_e);
  64. //}}AFX_DATA_MAP
  65. }
  66. BEGIN_MESSAGE_MAP(CNQueenDlg, CDialog)
  67. //{{AFX_MSG_MAP(CNQueenDlg)
  68. ON_WM_SYSCOMMAND()
  69. ON_WM_PAINT()
  70. ON_WM_QUERYDRAGICON()
  71. ON_BN_CLICKED(IDC_ABOUT, OnAbout)
  72. ON_WM_LBUTTONDOWN()
  73. ON_BN_CLICKED(IDC_JUDGE, OnJudge)
  74. //}}AFX_MSG_MAP
  75. END_MESSAGE_MAP()
  76. /////////////////////////////////////////////////////////////////////////////
  77. // CNQueenDlg message handlers
  78. BOOL CNQueenDlg::OnInitDialog()
  79. {
  80. CDialog::OnInitDialog();
  81. // Add "About..." menu item to system menu.
  82. // IDM_ABOUTBOX must be in the system command range.
  83. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  84. ASSERT(IDM_ABOUTBOX < 0xF000);
  85. CMenu* pSysMenu = GetSystemMenu(FALSE);
  86. if (pSysMenu != NULL)
  87. {
  88. CString strAboutMenu;
  89. strAboutMenu.LoadString(IDS_ABOUTBOX);
  90. if (!strAboutMenu.IsEmpty())
  91. {
  92. pSysMenu->AppendMenu(MF_SEPARATOR);
  93. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  94. }
  95. }
  96. // Set the icon for this dialog.  The framework does this automatically
  97. //  when the application's main window is not a dialog
  98. SetIcon(m_hIcon, TRUE); // Set big icon
  99. SetIcon(m_hIcon, FALSE); // Set small icon
  100. // TODO: Add extra initialization here
  101. N = 8;
  102. w = 400-400%N; //棋盘宽度(如果N不能整除400时,取宽度为最接近于400的、N的倍数)
  103. h = 400-400%N; //棋盘高度
  104. cell = w / N; //每格的宽度和高度
  105. return TRUE;  // return TRUE  unless you set the focus to a control
  106. }
  107. int queen[21][21];//={{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1},
  108. //{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1},
  109. //{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1},
  110. //{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1}}; //queen[i][j]为1表示该位置上已经放置了一个皇后
  111. void CNQueenDlg::OnSysCommand(UINT nID, LPARAM lParam)
  112. {
  113. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  114. {
  115. CAboutDlg dlgAbout;
  116. dlgAbout.DoModal();
  117. }
  118. else
  119. {
  120. CDialog::OnSysCommand(nID, lParam);
  121. }
  122. }
  123. // If you add a minimize button to your dialog, you will need the code below
  124. //  to draw the icon.  For MFC applications using the document/view model,
  125. //  this is automatically done for you by the framework.
  126. //参数:size-棋盘的规模,cell-每格的大小(宽度和高度)
  127. void DrawBoard(CDC *pDC, int size, int cell)
  128. {
  129. int i, j;
  130. CBrush w_brush, b_brush;
  131. b_brush.CreateSolidBrush(RGB(0, 0, 0));
  132. w_brush.CreateSolidBrush(RGB(255, 255, 255));
  133. for(i=0; i<size; i++)
  134. {
  135. for(j=0; j<size; j++)
  136. {
  137. if((i+j)%2 ==0 )
  138. pDC->FillRect(CRect(i*cell, j*cell, (i+1)*cell, (j+1)*cell), &b_brush);
  139. else
  140. pDC->FillRect(CRect(i*cell, j*cell, (i+1)*cell, (j+1)*cell), &w_brush);
  141. }
  142. }
  143. CPen b_pen(PS_SOLID, 1, RGB(0, 0, 0));
  144. int board = cell*size;
  145. pDC->SelectObject(b_pen);  
  146. pDC->MoveTo(0, 0);
  147. pDC->LineTo(0, board-1);
  148. pDC->LineTo(board-1, board-1);
  149. pDC->LineTo(board-1, 0);  
  150. pDC->LineTo(0, 0);  
  151. }
  152. void CNQueenDlg::OnPaint()
  153. {
  154. if (IsIconic())
  155. {
  156. CPaintDC dc(this); // device context for painting
  157. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  158. // Center icon in client rectangle
  159. int cxIcon = GetSystemMetrics(SM_CXICON);
  160. int cyIcon = GetSystemMetrics(SM_CYICON);
  161. CRect rect;
  162. GetClientRect(&rect);
  163. int x = (rect.Width() - cxIcon + 1) / 2;
  164. int y = (rect.Height() - cyIcon + 1) / 2;
  165. // Draw the icon
  166. dc.DrawIcon(x, y, m_hIcon);
  167. }
  168. else
  169. {
  170. LONG left = 20, top = 20; //N皇后棋盘左上角位置
  171. CPaintDC dc(this); // device context for painting
  172. CDC MemDC; //定义一个显示设备对象
  173. CBitmap MemBitmap;//定义一个位图对象
  174. CPen b_pen(PS_SOLID, 1, RGB(0, 0, 255)); //画外框的画笔
  175. CBrush w_brush, y_brush;
  176. w_brush.CreateSolidBrush(RGB(255, 255, 255)); //填充外框的画刷
  177. y_brush.CreateSolidBrush(RGB(255, 255, 0));
  178. MemDC.CreateCompatibleDC(&dc); //建立兼容的内存显示设备
  179. MemBitmap.CreateCompatibleBitmap(&dc,w, h);//建立一个兼容的位图
  180. CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);
  181. MemDC.FillRect(CRect(20, 20, w, h), &w_brush);
  182. DrawBoard(&MemDC, N, cell); //画棋盘
  183. MemDC.SelectObject(b_pen);
  184. MemDC.SelectObject(y_brush);
  185. int i, j;
  186. int x1,y1,x2,y2; //绘制圆圈时的边界
  187. for( i=0; i<N; i++)
  188. {
  189. for( j=0; j<N; j++ )
  190. {
  191. if( queen[i][j] == 1 )
  192. {
  193. x1 = j*cell+cell/6;
  194. y1 = i*cell+cell/6;
  195. x2 = j*cell+cell/6+cell*2/3;
  196. y2 = i*cell+cell/6+cell*2/3;
  197. MemDC.Ellipse(x1,y1,x2,y2);
  198. }
  199. }
  200. }
  201. dc.BitBlt(20,20,w, h,&MemDC,0,0,SRCCOPY);
  202. CDialog::OnPaint();
  203. }
  204. }
  205. // The system calls this to obtain the cursor to display while the user drags
  206. //  the minimized window.
  207. HCURSOR CNQueenDlg::OnQueryDragIcon()
  208. {
  209. return (HCURSOR) m_hIcon;
  210. }
  211. void CNQueenDlg::OnAbout() 
  212. {
  213. CAboutDlg dlgAbout;
  214. dlgAbout.DoModal();
  215. }
  216. void CNQueenDlg::OnLButtonDown(UINT nFlags, CPoint point) 
  217. {
  218. int c = (point.x-20)/cell, r = (point.y-20)/cell;
  219. queen[r][c] = 1 - queen[r][c];
  220. RECT rect;
  221. rect.left = 20+c*cell, rect.top = 20+r*cell;
  222. rect.right = 20+(c+1)*cell, rect.bottom = 20+(r+1)*cell;
  223. InvalidateRect( &rect );
  224. CDialog::OnLButtonDown(nFlags, point);
  225. }
  226. void CNQueenDlg::OnJudge() 
  227. {
  228. int i, j;
  229. bool right = true;
  230. int count = 0; //每行、列、每条对角想上皇后的个数
  231. for( i=0; i<8; i++ ) //检查每行,每行有且只有一个
  232. {
  233. count = 0;
  234. for( j=0; j<8; j++ )
  235. if( queen[i][j]==1 )  count++;
  236. if( count!=1 )
  237. { right = false;  break; }
  238. }
  239. if( !right )
  240. { MessageBox( "请重新安排!","抱歉,解不对!", MB_OK );  return; }
  241. for( i=0; i<8; i++ ) //检查每列,每列有且只有一个
  242. {
  243. count = 0;
  244. for( j=0; j<8; j++ )
  245. if( queen[j][i]==1 )  count++;
  246. if( count!=1 )
  247. { right = false;  break; }
  248. }
  249. if( !right )
  250. { MessageBox( "请重新安排!","抱歉,解不对!", MB_OK );  return; }
  251. for( i=0; i<8; i++ ) //检查每条主对角线,每条主对角线上最多只能有1个
  252. {
  253. count = 0;
  254. for( j=0; i+j<8; j++ ) //检查与queen[i][0]位于同一条主对角线的位置
  255. if( queen[i+j][j]==1 )  count++;
  256. if( count>1 )
  257. { right = false;  break; }
  258. count = 0;
  259. for( j=0; i+j<8; j++ ) //检查与queen[0][i]位于同一条主对角线的位置
  260. if( queen[j][i+j]==1 )  count++;
  261. if( count>1 )
  262. { right = false;  break; }
  263. }
  264. if( !right )
  265. { MessageBox( "请重新安排!","抱歉,解不对!", MB_OK );  return; }
  266. for( i=0; i<8; i++ ) //检查每条次对角线,每条次对角线上最多只能有1个
  267. {
  268. count = 0;
  269. for( j=0; i+j<8; j++ ) //检查与queen[i][7]位于同一条次对角线的位置
  270. if( queen[i+j][7-j]==1 )  count++;
  271. if( count>1 )
  272. { right = false;  break; }
  273. count = 0;
  274. for( j=0; i-j>=0; j++ ) //检查与queen[0][i]位于同一条次对角线的位置
  275. if( queen[j][i-j]==1 )  count++;
  276. if( count>1 )
  277. { right = false;  break; }
  278. }
  279. if( !right )
  280. { MessageBox( "请重新安排!","抱歉,解不对!", MB_OK );  return; }
  281. MessageBox( "您找到一个解!","恭喜您!", MB_OK );
  282. }