棋盘覆盖

  1 /*------------------------------------------------------------
  2    chessboard.c -- 棋盘覆盖
  3 
  4                   邝翼飞   2010
  5   ------------------------------------------------------------*/
  6 
  7 #include <windows.h>
  8 #include <math.h>
  9 
 10 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
 11 void chessBoard(HWND hwnd, int tr, int tc, int dr, int dc, int ssize, int windoww);
 12 // 控件声明
 13 HWND hedit1, hedit2, hedit3;
 14 HWND hwndButton1, hwndButton2, hwndButton3, hwndButton4;
 15 
 16 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int nCmdShow)
 17 {
 18     HWND      hwnd;
 19     MSG       msg ;
 20     WNDCLASS  wndclass ;
 21     static    CHAR szAppName[]="CHESSBOARD";
 22     int       cxScreen, cyScreen ;  // 用于获得屏幕的大小
 23     
 24     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
 25     wndclass.lpfnWndProc   = WndProc ;
 26     wndclass.cbClsExtra    = 0 ;
 27     wndclass.cbWndExtra    = 0 ;
 28     wndclass.hInstance     = hInstance ;
 29     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
 30     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
 31     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
 32     wndclass.lpszMenuName  = NULL ;
 33     wndclass.lpszClassName = szAppName ;
 34 
 35     if (!RegisterClass (&wndclass))
 36     {
 37         MessageBox (NULL, TEXT ("注册窗口出错!"), szAppName, MB_ICONERROR) ;
 38         return 0 ;
 39     }
 40     
 41     cxScreen = GetSystemMetrics (SM_CXSCREEN) ;
 42     cyScreen = GetSystemMetrics (SM_CYSCREEN) ;
 43     
 44     hwnd = CreateWindow ( szAppName,            // 创建主窗口
 45                           "棋盘覆盖",
 46                           WS_OVERLAPPEDWINDOW & (~WS_SIZEBOX) & (~WS_MAXIMIZEBOX),
 47                           ( cxScreen-820 ) / 2,
 48                           ( cyScreen-650 ) / 2,
 49                           820,
 50                           650,
 51                           NULL,
 52                           NULL,
 53                           hInstance,
 54                           NULL ) ;
 55     
 56     ShowWindow ( hwnd, nCmdShow ) ;
 57     UpdateWindow ( hwnd ) ;
 58     
 59     hwndButton1 = CreateWindow ("BUTTON",        // 创建 【开始】 按钮
 60                                  "开始", 
 61                                  WS_VISIBLE | WS_CHILD,
 62                                  640,
 63                                  5,
 64                                  75,
 65                                  20,
 66                                  hwnd,
 67                                  NULL,
 68                                  hInstance,
 69                                  NULL);
 70     hwndButton2 = CreateWindow ( "BUTTON",       // 创建 【重新设置】 按钮
 71                                  "重新设置", 
 72                                  WS_VISIBLE | WS_CHILD,
 73                                  640,
 74                                  30,
 75                                  75,
 76                                  20,
 77                                   hwnd,
 78                                  NULL,
 79                                  hInstance,
 80                                  NULL ) ; 
 81     hwndButton3 = CreateWindow ( "BUTTON",       // 创建 【帮助】 按钮
 82                                  "帮助", 
 83                                  WS_VISIBLE | WS_CHILD,
 84                                    720,
 85                                  30,
 86                                  75,
 87                                  20,
 88                                  hwnd,
 89                                  NULL,
 90                                  hInstance,
 91                                  NULL ) ;
 92     hwndButton4 = CreateWindow ( "BUTTON",       // 创建 【退出】 按钮
 93                                  "退出", 
 94                                  WS_VISIBLE | WS_CHILD,
 95                                  720,
 96                                  5,
 97                                  75,
 98                                  20,
 99                                  hwnd,
100                                  NULL,
101                                  hInstance,
102                                  NULL ) ;
103     hedit1 = CreateWindow ( "EDIT",              // 创建 【棋盘大小】 编辑框
104                             "4", 
105                             WS_VISIBLE | WS_CHILD,
106                             720,
107                             55,
108                             75,
109                             20,
110                             hwnd,
111                             NULL,
112                             hInstance,
113                             NULL ) ;
114     hedit2 = CreateWindow ( "EDIT",              // 创建 【特殊方格X轴】 编辑框
115                             "0", 
116                             WS_VISIBLE | WS_CHILD,
117                             675,
118                             105,
119                             35,
120                             20,
121                             hwnd,
122                             NULL,
123                             hInstance,
124                             NULL ) ;
125     hedit3 = CreateWindow ( "EDIT",              // 创建 【特殊方格Y轴】 编辑框
126                             "0", 
127                             WS_VISIBLE | WS_CHILD,
128                             755,
129                             105,
130                             35,
131                             20,
132                             hwnd,
133                             NULL,
134                             hInstance,
135                             NULL ) ;
136        
137     while (GetMessage (&msg, NULL, 0, 0))
138     {
139         TranslateMessage (&msg) ;
140         DispatchMessage (&msg) ;
141     }
142     return msg.wParam ;
143 }
144 
145 LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
146 {
147     HDC         hdc ;
148     PAINTSTRUCT ps ;
149     RECT        rect ;
150     HBRUSH      hbrush ;
151     int         x=620+50, y=160 ;
152     int         dr, dc, ssize ;
153     CHAR        lpsEditText[10] ;
154     int         i, j ;
155     
156     switch (message)
157     {
158     case WM_CREATE:
159         return 0 ;
160         
161     case WM_PAINT:
162         hdc = BeginPaint (hwnd, &ps) ;
163         // 画出窗口右方的元素
164     //    Sleep(500);
165         GetClientRect (hwnd, &rect) ;
166         MoveToEx (hdc, 620, 0, NULL);
167         LineTo (hdc, 620, 620) ;
168         MoveToEx (hdc, 620, 130, NULL);
169         LineTo (hdc, 820,130) ;
170         TextOut (hdc,640,55,"棋盘大小",8);
171         TextOut (hdc,640,80,"特殊方格位置",12);
172         TextOut (hdc,640,105,"横轴",4);
173         TextOut (hdc,720,105,"纵轴",4);
174         TextOut (hdc,640,135,"四种 L 型牌",11);
175         Rectangle (hdc,10,10,610,610);
176         // 第一种L形牌            
177         hbrush = CreateSolidBrush ( RGB ( 255, 0, 0 ) );
178         SelectObject ( hdc, hbrush );
179         Rectangle ( hdc, x, y, x + 50, y + 50 );
180         Rectangle ( hdc, x + 50, y, x + 50 + 50, y + 50 );
181         Rectangle ( hdc, x, y + 50, x + 50, y + 50 + 50 );
182         // 第二种L形牌
183         y=160+100+8;
184         x=620+50;
185         hbrush=CreateSolidBrush( RGB ( 0, 255, 0 ) );
186         SelectObject(hdc,hbrush);
187         Rectangle(hdc,x,y,x+50,y+50);
188         Rectangle(hdc,x,y+50,x+50,y+50+50);
189         Rectangle(hdc,x+50,y+50,x+50+50,y+50+50);
190         // 第三种L形牌
191         y=160+100+8+100+8;
192         x=620+50;
193         hbrush=CreateSolidBrush ( RGB ( 0, 0, 255 ) );
194         SelectObject(hdc,hbrush);
195         Rectangle(hdc,x+50,y,x+50+50,y+50);
196         Rectangle(hdc,x+50,y+50,x+50+50,y+50+50);
197         Rectangle(hdc,x,y+50,x+50,y+50+50);
198         // 第四种L形牌
199         y=160+100+8+100+8+100+8;
200         x=620+50;
201         hbrush=CreateSolidBrush ( RGB ( 255, 255, 0 ) );
202         SelectObject(hdc,hbrush);
203         Rectangle(hdc,x,y,x+50,y+50);
204         Rectangle(hdc,x+50,y,x+50+50,y+50);
205         Rectangle(hdc,x+50,y+50,x+50+50,y+50+50);
206         
207         EndPaint (hwnd, &ps) ;
208         return 0 ;
209 
210     case WM_COMMAND :        // 处理按钮控件产生的消息事件
211         if(lParam==(long)hwndButton4)       // 退出按钮
212         {
213             PostQuitMessage (0) ;
214             return 0;
215         }
216         else if(lParam==(long)hwndButton3)  // 帮助按钮
217         {
218             hdc = GetDC (hwnd) ;
219             hbrush=CreateSolidBrush ( RGB ( 255, 255, 255 ) );
220             SelectObject(hdc,hbrush);
221             Rectangle(hdc,10,10,610,610);
222             TextOut ( hdc,240,35, "程序使用说明",12 );
223             TextOut ( hdc,20,65,  "请在棋盘大小右边的编辑框里输入一个正整数且为2的k次方,程序将会成一个n*n的",73 );
224             TextOut ( hdc,20,100, "棋盘,n为输入的数。然后设置特殊方格在棋盘中的坐标,注意棋盘的横纵坐标都是",73 );
225             TextOut ( hdc,20,135, "从零开始的,特殊方格将被填成黑色。做完上述步骤后按开始按钮可观察到棋盘覆",72 );
226             TextOut ( hdc,20,170, "盖的结果,按重新设置按钮将使编辑框中出现默认值并可重新设置参数。",64 );
227             DeleteObject (SelectObject (hdc, hbrush)) ;
228             ReleaseDC (hwnd, hdc) ;
229             return 0;
230         }
231         else if(lParam==(long)hwndButton1)  // 开始按钮
232         {
233             GetWindowText(hedit1,lpsEditText,10);
234             ssize=atoi(lpsEditText);
235             if(ssize>64)
236             {
237                 MessageBox(hwnd,"棋盘大小太大,显示效果不好!","提示",MB_OK);
238                 return 0;
239             }
240             if(ssize<=0)
241             {
242                 MessageBox(hwnd,"棋盘大小不能为非整数!","提示",MB_OK);
243                 return 0;
244             }
245             if(ssize!=1 && ssize!=2)
246             {
247                 if(ssize%2!=0)
248                 {
249                     MessageBox(hwnd,"棋盘大小不是2的正次方幂!","提示",MB_OK);
250                     return 0;
251                 }
252                 else
253                 {
254                     for(i=3;i<ssize;i=i+2)
255                         if(ssize%i==0 )
256                         {
257                             MessageBox(hwnd,"棋盘大小不是2的正次方幂!","提示",MB_OK);
258                             return 0;
259                         }
260                 }
261             }
262             GetWindowText(hedit2,lpsEditText,10);
263             dr=atoi(lpsEditText);
264             GetWindowText(hedit3,lpsEditText,10);
265             dc=atoi(lpsEditText);
266             if(dr<0 || dc<0 || dr>=ssize || dc>=ssize)
267             {
268                 MessageBox(hwnd,"特殊方格的坐标参数设置不正确!","提示",MB_OK);
269                 return 0;
270             }
271             hdc = GetDC (hwnd) ;
272             hbrush=CreateSolidBrush ( RGB ( 255, 255, 255 ) );
273             SelectObject(hdc,hbrush);
274             Rectangle(hdc,10,10,610,610);
275             // 画出一个ssize*ssize的棋盘,方格颜色为白色
276             for(j=0;j<ssize;j++)
277                 for(i=0;i<ssize;i++)
278                     Rectangle ( hdc,
279                     10+i*(600/ssize),
280                     10+j*(600/ssize),
281                     10+i*(600/ssize)+600/ssize,
282                     10+j*(600/ssize)+600/ssize  );
283 
284                 DeleteObject (SelectObject (hdc, hbrush)) ;
285                 SelectObject( hdc, CreateSolidBrush ( RGB ( 0, 0, 0 ) ) );
286                 // 画特殊方格,方格颜色为黑色
287                 Rectangle(hdc,10+dc*(600/ssize),10+dr*(600/ssize),10+dc*(600/ssize)+600/ssize,10+dr*(600/ssize)+600/ssize);        
288                 DeleteObject (SelectObject (hdc, hbrush)) ;
289                 ReleaseDC (hwnd, hdc) ;
290                 chessBoard(hwnd,0,0,dr,dc,ssize,600);///////////////////////////////////////////////////////////
291 
292                 return 0;
293         }
294         else if(lParam==(long)hwndButton2)  // 重新设置按钮
295         {
296             SetWindowText(hedit1,"4");
297             SetWindowText(hedit2,"0");
298             SetWindowText(hedit3,"0");
299             return 0;
300         }
301         return 0;
302         
303         
304     case WM_DESTROY:
305         PostQuitMessage (0) ;
306         return 0 ;
307      }
308      return DefWindowProc (hwnd, message, wParam, lParam) ;
309 }
310 
311 void drawLcard1(HWND hwnd,int tr,int tc,int rectw);  // 第一种方格的画法函数
312 void drawLcard2(HWND hwnd,int tr,int tc,int rectw);  // 第二种方格的画法函数
313 void drawLcard3(HWND hwnd,int tr,int tc,int rectw);  // 第三种方格的画法函数
314 void drawLcard4(HWND hwnd,int tr,int tc,int rectw);  // 第四种方格的画法函数
315 
316 void chessBoard(HWND hwnd,int tr,int tc,int dr,int dc,int ssize,int windoww) // 递归分治法覆盖棋盘
317 {   // (tr,tc): 棋盘左上角坐标;  (dr,dc): 特殊方格坐标; ssize: 棋盘大小(一行或一列的方格数);  windoww: 棋盘宽度   
318     int s;           // 用于递归相当于ssize
319     int w;           // 用于递归相当于windoww
320     int rectw;       // 棋盘中一个方格的宽度
321     
322     int flag=0;      // 标志特殊方格位于哪个子棋盘区域
323     if(ssize==1)
324         return;
325     rectw=windoww/ssize;
326     if(ssize==2)
327     {
328         if(dr==tr && dc==tc)
329         {
330             Sleep(500);
331             drawLcard3(hwnd,tr,tc,rectw);
332             return;
333         }
334         else if(dr==tr && dc==tc+1)
335         {
336             Sleep(500);
337             drawLcard2(hwnd,tr,tc,rectw);
338             return;
339         }
340         else if(dr==tr+1 && dc==tc)
341         {
342             Sleep(500);
343             drawLcard4(hwnd,tr,tc,rectw);
344             return;
345         }
346         else 
347         {
348             Sleep(500);
349             drawLcard1(hwnd,tr,tc,rectw);
350             return;
351         }
352     }
353 
354     s=ssize/2;
355     w=windoww/2;
356 
357     if(dr<tr+s && dc<tc+s)       // 特殊方格位于第一个子棋盘区域
358     {
359         flag=1;
360         chessBoard(hwnd,tr,tc,dr,dc,s,w);
361     }
362     else
363         chessBoard(hwnd,tr,tc,tr+s-1,tc+s-1,s,w);
364     
365 
366     if(dr<tr+s && dc>=tc+s)      // 特殊方格位于第二个子棋盘区域
367     {
368         flag=2;
369         chessBoard(hwnd,tr,tc+s,dr,dc,s,w);
370     }
371     else
372         chessBoard(hwnd,tr,tc+s,tr+s-1,tc+s,s,w);
373     
374 
375     if(dr>=tr+s && dc<tc+s)      // 特殊方格位于第三个子棋盘区域
376     {    
377         flag=3;
378         chessBoard(hwnd,tr+s,tc,dr,dc,s,w);
379     }
380     else
381         chessBoard(hwnd,tr+s,tc,tr+s,tc+s-1,s,w);
382     
383 
384     if(dr>=tr+s && dc>=tc+s)      // 特殊方格位于第四个子棋盘区域
385     {    
386         flag=4;
387         chessBoard(hwnd,tr+s,tc+s,dr,dc,s,w);
388     }
389     else
390         chessBoard(hwnd,tr+s,tc+s,tr+s,tc+s,s,w);
391 
392     if(flag==1)
393     {
394         Sleep(500);
395         drawLcard3(hwnd,tr+s-1,tc+s-1,rectw);
396         return;
397     }
398     else if(flag==2)
399     {
400         Sleep(500);
401         drawLcard2(hwnd,tr+s-1,tc+s-1,rectw);
402         return;
403     }
404     else if(flag==3)
405     {
406         Sleep(500);
407         drawLcard4(hwnd,tr+s-1,tc+s-1,rectw);
408         return;
409     }
410     else if(flag==4)
411     {
412         Sleep(500);
413         drawLcard1(hwnd,tr+s-1,tc+s-1,rectw);
414         return;
415     }
416     return;
417 }
418 
419 void drawLcard1(HWND hwnd,int tr,int tc,int rectw)
420 {
421     HDC     hdc ;
422     HBRUSH  hbrush;
423     int     x = 10 + tc * rectw,  y = 10 + tr * rectw;
424 
425     hdc = GetDC (hwnd) ;
426     hbrush = CreateSolidBrush ( RGB ( 255,0,0 ) ) ;
427     SelectObject ( hdc, hbrush ) ;
428     Rectangle ( hdc, x, y, x + rectw, y + rectw ) ;
429     Rectangle ( hdc, x + rectw, y, x + 2*rectw, y + rectw ) ;
430     Rectangle ( hdc, x, y + rectw, x + rectw, y + 2*rectw ) ;
431     DeleteObject (SelectObject (hdc, hbrush)) ;
432     SelectObject ( hdc, CreatePen(PS_DOT,1, RGB ( 255,0,0 )  ) );
433     MoveToEx(hdc,x+rectw,y,NULL);
434     LineTo(hdc,x+rectw,y+rectw);
435     LineTo(hdc,x,y+rectw);
436     ReleaseDC (hwnd, hdc) ;
437 }
438 
439 void drawLcard2(HWND hwnd,int tr,int tc,int rectw)
440 {
441     HDC      hdc ;
442     HBRUSH   hbrush;
443     int      x = 10 + tc * rectw,  y = 10 + tr * rectw;
444 
445     hdc = GetDC (hwnd) ;
446     hbrush = CreateSolidBrush ( RGB ( 0, 255, 0 ) ) ;
447     SelectObject ( hdc, hbrush ) ;
448     Rectangle ( hdc, x, y, x + rectw, y + rectw ) ;
449     Rectangle ( hdc, x, y + rectw, x + rectw, y + 2*rectw ) ;
450     Rectangle ( hdc, x + rectw, y + rectw, x + 2*rectw, y + 2*rectw ) ;
451     DeleteObject (SelectObject (hdc, hbrush)) ;
452     SelectObject ( hdc, CreatePen(PS_DOT,1, RGB ( 0, 255, 0 ) ) );
453     MoveToEx(hdc,x,y+rectw,NULL);
454     LineTo(hdc,x+rectw,y+rectw);
455     LineTo(hdc,x+rectw,y+2*rectw);
456     ReleaseDC (hwnd, hdc) ;
457 }
458 
459 void drawLcard3(HWND hwnd,int tr,int tc,int rectw)
460 {
461     HDC      hdc ;
462     HBRUSH   hbrush;
463     int      x = 10 + tc * rectw,  y = 10 + tr * rectw;
464 
465     hdc = GetDC (hwnd) ;
466     hbrush = CreateSolidBrush ( RGB ( 0, 0, 255 ) ) ;
467     SelectObject ( hdc, hbrush ) ;
468     Rectangle ( hdc, x + rectw, y, x + 2*rectw, y + rectw ) ;
469     Rectangle ( hdc, x, y + rectw, x + rectw, y + 2*rectw ) ;
470     Rectangle ( hdc, x + rectw, y + rectw, x + 2*rectw, y + 2*rectw ) ;
471     DeleteObject (SelectObject (hdc, hbrush)) ;
472     SelectObject ( hdc, CreatePen(PS_DOT,1,  RGB ( 0, 0, 255 ) ) );
473     MoveToEx(hdc,x+2*rectw,y+rectw,NULL);
474     LineTo(hdc,x+rectw,y+rectw);
475     LineTo(hdc,x+rectw,y+2*rectw);
476     ReleaseDC (hwnd, hdc) ;
477 }
478 
479 void drawLcard4(HWND hwnd,int tr,int tc,int rectw)
480 {
481     HDC      hdc ;
482     HBRUSH   hbrush;
483     int      x = 10 + tc * rectw,  y = 10 + tr * rectw;
484 
485     hdc = GetDC (hwnd) ;
486     hbrush = CreateSolidBrush ( RGB ( 255, 255, 0 ) ) ;
487     SelectObject ( hdc, hbrush ) ;
488     Rectangle ( hdc, x, y, x + rectw, y + rectw ) ;
489     Rectangle ( hdc, x + rectw, y, x + 2*rectw, y + rectw ) ;
490     Rectangle ( hdc, x + rectw, y + rectw, x + 2*rectw, y + 2*rectw ) ;
491     DeleteObject (SelectObject (hdc, hbrush)) ;
492     SelectObject ( hdc, CreatePen(PS_DOT,1,   RGB ( 255, 255, 0  ) ) );
493     MoveToEx(hdc,x+rectw,y,NULL);
494     LineTo(hdc,x+rectw,y+rectw);
495     LineTo(hdc,x+2*rectw,y+rectw);
496     ReleaseDC (hwnd, hdc) ;
497 }

 

posted @ 2014-07-05 22:05  kyf  阅读(641)  评论(0编辑  收藏  举报