• 五子棋


    // chess.cpp : 定义应用程序的入口点。
    //

    #include "stdafx.h"
    #include "chess.h"
    #include "math.h"

    #define MAX_LOADSTRING 100

    // 全局变量:
    HINSTANCE hInst;        // 当前实例
    TCHAR szTitle[MAX_LOADSTRING];     // 标题栏文本
    TCHAR szWindowClass[MAX_LOADSTRING];   // 主窗口类名

    HBITMAP chess[2];
    HDC   hdc,mdc,bufdc;
    HWND  hWnd;
    DWORD tPre,tNow;
    int  board[10][10];
    bool ptab[10][10][192];
    bool ctab[10][10][192];
    int  win[2][192];
    int  num[2];
    bool turn,over;
    int  winner;

    // 此代码模块中包含的函数的前向声明:
    ATOM    MyRegisterClass(HINSTANCE hInstance);
    BOOL    InitInstance(HINSTANCE, int);
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);

    void MyPaint(HDC hdc);
    void InitGame();
    void ComTurn();

    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
     UNREFERENCED_PARAMETER(hPrevInstance);
     UNREFERENCED_PARAMETER(lpCmdLine);

      // TODO: 在此放置代码。
     MSG msg;
     HACCEL hAccelTable;

     // 初始化全局字符串
     LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
     LoadString(hInstance, IDC_CHESS, szWindowClass, MAX_LOADSTRING);
     MyRegisterClass(hInstance);

     // 执行应用程序初始化:
     if (!InitInstance (hInstance, nCmdShow))
     {
      return FALSE;
     }

     hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CHESS));

     // 主消息循环:
    /* while (GetMessage(&msg, NULL, 0, 0))
     {
      if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
      {
       TranslateMessage(&msg);
       DispatchMessage(&msg);
      }
     }*/
     while(TRUE)
     {
      if (GetMessage(&msg,NULL,0,0))
      {
       if (msg.message!=WM_QUIT)
       {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        MyPaint(hdc);
       }
      }
      else
       break;
     }

     return (int) msg.wParam;
    }

    //
    //  函数: MyRegisterClass()
    //
    //  目的: 注册窗口类。
    //
    //  注释:
    //
    //    仅当希望
    //    此代码与添加到 Windows 95 中的“RegisterClassEx”
    //    函数之前的 Win32 系统兼容时,才需要此函数及其用法。调用此函数十分重要,
    //    这样应用程序就可以获得关联的
    //    “格式正确的”小图标。
    //
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
     WNDCLASSEX wcex;

     wcex.cbSize = sizeof(WNDCLASSEX);

     wcex.style   = CS_HREDRAW | CS_VREDRAW;
     wcex.lpfnWndProc = WndProc;
     wcex.cbClsExtra  = 0;
     wcex.cbWndExtra  = 0;
     wcex.hInstance  = hInstance;
     wcex.hIcon   = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CHESS));
     wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);
     wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
     wcex.lpszMenuName = MAKEINTRESOURCE(IDC_CHESS);
     wcex.lpszClassName = szWindowClass;
     wcex.hIconSm  = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

     return RegisterClassEx(&wcex);
    }

    //
    //   函数: InitInstance(HINSTANCE, int)
    //
    //   目的: 保存实例句柄并创建主窗口
    //
    //   注释:
    //
    //        在此函数中,我们在全局变量中保存实例句柄并
    //        创建和显示主程序窗口。
    //
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
       HWND hWnd;
       HBITMAP tile,bmp;
       int rowNum,colNum;
       int i,x,y;

       hInst = hInstance; // 将实例句柄存储在全局变量中

       hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

       if (!hWnd)
       {
          return FALSE;
       }

       ShowWindow(hWnd, nCmdShow);
       MoveWindow(hWnd,0,0,600,600,TRUE);
       UpdateWindow(hWnd);

       hdc=GetDC(hWnd);
       mdc=CreateCompatibleDC(hdc);
       bufdc=CreateCompatibleDC(hdc);

       bmp=CreateCompatibleBitmap(hdc,450,450);
       SelectObject(mdc,bmp);

       tile=(HBITMAP)LoadImage(NULL,"tile.bmp",IMAGE_BITMAP,45,45,LR_LOADFROMFILE);
       chess[0]=(HBITMAP)LoadImage(NULL,"chess0.bmp",IMAGE_BITMAP,38,38,LR_LOADFROMFILE);
       chess[1]=(HBITMAP)LoadImage(NULL,"chess1.bmp",IMAGE_BITMAP,38,38,LR_LOADFROMFILE);
      
       for (i=0;i<100;i++)
       {
        rowNum=i/10;
        colNum=i%10;
        x=colNum*45;
        y=rowNum*45;
        SelectObject(bufdc,tile);
        BitBlt(mdc,x,y,45,45,bufdc,0,0,SRCCOPY);
       }
       //BitBlt(hdc,0,0,640,480,mdc,0,0,SRCCOPY);

       InitGame();
       MyPaint(hdc);
       return TRUE;
    }

    //
    //  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
    //
    //  目的: 处理主窗口的消息。
    //
    //  WM_COMMAND - 处理应用程序菜单
    //  WM_PAINT - 绘制主窗口
    //  WM_DESTROY - 发送退出消息并返回
    //
    //
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
     int wmId, wmEvent;
     PAINTSTRUCT ps;
     HDC hdc;
     int x,y,m,n,i;

     switch (message)
     {
     case WM_COMMAND:
      wmId    = LOWORD(wParam);
      wmEvent = HIWORD(wParam);
      // 分析菜单选择:
      switch (wmId)
      {
      case IDM_ABOUT:
       DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
       break;
      case IDM_EXIT:
       DestroyWindow(hWnd);
       break;
      default:
       return DefWindowProc(hWnd, message, wParam, lParam);
      }
      break;
     case WM_PAINT:
      hdc = BeginPaint(hWnd, &ps);
      // TODO: 在此添加任意绘图代码...
      EndPaint(hWnd, &ps);
      break;
     case WM_KEYDOWN:
      switch(wParam)
      {
      case VK_ESCAPE:
       PostQuitMessage(0);
       break;
      case VK_F1:
       InitGame();
       break;
      }
     case WM_LBUTTONDOWN:
      if(!over)
       if (turn)
       {
        x=LOWORD(lParam);
        y=HIWORD(lParam);
        if (x>10&&x<460&&y>10&&y<460)
        {
         m=(int)floor((double)((x-10)/45));
         n=(int)floor((double)((y-10)/45));

         if (board[m][n]==2)
         {
          board[m][n]=0;
          num[0]++;
          if (num[0]==50&&num[1]==50)
          {
           winner=2;
           over=true;
          }
          else
           for (i=0;i<192;i++)
           {
            if (ptab[m][n][i])
            {
             win[0][i]++;
             ctab[m][n][i]=false;
             win[1][i]=7;
             if (win[0][i]==5)
             {
              winner=0;
              over=true;
             }
            }
            
           }
          turn=false;
         }
        }
       }
       break;
     case WM_DESTROY:
      DeleteDC(mdc);
      DeleteDC(bufdc);
      DeleteObject(chess[0]);
      DeleteObject(chess[1]);
      PostQuitMessage(0);
      break;
     default:
      return DefWindowProc(hWnd, message, wParam, lParam);
     }
     return 0;
    }

    // “关于”框的消息处理程序。
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
     UNREFERENCED_PARAMETER(lParam);
     switch (message)
     {
     case WM_INITDIALOG:
      return (INT_PTR)TRUE;

     case WM_COMMAND:
      if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
      {
       EndDialog(hDlg, LOWORD(wParam));
       return (INT_PTR)TRUE;
      }
      break;
     }
     return (INT_PTR)FALSE;
    }

    void InitGame()
    {
     int i,j,k;
     int count=0;

     over=false;
     num[0]=num[1]=0;

     //设定玩家与计算机在各个获胜组合中的棋子数
     for (i=0;i<192;i++)
     {
      win[0][i]=0;
      win[1][i]=0;
     }
        //初始化棋盘状态
     for(i=0;i<10;i++)
      for(j=0;j<10;j++)
       board[i][j]=2;
     //设定水平方向的获胜组合
     for(i=0;i<10;i++)
      for (j=0;j<6;j++)
      {
       for(k=0;k<5;k++)
       {
        ptab[i][j+k][count]=TRUE;
        ctab[i][j+k][count]=TRUE;
       }
       count++;
      }
     //设定垂直方向的获胜组合
     for(i=0;i<10;i++)
      for (j=0;j<6;j++)
      {
       for(k=0;k<5;k++)
       {
        ptab[j+k][i][count]=TRUE;
        ctab[j+k][i][count]=TRUE;
       }
       count++;
      }
     //设定正对角线方向的获胜组合
     for(i=0;i<10;i++)
      for (j=0;j<6;j++)
      {
       for(k=0;k<5;k++)
       {
        ptab[j+k][i+k][count]=TRUE;
        ctab[j+k][i+k][count]=TRUE;
       }
       count++;
      }
     //设定反对角线方向的获胜组合
     for(i=0;i<6;i++)
      for (j=9;j>=4;j--)
      {
       for(k=0;k<5;k++)
       {
        ptab[j-k][i+k][count]=TRUE;
        ctab[j-k][i+k][count]=TRUE;
       }
       count++;
      }
     //随机数决定由哪一方先下棋子
     srand(GetTickCount());
     if(rand()%2==0)
      turn=true;
     else
      turn=false;
    }

    void ComTurn()
    {
     int grades[2][10][10];
     int m,n,i,max=0;
     int u,v;

     for (m=0;m<10;m++)
        for (n=0;n<10;n++)
        {
         grades[0][m][n]=0;
         grades[1][m][n]=0;

         if (board[m][n]==2)
         {
          for (i=0;i<192;i++)
          {
           //计算玩家在空格上的获胜分数
           if (ptab[m][n][i]&&win[0][i]!=7)
           {
            switch(win[0][i])
            {
            case 0:
             grades[0][m][n]+=1;
             break;
            case 1:
             grades[0][m][n]+=200;
             break;
            case 2:
             grades[0][m][n]+=400;
             break;
            case 3:
             grades[0][m][n]+=2000;
             break;
            case 4:
             grades[0][m][n]+=10000;
             break;
            }
           }
           //计算计算机在空棋格上的获胜分数
          if (ctab[m][n][i]&&win[1][i]!=7)
          {
           switch(win[1][i])
           {
           case 0:
            grades[1][m][n]+=1;
            break;
           case 1:
            grades[1][m][n]+=220;
            break;
           case 2:
            grades[1][m][n]+=420;
            break;
           case 3:
            grades[1][m][n]+=2100;
            break;
           case 4:
            grades[1][m][n]+=20000;
            break;
           }
          }
          }
          if (max==0)
          {
           u=m;
           v=n;
          }
          if (grades[0][m][n]>max)
          {
           max=grades[0][m][n];
           u=m;
           v=n;
          }
          else if (grades[0][m][n]==max)
          {
           if (grades[1][m][n]>grades[1][u][v])
           {
            u=m;
            v=n;
           }
          }
          if (grades[1][m][n]>max)
          {
           max=grades[1][m][n];
           u=m;
           v=n;
          }
          else if (grades[1][m][n]==max)
          {
           if (grades[0][m][n]>grades[0][u][v])
           {
            u=m;
            v=n;
           }
          }
         }
        }
        board[u][v]=1;//设定为计算机的棋子
        num[1]++;

        if (num[0]==50&&num[1]==50)
        {
         winner=2;
         over=true;
        }
        else
         for (i=0;i<192;i++)
         {
          if (ctab[u][v][i])
          {
           win[1][i]++;
           ptab[u][v][i]=false;
           win[0][i]=7;

           if (win[1][i]==5)
           {
            winner=1;
            over=true;
           }
          }
         }
      turn=true; //换由玩家下
    }

    void MyPaint(HDC hdc)
    {
     int m,n;
     char *str;

     if (over)
     {
      switch(winner)
      {
      case 0:
       str="您赢了!";
       break;
      case 1:
       str="计算机赢了!";
       break;
      case 2:
       str="不分胜负!";
       break;
      }
      TextOut(hdc,10,470,str,strlen(str));
     }
     else if (!turn)
     {
      str="计算机思考中...";
            TextOut(hdc,10,470,str,strlen(str));
      ComTurn();
     }
     else
     {
      str="该您下了...";
      TextOut(hdc,10,470,str,strlen(str));
     }
     for (m=0;m<10;m++)
      for (n=0;n<10;n++)
      {
       if (board[m][n]==0)
       {
        SelectObject(bufdc,chess[0]);
        BitBlt(mdc,m*45+3,n*45+3,38,38,bufdc,0,0,SRCCOPY);
       }
       else if (board[m][n]==1)
       {
        SelectObject(bufdc,chess[1]);
        BitBlt(mdc,m*45+3,n*45+3,38,38,bufdc,0,0,SRCCOPY);
       }
       else
       {
        SelectObject(bufdc,chess[1]);
        BitBlt(mdc,m*45+3,n*45+3,38,38,bufdc,0,0,WHITENESS);
       }
      }
      BitBlt(hdc,10,10,450,450,mdc,0,0,SRCCOPY);
      tPre=GetTickCount();
    }

  • 相关阅读:
    Document
    Document
    Document
    Document
    Document
    Document
    8. vue 的生命周期
    7. vue-cli 安装和使用脚手架
    5.组件(2) 之 父级传子级
    6.组件(3) 之 子级传父级
  • 原文地址:https://www.cnblogs.com/batman425/p/3268333.html
Copyright © 2020-2023  润新知