首页 > 其他 > 详细

扫雷程序的实现

时间:2014-03-23 08:55:25      阅读:497      评论:0      收藏:0      [点我收藏+]

用了一个星期,终于把扫雷做的差不多了,其中遇到很多很多问题,但慢慢解决了,确实挺令人高兴,也许这就是编程的魅力所在吧。

 

下面记录扫雷的主要几个算法:

一:布雷

bubuko.com,布布扣
 1 void CMineButton::Reset(CWnd* pParent)//参考与小张上传中的程序,,对butto进行初始化
 2 {
 3         
 4     CMINEMFCApp *app = (CMINEMFCApp *)AfxGetApp(); 
 5 
 6     app->m_pParent = pParent;
 7 
 8     int nI;
 9 
10     for(nI=0;nI<100;nI++)
11     {
12         if (app->m_aLandMine[nI]!=NULL)
13             delete app->m_aLandMine[nI];
14     }
15     for(nI=0;nI<100;nI++)
16     {
17     
18         app->m_aLandMine[nI] = new CMineButton;
19     
20     }
21 
22     
23     int nCurMines=0;
24     int nCurMine;
25     int curi = 0;
26     srand( (unsigned)time( NULL ));
27 
28     while(nCurMines<10)
29     {
30         nCurMine=rand()%(100);//获取10个雷的分布
31         (app->m_theRealMine[curi]) = nCurMine;
32         if(app->m_aLandMine[nCurMine]->GetMineNum() != -1)//该写法的作用是初始化10个雷周围button的雷的数量
33         {
34             app->m_aLandMine[nCurMine]->SetMineNum(-1);
35             int nMineRound,nMineRound1;
36             //right;
37             nMineRound = app->m_aLandMine[nCurMine]->GetRight(nCurMine);
38             if(nMineRound>=0)
39             {
40                 if (app->m_aLandMine[nMineRound]->GetMineNum() != -1)
41                     ++(*app->m_aLandMine[nMineRound]);
42                 //right top
43                 nMineRound1 = (app->m_aLandMine[nMineRound]->GetTop(nMineRound));
44                 if(nMineRound1>=0 && app->m_aLandMine[nMineRound1]->GetMineNum() != -1)
45                 {
46                     ++(*app->m_aLandMine[nMineRound1]);
47                 }
48                 //right bottom
49                 nMineRound1 = app->m_aLandMine[nMineRound]->GetBot(nMineRound);
50                 if(nMineRound1>=0 && app->m_aLandMine[nMineRound1]->GetMineNum() != -1)
51                 {
52                     ++(*app->m_aLandMine[nMineRound1]);
53                 }
54             }            
55             //left
56             nMineRound = app->m_aLandMine[nCurMine]->GetLeft(nCurMine);
57             if(nMineRound>=0)
58             {
59                 if(app->m_aLandMine[nMineRound]->GetMineNum() != -1)
60                     ++(*app->m_aLandMine[nMineRound]);
61         
62                 //Left top
63                 nMineRound1 = app->m_aLandMine[nMineRound]->GetTop(nMineRound);
64                 if(nMineRound1>=0 && app->m_aLandMine[nMineRound1]->GetMineNum() != -1)
65                 {
66                     ++(*app->m_aLandMine[nMineRound1]);
67                 }
68                 
69                 //Left bottom
70                 nMineRound1 =  app->m_aLandMine[nMineRound]->GetBot(nMineRound);
71                 if(nMineRound1>=0 && app->m_aLandMine[nMineRound1]->GetMineNum() !=分公司的72                 {
73                     ++(*app->m_aLandMine[nMineRound1]);
74                 }
75             }
76             //Top
77             nMineRound = app->m_aLandMine[nCurMine]->GetTop(nCurMine);
78             if(nMineRound>=0 && app->m_aLandMine[nMineRound]->GetMineNum() != -1)
79             {
80                 ++(*app->m_aLandMine[nMineRound]);
81             }
82 
83             //Bottom
84             nMineRound = app->m_aLandMine[nCurMine]->GetBot(nCurMine);
85             if(nMineRound>=0 && app->m_aLandMine[nMineRound]->GetMineNum() != -1)
86             {
87                 ++(*app->m_aLandMine[nMineRound]);
88             }
89             nCurMines++;
90             curi ++ ;
91         }
92     }
93 }
bubuko.com,布布扣

二:空白雷区的实现

 

 

bubuko.com,布布扣
BOOL CMINEMFCDlg::RecordMine(int nCurMine)//也是根据另一个程序打开空白的周围的算法,,是一个循环队列的使用
{

    CMINEMFCApp *app = (CMINEMFCApp *)AfxGetApp(); 

    int nRoundMine,nRoundMine1;
    int aMine[500];
    int nTop=0,nTail=0;
    
    aMine[nTop++] = nCurMine;
    
    while(nTop!=nTail)
    {
        int nCurrent=aMine[nTail];
         nTail = (nTail+1)%500;
        switch((app->m_aLandMine[nCurrent])->OpenMine(nCurrent))
        {
        case 0:        // Mine number is zero
            nRoundMine = (app->m_aLandMine[nCurrent])->GetLeft(nCurrent);
            if(nRoundMine!=-1)
            {
                aMine[nTop] = nRoundMine;
                nTop = (nTop+1)%500;
                nRoundMine1 = (app->m_aLandMine[nCurrent])->GetTop(nRoundMine);
                if(nRoundMine1!=-1)
                {
                    aMine[nTop] = nRoundMine1;
                    nTop = (nTop+1)%500;
                    nRoundMine1 = (app->m_aLandMine[nCurrent])->GetTop(nRoundMine);
                }
                nRoundMine1 = (app->m_aLandMine[nCurrent])->GetBot(nRoundMine);
                if(nRoundMine1!=-1)
                {
                    aMine[nTop] = nRoundMine1;
                    nTop = (nTop+1)%500;
                    nRoundMine1 = (app->m_aLandMine[nCurrent])->GetTop(nRoundMine);
                }
            }
            nRoundMine = (app->m_aLandMine[nCurrent])->GetRight(nCurrent);
            if(nRoundMine!=-1)
            {    
                aMine[nTop] = nRoundMine;
                nTop = (nTop+1)%500;
                nRoundMine1 = (app->m_aLandMine[nCurrent])->GetTop(nRoundMine);
                if(nRoundMine1!=-1)
                {
                    aMine[nTop] = nRoundMine1;
                    nTop = (nTop+1)%500;
                    nRoundMine1 = (app->m_aLandMine[nCurrent])->GetTop(nRoundMine);
                }
                nRoundMine1 = (app->m_aLandMine[nCurrent])->GetBot(nRoundMine);
                if(nRoundMine1!=-1)
                {
                    aMine[nTop] = nRoundMine1;
                    nTop = (nTop+1)%500;
                    nRoundMine1 = (app->m_aLandMine[nCurrent])->GetTop(nRoundMine);
                }
            }
            nRoundMine = (app->m_aLandMine[nCurrent])->GetTop(nCurrent);
            if(nRoundMine!=-1)
            {    
                aMine[nTop] = nRoundMine;
                nTop = (nTop+1)%500;
            }
            nRoundMine = (app->m_aLandMine[nCurrent])->GetBot(nCurrent);
            if(nRoundMine!=-1)
            {
                aMine[nTop] = nRoundMine;
                nTop = (nTop+1)%500;
            }
            break;
        case 1:
            break;
        case -1:
            return FALSE;        // fail
        }
    }
    return TRUE;
}
bubuko.com,布布扣

下面讲讲自己遇到的一些困难和新get的技能吧:

1,invalidate函数

 

Invalidate()之后:(MFC的,顺便了)
OnPaint()->OnPrepareDC()->OnDraw()
所以只是刷新在OnPaint()和OnDraw()函数中的绘图语句。其它地方没有影响。

Invalidate标记一个需要重绘的无效区域,并不意味着调用该函数后就立刻进行重绘。类似于PostMessage(WM_PAINT),需要处理到WM_PAINT消息时才真正重绘。以为您Invalidate之后还有其他的语句正在执行,程序没有机会去处理WM_PAINT消息,但当函数执行完毕后,消息处理才得以进行。

Invalidate只是放一个WM_PAINT消息在队列里,不做别的,所以只有当当前函数返回后,进入消息循环,取出WM_PAINT,才执行PAINT,所以不管Invalidate放哪里,都是最后的。

 

其实我遇到了就是把drawbutton放在了onpaint里面,导致其不断的刷新。。。。

 

invalidateRect是通过消息来调用OnPaint
RedrawWindow除了有InvalidateRect的效果,还会立即调用一次OnPaint(不经过消息队列,类似 UpdateWindow),这个redrawwindow会立即调用ONpaint。

2.

解决 unresolved external symbol 无法解析 _send@16

 

这个一般都是lib库没有设置好而导致的。。

 

 

3, 

VC6.0常见错误之::Debug Assertion Failed!

 

这个比较多,,发一个网址吧http://blog.csdn.net/xjkstar/article/details/6922259。

 

3

//声明:
SetWindowPos(
  hWnd: HWND;            {窗口句柄}
  hWndInsertAfter: HWND; {窗口的 Z 顺序}
  X, Y: Integer;         {位置}
  cx, cy: Integer;       {大小}
  uFlags: UINT           {选项}
): BOOL;

//hWndInsertAfter 参数可选值:
HWND_TOP       = 0;        {在前面}
HWND_BOTTOM    = 1;        {在后面}
HWND_TOPMOST   = HWND(-1); {在前面, 位于任何顶部窗口的前面}
HWND_NOTOPMOST = HWND(-2); {在前面, 位于其他顶部窗口的后面}

//uFlags 参数可选值:
SWP_NOSIZE         = 1;    {忽略 cx、cy, 保持大小}
SWP_NOMOVE         = 2;    {忽略 X、Y, 不改变位置}
SWP_NOZORDER       = 4;    {忽略 hWndInsertAfter, 保持 Z 顺序}
SWP_NOREDRAW       = 8;    {不重绘}
SWP_NOACTIVATE     = $10{不激活}
SWP_FRAMECHANGED   = $20{强制发送 WM_NCCALCSIZE 消息, 一般只是在改变大小时才发送此消息}
SWP_SHOWWINDOW     = $40{显示窗口}
SWP_HIDEWINDOW     = $80{隐藏窗口}
SWP_NOCOPYBITS     = $100; {丢弃客户区}
SWP_NOOWNERZORDER  = $200; {忽略 hWndInsertAfter, 不改变 Z 序列的所有者}
SWP_NOSENDCHANGING = $400; {不发出 WM_WINDOWPOSCHANGING 消息}
SWP_DRAWFRAME      = SWP_FRAMECHANGED; {画边框}
SWP_NOREPOSITION   = SWP_NOOWNERZORDER;{}
SWP_DEFERERASE     = $2000;            {防止产生 WM_SYNCPAINT 消息}
SWP_ASYNCWINDOWPOS = $4000;            {若调用进程不拥有窗口, 系统会向拥有窗口的线程发出需求}

//举例:
procedure TForm1.Button1Click(Sender: TObject);
begin
  SetWindowPos(Handle, HWND_TOPMOST, 0,0, 100,200, SWP_SHOWWINDOW);
end;

4,在鼠标右击响应函数中这样来写

bubuko.com,布布扣
BOOL CMINEMFCDlg::PreTranslateMessage(MSG* pMsg) //对于右击鼠标的响应
{
    // TODO: Add your specialized code here and/or call the base class
    CMINEMFCApp *app = (CMINEMFCApp *)AfxGetApp(); 

    CClientDC dc(this);
    CFont font;

 
     font.CreateFont(20, 15, 0, 0, FW_SEMIBOLD,
    FALSE, FALSE, FALSE, 0, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,   DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, _T("新宋体"));
     
     CFont *pOldFont=dc.SelectObject(&font);
 

    dc.SetBkColor(RGB(237,237,237));

     if(pMsg->message==WM_RBUTTONDOWN)//鼠标点击右键
     { 
          CRect rc;
          CPoint ptCursor;
          ::GetCursorPos(&ptCursor);//获取鼠标的位置信息
          int pos;
    
     
          for(pos=159;pos<259;pos++)
          {
                GetDlgItem(pos)-> GetWindowRect(&rc);//获取控件的位置信息
            
        
               if(PtInRect(&rc,ptCursor))//右键点击位置在某一个控件上
               {    
                   CMineButtonVisual* pMineButton = (CMineButtonVisual*)GetDlgItem(pos);
                
                 if(pMineButton->rButClickedFlags  == 0)
                {
                    SetDlgItemText(pos,"");
                    pMineButton->rButClickedFlags = (pMineButton->rButClickedFlags +1)%3;
                    m_recordRealMine[m_recordRealMineFlags] = pos;
                    m_recordRealMineFlags ++ ;
                    CString str;
                    str.Format("剩余雷数:%d",(10-m_recordRealMineFlags));
                    GetDlgItem(IDC_STATIC_MINENUM)->SetWindowText(str);
                    
                }    
                else if(pMineButton->rButClickedFlags  == 1)
                {
                    SetDlgItemText(pos,"?");
                    pMineButton->rButClickedFlags  =(pMineButton->rButClickedFlags +1)%3;
                    m_recordRealMineFlags -- ;
                    CString str;
                    str.Format("剩余雷数:%d",(10-m_recordRealMineFlags));
                    GetDlgItem(IDC_STATIC_MINENUM)->SetWindowText(str);
                }
                else
                {    
                    SetDlgItemText(pos," ");
                    pMineButton->rButClickedFlags  = (pMineButton->rButClickedFlags +1)%3;
                    
                }
                
                
                //m_minenum--;
                    //if(flg[pos-1000]==1)
                     //mine[0]--;
               }
              
               
          }
          
      if(m_recordRealMineFlags == 10)
               {
                   
                    int curflags = 0;       
                   for(int curj = 0;curj<m_recordRealMineFlags;curj++)
                       for(int curi = 0;curi<10;curi++)
                       {
                           if (m_recordRealMine[curi] == (app->m_theRealMine[curj]+159))
                           {
                               curflags ++ ;
                               break;
                           }
                       }
                     if(curflags == 10)
                     {
                         MessageBox("恭喜你!!!扫雷成功!!你碉堡了!!!");
                            bFail = 1;
                     }
        
               } 
        //  GetDlgItem(1100)-> GetWindowRect(&rc);//获取开始按钮的位置信息
         /*if(PtInRect(&rc,ptCursor))//右键点击位置在某一个控件上
          {
               for(int i=1;i<=mine[0];i++)
               {
                    SetDlgItemText(mine[i]+1000,"*");
               }
          }*/
     }

    return CDialog::PreTranslateMessage(pMsg);
}
bubuko.com,布布扣

5.ON_CONTROL_RANGE(BN_CLICKED, IDC_BUTTON1, IDC_BUTTON10, OnButtonClicked)的使用。

 

6.创建一个指针,,delete掉。

bubuko.com,布布扣
    for(int curi = 0; curi < 100 ;curi++)
    {
        if(m_btn[curi]->m_hWnd != 0)
        {
            delete m_btn[curi];
            
            m_btn[curi] = new CMineButtonVisual;
        }
    }
bubuko.com,布布扣

7.定时器的用法

 

settimer(1,1000,null)

ontimer()则响应。

killtimer则销毁settimer

 

最后附一张截图,,纪念一下自己写的第一个游戏。

bubuko.com,布布扣

扫雷程序的实现,布布扣,bubuko.com

扫雷程序的实现

原文:http://www.cnblogs.com/fuzhenzhen/p/3618342.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!