棋盘覆盖
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 }