[游戏模版18] Win32 五子棋
生活随笔
收集整理的這篇文章主要介紹了
[游戏模版18] Win32 五子棋
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
?
>_<:Learning its AI logic.
>_<:resource
>_<:code:
1 #include <windows.h> 2 // C 運(yùn)行時頭文件 3 #include <stdlib.h> 4 #include <cstdio> 5 #include <malloc.h> 6 #include <memory.h> 7 #include <tchar.h> 8 #include <time.h> 9 #include <string> 10 #include <cmath> 11 12 #define MAX_LOADSTRING 100 13 // 全局變量: 14 HINSTANCE hInst; // 當(dāng)前實(shí)例 15 TCHAR szTitle[MAX_LOADSTRING]; // 標(biāo)題欄文本 16 TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口類名 17 HBITMAP cheers[2]; 18 HDC hdc,mdc,bufdc; 19 HWND hWnd; 20 DWORD tPre,tNow; 21 int board[10][10]; //記錄棋盤上格子的信息0,1,2分標(biāo)表示玩家棋子、電腦棋子、空 22 bool ptab[10][10][192]; //玩家獲勝表 23 bool ctab[10][10][192]; //電腦獲勝表 24 int win[2][192]; 25 int num[2]; //分別計算玩家和計算機(jī)下棋個數(shù) 26 bool turn,over;//turn 用來指示是有哪一方下棋,true玩家;false電腦;;over 指示棋局是否結(jié)束,ture結(jié)束 27 int begin; 28 int winner; //指示當(dāng)前棋局誰贏0表示玩家贏;1表示電腦贏;2表示平局 29 30 // 此代碼模塊中包含的函數(shù)的前向聲明: 31 ATOM MyRegisterClass(HINSTANCE hInstance); 32 BOOL InitInstance(HINSTANCE, int); 33 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 34 INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); 35 void MyPaint(HDC hdc); 36 void InitGame();//游戲初始操作 37 void ComTurn();//計算機(jī)下棋時計算分?jǐn)?shù)決定下棋位置 38 39 int APIENTRY _tWinMain(HINSTANCE hInstance, 40 HINSTANCE hPrevInstance, 41 LPTSTR lpCmdLine, 42 int nCmdShow){ 43 44 MSG msg; 45 MyRegisterClass(hInstance); 46 // 執(zhí)行應(yīng)用程序初始化: 47 if (!InitInstance (hInstance, nCmdShow)){ 48 return FALSE; 49 } 50 // 主消息循環(huán): 51 while (GetMessage(&msg, NULL, 0, 0)){ 52 TranslateMessage(&msg); 53 DispatchMessage(&msg); 54 } 55 return (int) msg.wParam; 56 } 57 58 // 函數(shù): MyRegisterClass() 59 // 60 // 目的: 注冊窗口類。 61 ATOM MyRegisterClass(HINSTANCE hInstance){ 62 WNDCLASSEX wcex; 63 64 wcex.cbSize = sizeof(WNDCLASSEX); 65 66 wcex.style = CS_HREDRAW | CS_VREDRAW; 67 wcex.lpfnWndProc = WndProc; 68 wcex.cbClsExtra = 0; 69 wcex.cbWndExtra = 0; 70 wcex.hInstance = hInstance; 71 wcex.hIcon = NULL; 72 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 73 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 74 wcex.lpszMenuName = "Beautifulzzzz"; 75 wcex.lpszClassName = "Beautifulzzzz"; 76 wcex.hIconSm = NULL; 77 78 return RegisterClassEx(&wcex); 79 } 80 81 // 82 // 函數(shù): InitInstance(HINSTANCE, int) 83 // 84 // 目的: 保存實(shí)例句柄并創(chuàng)建主窗口 85 // 86 // 注釋: 87 // 88 // 在此函數(shù)中,我們在全局變量中保存實(shí)例句柄并 89 // 創(chuàng)建和顯示主程序窗口。 90 // 棋盤拼接以及調(diào)用InitGame()開始棋局 91 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){ 92 HBITMAP tile,bmp; 93 int rowNum,colNum; 94 int i,x,y; 95 96 hInst = hInstance; // 將實(shí)例句柄存儲在全局變量中 97 98 begin=9; 99 hWnd = CreateWindow("Beautifulzzzz","Beautifulzzzz", WS_OVERLAPPEDWINDOW, 100 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); 101 102 if (!hWnd) 103 { 104 return FALSE; 105 } 106 107 MoveWindow(hWnd,10,10,480,550,true); 108 ShowWindow(hWnd, nCmdShow); 109 UpdateWindow(hWnd); 110 111 hdc=GetDC(hWnd); 112 mdc=CreateCompatibleDC(hdc); 113 bufdc=CreateCompatibleDC(hdc); 114 115 bmp=CreateCompatibleBitmap(hdc,450,450); 116 SelectObject(mdc,bmp); 117 118 tile=(HBITMAP)LoadImageA(NULL,"tile.bmp",IMAGE_BITMAP,45,45,LR_LOADFROMFILE); 119 cheers[0]=(HBITMAP)LoadImageA(NULL,"cheers[0].bmp",IMAGE_BITMAP,38,38,LR_LOADFROMFILE); 120 cheers[1]=(HBITMAP)LoadImageA(NULL,"cheers[1].bmp",IMAGE_BITMAP,38,38,LR_LOADFROMFILE); 121 122 for(i=0;i<100;i++)//產(chǎn)生棋盤 123 { 124 rowNum=i/10; 125 colNum=i%10; 126 x=colNum*45; 127 y=rowNum*45; 128 129 SelectObject(bufdc,tile); 130 BitBlt(mdc,x,y,45,45,bufdc,0,0,SRCCOPY); 131 } 132 133 InitGame();//初始化 134 135 SetTimer(hWnd,1,200,NULL); 136 MyPaint(hdc); 137 138 begin=8; 139 return TRUE; 140 } 141 142 // 143 // 函數(shù): WndProc(HWND, UINT, WPARAM, LPARAM) 144 // 145 // 目的: 處理主窗口的消息。 146 // 147 // WM_COMMAND - 處理應(yīng)用程序菜單 148 // WM_PAINT - 繪制主窗口 149 // WM_DESTROY - 發(fā)送退出消息并返回 150 // 151 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ 152 int wmId, wmEvent; 153 PAINTSTRUCT ps; 154 int x,y,m,n,i; 155 156 switch (message){ 157 case WM_TIMER: 158 A:MyPaint(hdc); 159 break; 160 case WM_KEYDOWN://按下見消息 161 switch(wParam){ 162 case VK_ESCAPE: 163 PostQuitMessage(0); 164 break; 165 case VK_F1: 166 InitGame(); 167 break; 168 } 169 break; 170 case WM_LBUTTONDOWN: 171 if(!over) 172 if(turn) 173 { 174 x=LOWORD(lParam); 175 y=HIWORD(lParam); 176 177 if(x>10 && x<460 && y>10 && y<460) 178 { 179 m=(int)floor((double)((x-10)/45)); 180 n=(int)floor((double)((y-10)/45)); 181 182 if(board[m][n]==2) 183 { 184 board[m][n]=0; 185 num[0]++; 186 187 if(num[0]==50 && num[1]==50) 188 { 189 winner=2; 190 over=true; 191 } 192 else for(i=0;i<192;i++) 193 { 194 if(ptab[m][n][i]) 195 { 196 win[0][i]++; 197 ctab[m][n][i]=false; 198 win[1][i]=7; 199 200 if(win[0][i]==5) 201 { 202 winner=0; 203 over=true; 204 } 205 } 206 } 207 turn=false;//換由計算機(jī)下 208 } 209 } 210 } 211 break; 212 case WM_PAINT: 213 if(begin==8){ 214 hdc = BeginPaint(hWnd, &ps); 215 goto A;// TODO: 在此添加任意繪圖代碼... 216 EndPaint(hWnd, &ps);} 217 break; 218 case WM_DESTROY: 219 DeleteDC(mdc); 220 DeleteDC(bufdc); 221 DeleteObject(cheers[0]); 222 DeleteObject(cheers[1]); 223 224 ReleaseDC(hWnd,hdc); 225 226 PostQuitMessage(0); 227 break; 228 default: 229 return DefWindowProc(hWnd, message, wParam, lParam); 230 } 231 return 0; 232 } 233 234 //初始化棋盤 235 //1、設(shè)定棋盤初始狀態(tài)及獲勝表內(nèi)容 236 //2、決定先下子的一方` 237 void InitGame(){ 238 int i,j,k; 239 int count=0; 240 241 over=false; 242 num[0]=num[1]=0; 243 244 245 //設(shè)定玩家與計算機(jī)在各個獲勝組合中的棋子數(shù) 246 for(i=0;i<192;i++){ 247 win[0][i]=0; 248 win[1][i]=0; 249 } 250 251 //初始化棋盤狀態(tài) 252 for(i=0;i<10;i++) 253 for(j=0;j<10;j++) 254 board[i][j]=2; 255 256 //設(shè)定水平方向的獲勝組合 257 for(i=0;i<10;i++){ 258 for(j=0;j<6;j++){ 259 for(k=0;k<5;k++){//5個棋子1個獲勝組合 260 261 ptab[i][j+k][count]=true; 262 ctab[i][j+k][count]=true; 263 } 264 count++; 265 } 266 } 267 268 //設(shè)定垂直方向的獲勝組合 269 for(i=0;i<10;i++){ 270 for(j=0;j<6;j++){ 271 for(k=0;k<5;k++){ 272 ptab[j+k][i][count]=true; 273 ctab[j+k][i][count]=true; 274 } 275 count++; 276 } 277 } 278 279 //設(shè)定正對角線方向上的獲勝組合 280 for(i=0;i<6;i++){ 281 for(j=0;j<6;j++){ 282 for(k=0;k<5;k++){ 283 ptab[j+k][i+k][count]=true; 284 ctab[j+k][i+k][count]=true; 285 } 286 count++; 287 } 288 } 289 290 //設(shè)定反對角線方向的獲勝組合 291 for(i=0;i<6;i++){ 292 for(j=9;j>=4;j--){ 293 for(k=0;k<5;k++){ 294 ptab[j-k][i+k][count]=true; 295 ctab[j-k][i+k][count]=true; 296 } 297 count++; 298 } 299 } 300 301 //隨機(jī)數(shù)決定由哪一方先下棋子 302 srand(GetTickCount()); 303 if(rand()%2==0) 304 turn=true; 305 else 306 turn=false; 307 } 308 309 //計算機(jī)下棋函數(shù) 310 //1、計算獲勝分?jǐn)?shù) 311 //2、選擇最佳位置進(jìn)行下棋 312 void ComTurn(){ 313 int grades[2][10][10]; 314 int m,n,i,max=0; 315 int u,v; 316 317 for(m=0;m<10;m++){ 318 for(n=0;n<10;n++){ 319 grades[0][m][n]=0; 320 grades[1][m][n]=0; 321 322 if(board[m][n]==2){ 323 for(i=0;i<192;i++){ 324 //計算玩家在空棋格上的獲勝分?jǐn)?shù) 325 if(ptab[m][n][i] && win[0][i]!=7){ 326 switch(win[0][i]){ 327 case 0: 328 grades[0][m][n]+=1; 329 break; 330 case 1: 331 grades[0][m][n]+=200; 332 break; 333 case 2: 334 grades[0][m][n]+=400; 335 break; 336 case 3: 337 grades[0][m][n]+=2000; 338 break; 339 case 4: 340 grades[0][m][n]+=10000; 341 break; 342 } 343 } 344 345 //計算計算機(jī)在空格上的獲勝分?jǐn)?shù) 346 if(ctab[m][n][i] && win[1][i]!=7){ 347 switch(win[1][i]){ 348 case 0: 349 grades[1][m][n]+=1; 350 break; 351 case 1: 352 grades[1][m][n]+=220; 353 break; 354 case 2: 355 grades[1][m][n]+=420; 356 break; 357 case 3: 358 grades[1][m][n]+=2100; 359 break; 360 case 4: 361 grades[1][m][n]+=20000; 362 break; 363 } 364 } 365 } 366 367 if(max==0){ 368 u=m; 369 v=n; 370 } 371 372 if(grades[0][m][n]>max){ 373 max=grades[0][m][n]; 374 u=m; 375 v=n; 376 }else if(grades[0][m][n]==max){ 377 if(grades[1][m][n]>grades[1][u][v]){ 378 u=m; 379 v=n; 380 } 381 } 382 383 if(grades[1][m][n]>max){ 384 max=grades[1][m][n]; 385 u=m; 386 v=n; 387 }else if(grades[1][m][n]==max){ 388 if(grades[0][m][n]>grades[0][u][v]){ 389 u=m; 390 v=n; 391 } 392 } 393 } 394 } 395 } 396 397 board[u][v]=1;//設(shè)定為計算機(jī)的棋子 398 num[1]++; 399 400 if(num[0]==50 && num[1]==50){ 401 winner=2; 402 over=true; 403 }else for(i=0;i<192;i++){ 404 if(ctab[u][v][i]){ 405 win[1][i]++; 406 ptab[u][v][i]=false; 407 win[0][i]=7; 408 409 if(win[1][i]==5){ 410 winner=1; 411 over=true; 412 } 413 } 414 } 415 turn=true; 416 } 417 418 //MyPaint() 419 void MyPaint(HDC hdc){ 420 int m,n; 421 char* str; 422 char* whitestr=" "; 423 424 if(over){ 425 switch(winner){ 426 case 0: 427 str="您贏了!按下[F1]鍵可重新進(jìn)行游戲.."; 428 break; 429 case 1: 430 str="計算機(jī)贏了!按下[F1]鍵可重新進(jìn)行游戲.."; 431 break; 432 case 2: 433 str="不分勝負(fù)!按下[F1]鍵可重新進(jìn)行游戲.."; 434 break; 435 } 436 TextOutA(hdc,10,470,whitestr,strlen(whitestr)); 437 TextOutA(hdc,10,470,str,strlen(str)); 438 } 439 440 else if(!turn){ //電腦下棋 441 TextOutA(hdc,10,470,whitestr,strlen(whitestr)); 442 str="計算機(jī)思考中..."; 443 TextOutA(hdc,10,470,str,strlen(str)); 444 ComTurn(); 445 }else{ 446 TextOutA(hdc,10,470,whitestr,strlen(whitestr)); 447 str="該您下了..."; 448 TextOutA(hdc,10,470,str,strlen(str)); 449 } 450 451 for(m=0;m<10;m++) 452 for(n=0;n<10;n++) 453 { 454 if(board[m][n]==0)//貼上玩家棋子 455 { 456 SelectObject(bufdc,cheers[0]); 457 BitBlt(mdc,m*45+3,n*45+3,38,38,bufdc,0,0,SRCCOPY); 458 } 459 else if(board[m][n]==1)//貼上計算機(jī)棋子 460 { 461 SelectObject(bufdc,cheers[1]); 462 BitBlt(mdc,m*45+3,n*45+3,38,38,bufdc,0,0,SRCCOPY); 463 } 464 else 465 { 466 SelectObject(bufdc,cheers[1]); 467 BitBlt(mdc,m*45+3,n*45+3,38,38,bufdc,0,0,WHITENESS); 468 } 469 } 470 471 BitBlt(hdc,10,10,450,450,mdc,0,0,SRCCOPY); 472 473 tPre=GetTickCount(); 474 }?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/zjutlitao/p/3735149.html
總結(jié)
以上是生活随笔為你收集整理的[游戏模版18] Win32 五子棋的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java基础学习网站收藏
- 下一篇: ExtJs之自定义事件