zoukankan      html  css  js  c++  java
  • [游戏模版18] Win32 五子棋

    >_<:Learning its AI logic.

    >_<:resource

    >_<:code:

      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 }
  • 相关阅读:
    解决:std::ostream operator<< should have been declared inside 'xxx'
    c++ friend 遇到 namespace 无法访问 private 成员的问题
    Compiler Error C2872: ambiguous symbol
    【持续更新】总结:C++开发时积累的一些零碎的东西
    陷阱:C++模块之间的”直接依赖“和”间接依赖“与Makefile的撰写
    ZThread::ThreadLocal:ERROR C4716 must return a value的解决
    java值传递
    iframe与父页面传值
    iframe父子兄弟之间调用传值(contentWindow && parent)
    MySQL返回影响行数的测试示例
  • 原文地址:https://www.cnblogs.com/zjutlitao/p/3735149.html
Copyright © 2011-2022 走看看