fuliangliang的Blog

合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。

用户操作
[即时聊天] [发私信] [加为好友]
fuliangID:fuliangliang
65469次访问,排名1598好友1人,关注者3
fuliangliang的文章
原创 100 篇
翻译 0 篇
转载 25 篇
评论 29 篇
fuliang的公告

我的联系方式:20542606

Email:fuliangliang@gmail.com


最近评论
topgunqq:条理清楚,简单易学.比网上其他例子要好一些.至少按照楼主写的过程,我这个初学者实验成功了!
marshluca:恭喜~~
请问有没rails 做的项目,比方blog?
marshluca@gmail.com
marshluca:恭喜~~
请问有没rails 做的项目,比方blog?
marshluca@gmail.com
chucai:写的非常的好,仔细的拜读了。思路很清晰。考虑的问题也比较全面。
tbsc3:我也遇到了这个问题,如果配1 M就有用,大于2M就还是默认的 不知道你有没有解决呀,教教我
文章分类
收藏
    相册
    净月潭一日游
    页面图片
    日历
    文章收藏
    我的JavaEye博客
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 今天用Windows API写的扫雷程序收藏

    新一篇: 重构了一下我的扫雷代码,代码清晰了许多 | 旧一篇: MFC下实现图形学之Hermite、Bezier曲线的绘制

    #include <windows.h>
    #include <math.h>
    #include <string.h>
    #include "resource.h"   // 菜单资源头文件
    #define SHADOW_WIDTH1 1 //阴影宽度
    #define SHADOW_WIDTH2 2
    #define SHADOW_WIDTH3 3
    #define BORDER 8    //边界的宽度
    #define BOX_WIDTH 20//box的宽度
    #define BOX_HEIGHT 20 //box的高度
    #define RESERVED_AREA 32 //保留区高度
    //******************************
    //自定义的函数声明
    //******************************
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
    void DrawBorder(HDC hdc,int x,int y,int width,int height,int BorderWidth,COLORREF &color1,COLORREF &color2,bool WTop);
    void AutoOpenBoxes(HDC &hdc,int i,int j);
    void drawRect(HDC &hdc,int x,int y);
    bool allRoundIsOpened(int row,int col);
    void InitBox();
    void UpdateTheWindow(HWND &hwnd,int rows,int cols,int mineNO);
    void ComputeRoundMineNo();
    void RandomSetMines();
    //**************************************
    //结构体Box,roundMineNO表示周围雷的个数
    //containMine表示是否里面是否有雷,
    //isOpened表示box是否已经打开
    //**************************************
    static HMENU hMenu;
    struct Box
    {
     int  roundMineNO;
     bool containMine;
     bool isOpened;
    };
    static int mineNumber;
    static int ROWS;     //行数
    static int COLS;     //列数
    static int iSM_BorderX;
    static int iSM_BorderY;
    static int iSM_CaptionY;
    static int iSM_MenuY;
    static Box **box;
    static int i,j,numberOpened;
    static RECT mineRect;
    //********
    //main函数
    //********
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
       PSTR szCmdLine, int iCmdShow)
    {
     static TCHAR szAppName[] = TEXT ("SineWave") ;
     HWND   hwnd ;
     MSG    msg ;
     WNDCLASS  wndclass ;

     mineNumber = 5;
        ROWS = 10; COLS = 10;
        mineNumber = 10;
     box = new Box* [COLS];
     for(int k=0;k<COLS;k++)
      box[k] = new Box[ROWS];

        iSM_BorderX = GetSystemMetrics(SM_CXBORDER);
     iSM_BorderY = GetSystemMetrics(SM_CYBORDER);
     iSM_CaptionY = GetSystemMetrics(SM_CYCAPTION);
     iSM_MenuY = GetSystemMetrics(SM_CYMENU);
        int cx = BOX_WIDTH * COLS + 2 * SHADOW_WIDTH3 + 2 * SHADOW_WIDTH2 + 2 * iSM_BorderX + 2 * BORDER;
     int cy = BOX_HEIGHT * ROWS + 2 * SHADOW_WIDTH3 + 4 * SHADOW_WIDTH2 + 2 * iSM_BorderY + 3 * BORDER + RESERVED_AREA+iSM_CaptionY+iSM_MenuY;
     mineRect.left = SHADOW_WIDTH3+BORDER+SHADOW_WIDTH2;
     mineRect.right =mineRect.left + BOX_WIDTH * COLS;
     mineRect.top = SHADOW_WIDTH3+2*BORDER+RESERVED_AREA+3*SHADOW_WIDTH2;
     mineRect.bottom = mineRect.top + BOX_HEIGHT * ROWS;
       
     wndclass.style  = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc= WndProc ;
     wndclass.cbClsExtra = 0 ;
     wndclass.cbWndExtra = 0 ;
     wndclass.hInstance = hInstance ;
     wndclass.hIcon  = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
     hMenu = LoadMenu (hInstance, MAKEINTRESOURCE (IDR_MENU1)) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;
             
     if (!RegisterClass (&wndclass))
     {
      MessageBox ( NULL, TEXT ("Program requires Windows NT!"),
       szAppName, MB_ICONERROR) ;
       return 0 ;
     }
       
     hwnd = CreateWindow ( szAppName, TEXT ("扫雷-游戏"),
         WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX,
        CW_USEDEFAULT, CW_USEDEFAULT,
        cx, cy,
        NULL, hMenu, hInstance, NULL) ;
     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;
        
     while (GetMessage (&msg, NULL, 0, 0))
         {
      TranslateMessage (&msg) ;
            DispatchMessage (&msg) ;
     }
      return msg.wParam ;
    }
    //*************
    //消息处理函数
    //*************
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
     HDC         hdc ;
     HBRUSH      hBrush ;
     PAINTSTRUCT ps ;
        static bool isLButtonDown=false;
     int xStart,yStart;
     static int m,n,cx,cy;
     static COLORREF color1=RGB(0, 0, 0),
      color2=RGB(255,255,255),
      color3=RGB(200,200,200),
      color4=RGB(120,120,200);
        static RECT grid,rect;
     static char szBuffer[2];
     POINT pt;
     switch (message)
     {
        case WM_CREATE: //初始化变量
               InitBox();
         RandomSetMines();
         ComputeRoundMineNo();
       return 0;
     case WM_PAINT:
       hdc = BeginPaint (hwnd, &ps) ;
             GetClientRect(hwnd,&rect);
             hBrush = CreateSolidBrush(RGB(200,200,200));
       SetBkColor(hdc,RGB(200,200,200));
       SelectObject(hdc,hBrush);
       SelectObject(hdc,GetStockObject(NULL_PEN));
       Rectangle(hdc,0,0,rect.right,rect.bottom);
       //绘制外边界
       DrawBorder(hdc,0,0,rect.right,rect.bottom,SHADOW_WIDTH3,color1,color2,true);
       //绘制保留区
       DrawBorder(hdc, SHADOW_WIDTH3+BORDER, SHADOW_WIDTH3+BORDER,
        BOX_WIDTH * COLS + 2 * SHADOW_WIDTH2, RESERVED_AREA + 2 * SHADOW_WIDTH2, SHADOW_WIDTH2, color1,color2,false);
       //绘制内边界
       DrawBorder(hdc, SHADOW_WIDTH3+BORDER, SHADOW_WIDTH3+2*BORDER+RESERVED_AREA+2*SHADOW_WIDTH2,
        BOX_WIDTH * COLS + 2 * SHADOW_WIDTH2, BOX_HEIGHT*ROWS + 2*SHADOW_WIDTH2, SHADOW_WIDTH2, color1,color2,false);
       //绘制雷区的box
       xStart = mineRect.left;
       yStart = mineRect.top;
             RECT rect0;
       for(i = 0; i < ROWS; i++)
       {
        for(j = 0; j < COLS; j++)
        {
          if(!box[i][j].isOpened)
         DrawBorder(hdc,xStart,yStart,BOX_WIDTH-2,BOX_HEIGHT-2,SHADOW_WIDTH2,
          color1,color2,true);
          else
          {
         DrawBorder(hdc,xStart,yStart,BOX_WIDTH-2,BOX_HEIGHT-2,SHADOW_WIDTH2,
          color3,color3,true);
         DrawBorder(hdc,xStart,yStart,BOX_WIDTH,BOX_HEIGHT,SHADOW_WIDTH1,
          color4,color4,true);
                    if(box[i][j].roundMineNO != 0)
        {
          rect0.left = mineRect.left + BOX_WIDTH * j;
                rect0.right = rect0.left + BOX_WIDTH;
                rect0.top = mineRect.top + BOX_HEIGHT * i;
                rect0.bottom = rect0.top + BOX_HEIGHT;
                wsprintf(szBuffer,TEXT("%d"),box[i][j].roundMineNO);
        //输出周围雷的个数
                DrawText(hdc,szBuffer,-1,&rect0,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
        }
          }
         xStart += BOX_WIDTH;
        }
        yStart += BOX_HEIGHT;
        xStart = SHADOW_WIDTH3+BORDER+SHADOW_WIDTH2;
       }
       EndPaint(hwnd,&ps);
       return 0 ;
        case WM_LBUTTONDOWN:
       isLButtonDown = true;
             pt.x = LOWORD(lParam);
       pt.y = HIWORD(lParam);
       grid.left = mineRect.left;
       grid.right = mineRect.right;
       grid.top = mineRect.top;
       grid.bottom = mineRect.bottom;
       if(PtInRect(&grid,pt))
       {
        j = (pt.x - grid.left) / BOX_WIDTH;
        i = (pt.y - grid.top) / BOX_HEIGHT;
                 grid.left += BOX_WIDTH * j;
        grid.top += BOX_HEIGHT * i;
        grid.right =  grid.left + BOX_WIDTH;
        grid.bottom = grid.top + BOX_HEIGHT;
        hdc = GetDC(hwnd);
                 DrawBorder(hdc,grid.left,grid.top,BOX_WIDTH-2,BOX_HEIGHT-2,SHADOW_WIDTH2,color3,color3,false);
           DrawBorder(hdc,grid.left,grid.top,BOX_WIDTH,BOX_HEIGHT,SHADOW_WIDTH1,color4,color4,false);
       }
       DeleteDC(hdc);
      return 0;
     case WM_LBUTTONUP:
       static HPEN hPen;
       static RECT rect1;
       hdc = GetDC(hwnd);
       hPen = CreatePen(PS_SOLID,2,RGB(255,255,0));
       SelectObject(hdc,hPen);
       SetBkColor(hdc,RGB(200,200,200));
       isLButtonDown = false;
             rect1.left = mineRect.left + BOX_WIDTH * j;
       rect1.right = rect1.left + BOX_WIDTH;
       rect1.top = mineRect.top + BOX_HEIGHT * i;
       rect1.bottom = rect1.top + BOX_HEIGHT;
      if(!box[i][j].isOpened)
      {
        if(!box[i][j].containMine)
        {
         if(box[i][j].roundMineNO != 0)
         {
           wsprintf(szBuffer,TEXT("%d"),box[i][j].roundMineNO);
        //输出周围雷的个数
           DrawText(hdc,szBuffer,-1,&rect1,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
         }

         box[i][j].isOpened = true;
         numberOpened ++;
         if(numberOpened == ROWS * COLS - mineNumber)
         {
                MessageBox (hwnd, TEXT ("祝贺你赢了!"),TEXT("扫雷游戏"), MB_ICONWARNING) ; 
         }

         AutoOpenBoxes(hdc,i,j);
        }
        else
        {
          for(int k=0;k<ROWS;k++)
           for(int l=0;l<COLS;l++)
        {  
         if(box[k][l].containMine)//点到雷后,使所有的类显现
         {
              rect.left =mineRect.left + BOX_WIDTH * l;
                 rect.top = mineRect.top + BOX_HEIGHT * k;
                 rect.right =  rect.left + BOX_WIDTH;
                 rect.bottom = rect.top + BOX_HEIGHT;
           DrawBorder(hdc,rect.left,rect.top,BOX_WIDTH-2,BOX_HEIGHT-2,SHADOW_WIDTH2,color3,color3,false);
                    DrawBorder(hdc,rect.left,rect.top,BOX_WIDTH,BOX_HEIGHT,SHADOW_WIDTH1,color4,color4,false);
                          DrawText(hdc,"?",-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
         }
        }
       MessageBox (hwnd, TEXT ("游戏结束"),TEXT("扫雷游戏"), MB_ICONWARNING) ; 
        }
       }
       DeleteDC(hdc);
      return 0;
     case WM_MOUSEMOVE:
      if(isLButtonDown)
      {
              pt.x = LOWORD(lParam);
        pt.y = HIWORD(lParam);
        rect.left = mineRect.left;
        rect.right = mineRect.right;
        rect.top = mineRect.top;
        rect.bottom = mineRect.bottom;

       if(PtInRect(&rect,pt))//判断是否在雷区
       {  
        m = i; n = j;
        j = (pt.x - rect.left) / BOX_WIDTH;
        i = (pt.y - rect.top) / BOX_HEIGHT;
                 rect.left += BOX_WIDTH * j;
        rect.top += BOX_HEIGHT * i;
        rect.right =  rect.left + BOX_WIDTH;
        rect.bottom = rect.top + BOX_HEIGHT;
        if(grid.left == rect.left && grid.right==rect.right
         &&grid.bottom == rect.bottom && grid.top == rect.top)
         return 0;
        hdc = GetDC(hwnd);
        if(!box[m][n].isOpened)//鼠标移走后,恢复未按下
        {
         DrawBorder(hdc,grid.left,grid.top,BOX_WIDTH-2,BOX_HEIGHT-2,SHADOW_WIDTH2,color1,color2,true);
         DrawBorder(hdc,grid.left,grid.top,BOX_WIDTH,BOX_HEIGHT,SHADOW_WIDTH1,color3,color3,true);
        }
        //使当前的box成为按下状态
         grid.left = rect.left; 
         grid.right = rect.right;
         grid.bottom = rect.bottom;
         grid.top = rect.top;
         DrawBorder(hdc,grid.left,grid.top,BOX_WIDTH-2,BOX_HEIGHT-2,SHADOW_WIDTH2,color3,color3,true);
            DrawBorder(hdc,grid.left,grid.top,BOX_WIDTH,BOX_HEIGHT,SHADOW_WIDTH1,color4,color4,true);
        }
        DeleteDC(hdc);
       }
      return 0;
      case WM_COMMAND: //响应菜单消息
               switch (LOWORD (wParam))
               {
         case IDM_PLAY:
                    InitBox();
           RandomSetMines();
        ComputeRoundMineNo();
           InvalidateRect(hwnd,NULL,TRUE);
        UpdateWindow(hwnd);
        return 0;
         case IDM_BEGINER:
         UpdateTheWindow(hwnd,10,10,5);
         return 0;       
                  case IDM_MEDIUM:
          UpdateTheWindow(hwnd,15,15,15);
          return 0;
                  case IDM_SENIOR:
          UpdateTheWindow(hwnd,20,20,30);
          return 0;
         case IDM_EXIT:
          SendMessage (hwnd, WM_CLOSE, 0, 0) ;
          return 0;
       }
       case  WM_DESTROY:
      PostQuitMessage (0) ;
      return 0 ;
       }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
    }
    //绘制边界
    void DrawBorder(HDC hdc,int x,int y,int width,int height,int BorderWidth,COLORREF &color1,COLORREF &color2,bool WTop)
    {
        int i;
     HPEN  hpen1,hpen2;
     hpen1=CreatePen(PS_SOLID, 1, color1);
     hpen2=CreatePen(PS_SOLID, 1, color2);
     if(WTop)
           SelectObject(hdc,hpen2);
     else
        SelectObject(hdc,hpen1);
     for(i = 0; i < BorderWidth; i++)
     {
      MoveToEx(hdc,x+i,y+i,NULL);
      LineTo(hdc,x+width-i,y+i);
      MoveToEx(hdc,x+i,y+i,NULL);
         LineTo(hdc,x+i,y+height-i);
     }
     if(WTop)
            SelectObject(hdc,hpen1);
     else
         SelectObject(hdc,hpen2);
     for(i = 0; i < BorderWidth; i++)
     {
      MoveToEx(hdc,x+width-i,y+height-i,NULL);
      LineTo(hdc,x+width-i,y+i);
      MoveToEx(hdc,x+width-i,y+height-i,NULL);
         LineTo(hdc,x+i,y+height-i);
     }
    }
    //初始化box
    void InitBox()
    {
     numberOpened = 0;
     for(i=0;i<ROWS;i++)
     for(j=0;j<COLS;j++)
     {
      box[i][j].containMine = false;
      box[i][j].isOpened = false;
      box[i][j].roundMineNO = 0;
     }
    }
    //计算周围类的个数
    void ComputeRoundMineNo()
    {
     for(i=0;i<ROWS;i++)
      for(j=0;j<COLS;j++)
      {
       if(i>0&&box[i-1][j].containMine==true)
       {
         box[i][j].roundMineNO++;
       }
       if(i>0&&j<COLS-1&&box[i-1][j+1].containMine == true)
       {
         box[i][j].roundMineNO++;
       }
       if(j<COLS-1&&box[i][j+1].containMine == true)
       {
        box[i][j].roundMineNO++;
       }
         if(i<ROWS-1 && j<COLS && box[i+1][j+1].containMine == true)
       {
        box[i][j].roundMineNO++;
       }
       if(i<ROWS-1 && box[i+1][j].containMine == true)
                {
         box[i][j].roundMineNO++;
       }
       if(i<ROWS-1 && j>0  && box[i+1][j-1].containMine == true)
       {
        box[i][j].roundMineNO++;
        }
       if(j>0 && box[i][j-1].containMine == true)
       {
        box[i][j].roundMineNO++;
       }
       if(i>0 && j>0 && box[i-1][j-1].containMine == true)
       {
         box[i][j].roundMineNO++;
       }
      }
    }
    //随机布雷
    void RandomSetMines()
    {
       int row,col;
       srand((UINT)GetCurrentTime());
       for(i=0;i<mineNumber;)
     { 
       row=rand()%ROWS;
       col=rand()%COLS;
       if(box[row][col].containMine != true)
       {
                   box[row][col].containMine = true;
          i++;
       }
       }
    }
    //自动打开box
    void AutoOpenBoxes(HDC &hdc,int x,int y)
    {
     if(x >= 0 && y >= 0 && x < ROWS && y < COLS &&
      box[x][y].roundMineNO == 0&& !allRoundIsOpened(x,y))
     {
        drawRect(hdc,x-1,y);
        drawRect(hdc,x-1,y+1);
        drawRect(hdc,x,y+1);
        drawRect(hdc,x+1,y+1);
           drawRect(hdc,x+1,y);
        drawRect(hdc,x+1,y-1);
        drawRect(hdc,x,y-1);
        drawRect(hdc,x-1,y-1);
        AutoOpenBoxes(hdc,x-1,y);
         AutoOpenBoxes(hdc,x-1,y+1);
        AutoOpenBoxes(hdc,x,y+1);
           AutoOpenBoxes(hdc,x+1,y+1);
           AutoOpenBoxes(hdc,x+1,y);
        AutoOpenBoxes(hdc,x+1,y-1);
        AutoOpenBoxes(hdc,x,y-1);
        AutoOpenBoxes(hdc,x-1,y-1);
     }
    }
    //绘制矩形
    void UpdateTheWindow(HWND &hwnd,int rows,int cols,int mineNO)
    {
      ROWS = rows;
      COLS = cols;
      mineNumber = mineNO;
      mineRect.left = SHADOW_WIDTH3+BORDER+SHADOW_WIDTH2;
      mineRect.right =mineRect.left + BOX_WIDTH * COLS;
      mineRect.top = SHADOW_WIDTH3+2*BORDER+RESERVED_AREA+3*SHADOW_WIDTH2;
      mineRect.bottom = mineRect.top + BOX_HEIGHT * ROWS;
      box = new Box* [COLS];
      for(int k=0;k< COLS;k++)
        box[k] = new Box[ROWS];
      InitBox();
      RandomSetMines();
      ComputeRoundMineNo();
      int cx = BOX_WIDTH * COLS + 2 * SHADOW_WIDTH3 +
     2 * SHADOW_WIDTH2 + 2 * iSM_BorderX + 2 * BORDER;
      int cy = BOX_HEIGHT * ROWS + 2 * SHADOW_WIDTH3 +
     4 * SHADOW_WIDTH2 + 2 * iSM_BorderY + 3 * BORDER + RESERVED_AREA+iSM_CaptionY+iSM_MenuY;
     MoveWindow(hwnd,0,0,cx,cy,true);
    }

    void drawRect(HDC &hdc,int x,int y)
    {
     RECT rect1;
     COLORREF color1 = RGB(200,200,200),
      color2 = RGB(120,120,200);
     TCHAR szBuffer[2]={"0"};
     if(x<0 || y<0 || x >= ROWS || y >= COLS)
     return;
     rect1.left = mineRect.left + BOX_WIDTH * y;
        rect1.right = rect1.left + BOX_WIDTH;
        rect1.top = mineRect.top + BOX_HEIGHT * x;
        rect1.bottom = rect1.top + BOX_HEIGHT;

       if(!box[x][y].isOpened)
       {
      DrawBorder(hdc,rect1.left,rect1.top,
         BOX_WIDTH-2,BOX_HEIGHT-2,SHADOW_WIDTH2,color1,color1,true);
      DrawBorder(hdc,rect1.left,rect1.top,
      BOX_WIDTH,BOX_HEIGHT,SHADOW_WIDTH1,color2,color2,true);

      if(!box[x][y].containMine && box[x][y].roundMineNO != 0)
        {
         wsprintf(szBuffer,TEXT("%d"),box[x][y].roundMineNO);
         DrawText(hdc,szBuffer,-1,&rect1,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
        }

       box[x][y].isOpened = true;
      numberOpened ++;
         if(numberOpened == ROWS * COLS - mineNumber )
         {
           MessageBox (NULL, TEXT ("祝贺你赢了!"),TEXT("扫雷游戏"), MB_ICONWARNING) ; 
         }
      }
    }
    //判断周围的所有box是否已经open
    bool allRoundIsOpened(int x,int y)
    {
      bool flag = true;
      if(x > 0 && !box[x-1][y].isOpened)
       flag = false;
      if(x > 0 && y < COLS-1 && !box[x-1][y+1].isOpened)
       flag = false;
      if(y < COLS-1 && !box[x][y+1].isOpened)
       flag = false;
      if(x < ROWS-1 && y< COLS-1 && !box[x+1][y+1].isOpened)
       flag = false;
      if(x < ROWS-1 && !box[x+1][y].isOpened)
       flag = false;
      if(x < ROWS-1 && y > 0 && !box[x+1][y-1].isOpened)
          flag = false;
      if(y > 0 && !box[x][y-1].isOpened)
          flag = false;
      if(x > 0 && y > 0 && !box[x-1][y-1].isOpened)
          flag = false;
      return flag;
    }

    发表于 @ 2005年11月19日 18:06:00|评论(loading...)|编辑

    新一篇: 重构了一下我的扫雷代码,代码清晰了许多 | 旧一篇: MFC下实现图形学之Hermite、Bezier曲线的绘制

    评论:没有评论。

    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © fuliang