[游戏模版18] Win32 五子棋

 

>_<:Learning its AI logic.

>_<:resource

>_<:code:

[游戏模版18] Win32 五子棋

  1 #include <windows.h>

  2 // C 运行时头文件

  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;                                // 当前实例

 15 TCHAR szTitle[MAX_LOADSTRING];                    // 标题栏文本

 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分标表示玩家棋子、电脑棋子、空

 22 bool ptab[10][10][192];    //玩家获胜表

 23 bool ctab[10][10][192];    //电脑获胜表

 24 int win[2][192];

 25 int num[2];                //分别计算玩家和计算机下棋个数

 26 bool turn,over;//turn 用来指示是有哪一方下棋,true玩家;false电脑;;over 指示棋局是否结束,ture结束

 27 int begin;

 28 int winner;    //指示当前棋局谁赢0表示玩家赢;1表示电脑赢;2表示平局

 29 

 30 // 此代码模块中包含的函数的前向声明:

 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();//计算机下棋时计算分数决定下棋位置

 38 

 39 int APIENTRY _tWinMain(HINSTANCE hInstance,

 40                      HINSTANCE hPrevInstance,

 41                      LPTSTR    lpCmdLine,

 42                      int       nCmdShow){

 43 

 44     MSG msg;

 45     MyRegisterClass(hInstance);

 46     // 执行应用程序初始化:

 47     if (!InitInstance (hInstance, nCmdShow)){

 48         return FALSE;

 49     }

 50     // 主消息循环:

 51     while (GetMessage(&msg, NULL, 0, 0)){

 52         TranslateMessage(&msg);

 53         DispatchMessage(&msg);

 54     }

 55     return (int) msg.wParam;

 56 }

 57 

 58 //  函数: 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 //   函数: InitInstance(HINSTANCE, int)

 83 //

 84 //   目的: 保存实例句柄并创建主窗口

 85 //

 86 //   注释:

 87 //

 88 //        在此函数中,我们在全局变量中保存实例句柄并

 89 //        创建和显示主程序窗口。

 90 //        棋盘拼接以及调用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; // 将实例句柄存储在全局变量中

 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++)//产生棋盘

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 //  函数: WndProc(HWND, UINT, WPARAM, LPARAM)

144 //

145 //  目的: 处理主窗口的消息。

146 //

147 //  WM_COMMAND    - 处理应用程序菜单

148 //  WM_PAINT    - 绘制主窗口

149 //  WM_DESTROY    - 发送退出消息并返回

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;//换由计算机下

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、设定棋盘初始状态及获胜表内容

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     //设定玩家与计算机在各个获胜组合中的棋子数

246     for(i=0;i<192;i++){

247         win[0][i]=0;

248         win[1][i]=0;

249     }

250 

251     //初始化棋盘状态

252     for(i=0;i<10;i++)

253         for(j=0;j<10;j++)

254             board[i][j]=2;

255 

256     //设定水平方向的获胜组合

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     //设定垂直方向的获胜组合

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     //设定正对角线方向上的获胜组合

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     //设定反对角线方向的获胜组合

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     //随机数决定由哪一方先下棋子

302     srand(GetTickCount());

303     if(rand()%2==0)

304         turn=true;

305     else

306         turn=false;

307 }

308 

309 //计算机下棋函数

310 //1、计算获胜分数

311 //2、选择最佳位置进行下棋

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                     //计算玩家在空棋格上的获胜分数

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                     //计算计算机在空格上的获胜分数

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;//设定为计算机的棋子

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]键可重新进行游戏..";

428             break;

429         case 1:

430             str="计算机赢了!按下[F1]键可重新进行游戏..";

431             break;

432         case 2:

433             str="不分胜负!按下[F1]键可重新进行游戏..";

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="计算机思考中...";

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)//贴上计算机棋子

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 }

 

 

 

你可能感兴趣的:(Win32)