标题:帮忙用语言描述下这个程序的所有算法!!谢谢!~~
只看楼主
shi619781499
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2012-12-11
结帖率:50%
已结贴  问题点数:20 回复次数:1 
帮忙用语言描述下这个程序的所有算法!!谢谢!~~
// txz1Dlg.cpp : implementation file
//program by 镇关西 QQ 191635418

#include "stdafx.h"
#include "txz1.h"
#include "txz1Dlg.h"

#define __GOBAL__
#include "TxzMap.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
    CAboutDlg();

// Dialog Data
    //{{AFX_DATA(CAboutDlg)
    enum { IDD = IDD_ABOUTBOX };
    //}}AFX_DATA

    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CAboutDlg)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    //}}AFX_VIRTUAL

// Implementation
protected:
    //{{AFX_MSG(CAboutDlg)
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
    //{{AFX_DATA_INIT(CAboutDlg)
    //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CAboutDlg)
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    //{{AFX_MSG_MAP(CAboutDlg)
        // No message handlers
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTxz1Dlg dialog

CTxz1Dlg::CTxz1Dlg(CWnd* pParent /*=NULL*/)
    : CDialog(CTxz1Dlg::IDD, pParent)
{
    //{{AFX_DATA_INIT(CTxz1Dlg)
        // NOTE: the ClassWizard will add member initialization here
    //}}AFX_DATA_INIT
    // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    gameback = NULL;
}

void CTxz1Dlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CTxz1Dlg)
        // NOTE: the ClassWizard will add DDX and DDV calls here
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CTxz1Dlg, CDialog)
    //{{AFX_MSG_MAP(CTxz1Dlg)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_WM_DESTROY()
    ON_WM_LBUTTONDOWN()
    ON_WM_RBUTTONDOWN()
    ON_BN_CLICKED(IDC_BTN_OPEN, OnBtnOpen)
    ON_BN_CLICKED(IDC_BTN_BACK, OnBtnBack)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTxz1Dlg message handlers

BOOL CTxz1Dlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Add "About..." menu item to system menu.

    // IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        CString strAboutMenu;
        strAboutMenu.LoadString(IDS_ABOUTBOX);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);            // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon
   
    // TODO: Add extra initialization here
    {
        //GetDlgItem(IDC_BTN_OPEN)->EnableWindow(FALSE);
        //GetDlgItem(IDC_BTN_OPEN)->ShowWindow(FALSE);
        //HBITMAP hbmp = (HBITMAP)LoadImage(NULL, dlg.GetPathName(), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADFROMFILE);
        //HBITMAP hbmp = (HBITMAP)LoadImage(NULL, "txz.bmp", IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADFROMFILE);
        //HBITMAP hbmp = (HBITMAP)LoadImage(NULL, IDB_BITMAP3, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADFROMFILE);
#if 0
        if(hbmp == NULL)
        {
            AfxMessageBox(_T("加载位图错误!"));
            SendMessage(WM_CLOSE,0,0);
            return FALSE;
        }
#endif
        FreeObjects();
        
        //m_bmp.Attach(hbmp);
        m_bmp.LoadBitmap(IDB_BITMAP3);
        
        //BITMAP tmpBitmap;
        //m_bmp.GetBitmap(&tmpBitmap);            //获得图片的尺寸
        
        CDC *pDC = GetDC();                        //获得程序的DC环境
        m_dc.CreateCompatibleDC(pDC);            //创建相应的内存区域
        ReleaseDC(pDC);                            //释放环境
        
        m_pOldBmp = m_dc.SelectObject(&m_bmp);    //
        
#if 0
        SetWindowPos(   HWND   hWndInsertAfter,   int   x,   int   y,   int   cx,   int   cy,   UINT   nFlags   );   
        uFlags   =   SWP_DRAWFRAME   |SWP_FRAMECHANGED;   
        CenterWindow();
#endif        
        m_mapIndex=0;
        LoadMap(m_mapIndex);
        m_bFindWay=FALSE;
        gameback=new UINT[512];
        Invalidate(FALSE);            //会产生paint事件
    }        
    return TRUE;  // return TRUE  unless you set the focus to a control
}

void CTxz1Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else
    {
        CDialog::OnSysCommand(nID, lParam);
    }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CTxz1Dlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting

        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        if(m_dc.GetSafeHdc()==NULL)
        {
            CDialog::OnPaint();
        }
        else{
            CPaintDC dc(this);
            CRect rect;
            //用白色填充客户区
            //GetClientRect(&rect);    //和 this->GetClientRect(&rect);    效果一致
            //::FillRect(dc.GetSafeHdc(), rect, (HBRUSH)GetStockObject(LTGRAY_BRUSH));
            
            //获得图片大小
#if 0
            BITMAP bm;
            m_bmp.GetBitmap(&bm);   
            dc.StretchBlt(
                0, 0,
                bm.bmWidth, bm.bmHeight,
                &m_dc,
                0, 0,
                bm.bmWidth, bm.bmHeight,
                SRCCOPY);
#else
            DrawMap(&dc);
#endif
        }
    }
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CTxz1Dlg::OnQueryDragIcon()
{
    return (HCURSOR) m_hIcon;
}

void CTxz1Dlg::FreeObjects()
{
    if(m_dc.GetSafeHdc() != NULL)
    {
        m_dc.SelectObject(m_pOldBmp);
        m_dc.DeleteDC();
        m_bmp.DeleteObject();
    }
}



void CTxz1Dlg::OnDestroy()
{
    CDialog::OnDestroy();
    // TODO: Add your message handler code here
    FreeObjects();   
    if (gameback!=NULL)
    {
        delete[] gameback;
        gameback = NULL;
    }
}

/*
Invalidate  void Invalidate( BOOL bErase = TRUE );
  该函数的作用是使整个窗口客户区无效。窗口的客户区无效意味着需要重绘,
    例如,如果一个被其它窗口遮住的窗口变成了前台窗口,那么原来被遮住的部分就是无效的,
    需要重绘。这时Windows会在应用程序的消息队列中放置WM_PAINT消息。
    MFC为窗口类提供了WM_PAINT的消息处理函数OnPaint,
    OnPaint负责重绘窗口。
    视图类有一些例外,在视图类的OnPaint函数中调用了OnDraw函数,
    实际的重绘工作由OnDraw来完成。参数bErase为TRUE时,
    重绘区域内的背景将被擦除,否则,背景将保持不变。
  它和 UpdateWindow( )区别在于:
  UpdateWindow( )的作用是使窗口立即重绘。
    调用Invalidate等函数后窗口不会立即重绘,
    这是由于WM_PAINT消息的优先级很低,
    它需要等消息队列中的其它消息发送完后才能被处理。
    调用UpdateWindow函数可使WM_PAINT被直接发送到目标窗口,
    从而导致窗口立即重绘。
*/

//0x0C,0x0D, 代表长宽
//00 是空腔
//01 是围墙
//02 箱子
//03 目的地
//04 是人
//06 代表不可到达的空腔
enum{
    Map_Space=0,
    Map_Wall,
    Map_Box,
    Map_Goal,
    Map_Player,
    Map_Nop,
    Map_Unreach,
};

void CTxz1Dlg::LoadMap(int nIndex)
{
    unsigned long addr,x,y,ix,iy,d;
    gamebackcnt=0;
    for(ix=0;ix<256;ix++)    {map[ix]=6;mapball[ix]=0;}
    addr=(((unsigned long)txz_mapindex[nIndex*4+1])<<8)+txz_mapindex[nIndex*4]-1;
    x=txz_map[addr++];
    y=txz_map[addr++];
    for(iy=0;iy<y;iy++)
    {
        for(ix=0;ix<x;ix++)
        {
            d=txz_map[addr++];
            if(d==Map_Goal)
            {
                map[16*(8-y/2+iy)+(8-x/2+ix)]=Map_Space;
                mapball[16*(8-y/2+iy)+(8-x/2+ix)]=1;
            }else
            {
                map[16*(8-y/2+iy)+(8-x/2+ix)]=(int)d;
                if(d==Map_Player)                //player位置坐标
                {
                    //*player=16*(8-y/2+iy)+(8-x/2+ix);
                    player.x=8-x/2+ix;
                    player.y=8-y/2+iy;
                }
            }
        }
    }
}

void CTxz1Dlg::DrawMap(CPaintDC *pdc)
{
    UINT i,d=0;

    CDC CacheDC;                            //创建一个缓存
    CDC *pDCTmp = GetDC();                        //获得程序的DC环境
    CacheDC.CreateCompatibleDC(pDCTmp);            //创建相应的内存区域

    //定义一个位图对象
    CBitmap bmp;
   
    //获取窗体客户区尺寸
    CRect rt;
    GetClientRect(&rt);   
    int nWidth = rt.Width();
    int nHeight = rt.Height();
   
    //建立一个与窗体客户区显示兼容的位图
    bmp.CreateCompatibleBitmap(pDCTmp,nWidth,nHeight);
    //关联位图与虚拟屏
    CBitmap *pOldBit=CacheDC.SelectObject(&bmp);
   
    ReleaseDC(pDCTmp);                            //释放环境

    for(i=0;i<256;i++)
    {
        if(map[i]!=Map_Unreach)
        {
            if(mapball[i])
            {
                d=12;
                if(map[i]==Map_Box)        d=10;
                if(map[i]==Map_Player)    d=7;
            }
            else
            {
                if(map[i]==Map_Space)        d=11;
                else if(map[i]==Map_Wall)    d=9;
                else if(map[i]==Map_Box)    d=8;
                else if(map[i]==Map_Player)    d=7;
            }
            CacheDC.BitBlt(                            //在缓存中贴图
                (i&15)*30, (i/16)*30,
                30, 30,
                &m_dc,
                d*30, 0,
                SRCCOPY);
        }
    }

    pdc->BitBlt(                                    //将缓存中的贴图,贴到Client中
        0,0,
        nWidth, nHeight,
        &CacheDC,
        0, 0,
        SRCCOPY);

    CacheDC.SelectObject(pOldBit);
    CacheDC.DeleteDC();
    bmp.DeleteObject();
}


void CTxz1Dlg::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
    //CString tmpStr;
    //tmpStr.Format("标志位:%d-%d 位置%d,%d",player.x,player.y,point.x/30,point.y/30);
    //SetDlgItemText(IDC_OUTPUT,tmpStr);   
    int    nx=point.x/30;
    int ny=point.y/30;
    if(nx<16 && ny<16 && m_bFindWay==FALSE)
    {
        ny=ny*16+nx;
        if(map[ny]==Map_Space)        FindWay(ny);
        else if(map[ny]==Map_Box)    PushBox(ny);
    }

    CDialog::OnLButtonDown(nFlags, point);
}

#define maxway 200

UINT CTxz1Dlg::FindWayProc(LPVOID lpParam)
{
    CTxz1Dlg *pDlg=(CTxz1Dlg*)lpParam;

    typedef struct
    {
        UINT addr;
        UINT farther;
    }myway;
    myway way[maxway];   
   
    UINT wayback[maxway],waybegin=0,wayend=1;
    UINT map_temp[256];
    UINT dest=pDlg->m_goal;
    UINT PlayerPos=(UINT)(pDlg->player.y*16+pDlg->player.x);
    unsigned long i;

    for(i=0;i<256;i++)    map_temp[i]=pDlg->map[i];
   
    way[0].addr=PlayerPos;        //设置起始点
    while(waybegin<wayend)
    {
        if( way[waybegin].addr>16 )            //向上查找
        {
            if(map_temp[way[waybegin].addr-16]==0)        //可以嵌入
            {
                way[wayend].addr=way[waybegin].addr-16;
                way[wayend].farther=waybegin;
                if(way[wayend].addr==dest)    break; //找到目标
                map_temp[way[wayend].addr]=1;
                if(++wayend>=maxway)    break;        //寻找失败
            }
        }
        
        if( way[waybegin].addr&15 )            //向左边寻找
        {
            if(map_temp[way[waybegin].addr-1]==0)        //可以嵌入
            {
                way[wayend].addr=way[waybegin].addr-1;
                way[wayend].farther=waybegin;
                if(way[wayend].addr==dest)    break; //找到目标
                map_temp[way[wayend].addr]=1;
                if(++wayend>=maxway)    break;        //寻找失败
            }
        }
        
        if( way[waybegin].addr<240 )            //向下寻找
        {
            if(map_temp[way[waybegin].addr+16]==0)        //可以嵌入
            {
                way[wayend].addr=way[waybegin].addr+16;
                way[wayend].farther=waybegin;
                if(way[wayend].addr==dest)    break; //找到目标
                map_temp[way[wayend].addr]=1;
                if(++wayend>=maxway)    break;        //寻找失败
            }
        }
        
        if( (way[waybegin].addr&15)!=15 )            //向左边寻找
        {
            if(map_temp[way[waybegin].addr+1]==0)        //可以嵌入
            {
                way[wayend].addr=way[waybegin].addr+1;
                way[wayend].farther=waybegin;
                if(way[wayend].addr==dest)    break; //找到目标
                map_temp[way[wayend].addr]=1;
                if(++wayend>=maxway)    break;        //寻找失败
            }
        }
        ++waybegin;
    }
    if(way[wayend].addr==dest)                //招到目标
    {
        waybegin=0;
        while(1)                //逆运算
        {
            wayback[waybegin]=way[wayend].addr;
            wayend=way[wayend].farther;
            ++waybegin;
            if(wayend==0)    break;
        }
        do
        {
            --waybegin;
            pDlg->map[PlayerPos]=0;        //清除
            PlayerPos=wayback[waybegin];
            pDlg->map[PlayerPos]=4;
            pDlg->Invalidate(FALSE);
            Sleep(80);
        }while(waybegin);
        pDlg->player.x=PlayerPos&0x0F;
        pDlg->player.y=PlayerPos>>4;
    }
    pDlg->m_bFindWay=FALSE;
    return 0;
}

void CTxz1Dlg::FindWay(UINT nIndex)
{
    m_bFindWay=TRUE;
    m_goal=nIndex;
   
    AfxBeginThread(FindWayProc,(LPVOID)this);        //要静态的函数 才能成为进程函数的 记住
}


void CTxz1Dlg::PushBox(UINT y)
{
    UINT PlayerPos=player.y*16+player.x;
    if( ( ( PlayerPos==(y+1) ||  PlayerPos==(y-1) )
        && ( (PlayerPos/16)==(y/16)))        //左右相邻
        || ( ( (PlayerPos&15)==(y&15) )
        &&    (PlayerPos==y+16 || PlayerPos==y-16) )  )    //上下相邻
    {
        UINT temp=y;
        temp=temp*2-PlayerPos;
        if(map[temp]==Map_Space)
        {
            if(gamebackcnt<255){
                //gameback[gamebackcnt][0]=temp;    //记录移动后的位置
                gameback[gamebackcnt*2]=temp;
                //gameback[gamebackcnt][1]=y;        //记录移动前的位置
                gameback[gamebackcnt*2+1]=y;
                ++gamebackcnt;                    //最多保存255个动作
            }
            map[PlayerPos]=Map_Space;
            map[temp]=Map_Box;
            map[y]=Map_Player;
            //::mouse_event(MOUSEEVENTF_MOVE,30*((y&0x0f)-player.x),30*((y>>4)-player.y),0,0);
            //::mouse_event(MOUSEEVENTF_MOVE,20*((y&0x0f)-player.x),20*((y>>4)-player.y),0,0);

            CPoint tmpMouse;                //用这两个语句设定鼠标的绝对位置
            ::GetCursorPos(&tmpMouse);
            ::SetCursorPos(tmpMouse.x+30*((y&0x0f)-player.x),tmpMouse.y+30*((y>>4)-player.y));


            PlayerPos=y;
            player.x=PlayerPos&0x0F;
            player.y=PlayerPos>>4;
            Invalidate(FALSE);
            if(TestWin())
            {
                AfxMessageBox("恭喜,你过关了...");
                m_mapIndex++;
                LoadMap(m_mapIndex);
            }
            Invalidate(FALSE);
        }
    }
}


void CTxz1Dlg::OnRButtonDown(UINT nFlags, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
    if(gamebackcnt)
    {
        UINT PlayerPos=player.y*16+player.x;
        --gamebackcnt;
        map[PlayerPos]=0;
        //map[gameback[gamebackcnt][0]]=Map_Space;
        map[gameback[gamebackcnt*2]]=Map_Space;
        //map[gameback[gamebackcnt][1]]=Map_Box;
        map[gameback[gamebackcnt*2+1]]=Map_Box;
        //PlayerPos=((UINT)gameback[gamebackcnt][1])*2-gameback[gamebackcnt][0];
        PlayerPos=((UINT)gameback[gamebackcnt*2+1])*2-gameback[gamebackcnt*2];
        map[PlayerPos]=Map_Player;
        player.x=PlayerPos&0x0F;
        player.y=PlayerPos>>4;
        Invalidate(FALSE);
    }
    CDialog::OnRButtonDown(nFlags, point);
}

UINT CTxz1Dlg::TestWin()
{
    UINT i;
    for(i=0;i<256;i++)
    {
        if(mapball[i] && map[i]!=2)    return 0;
    }
    return 1;
}

void CTxz1Dlg::OnBtnOpen()
{
    // TODO: Add your control notification handler code here
    if(m_bFindWay==FALSE && m_mapIndex<sizeof(txz_mapindex)/4)
    {
        m_mapIndex++;
        LoadMap(m_mapIndex);
        Invalidate(FALSE);
    }
}

void CTxz1Dlg::OnBtnBack()
{
    // TODO: Add your control notification handler code here
    if(m_bFindWay==FALSE && m_mapIndex)
    {
        m_mapIndex--;
        LoadMap(m_mapIndex);
        Invalidate(FALSE);
    }
}
搜索更多相关主题的帖子: include 语言 镇关西 public 语言 include 镇关西 public 
2012-12-18 15:53
yuccn
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:何方
等 级:版主
威 望:167
帖 子:6809
专家分:42393
注 册:2010-12-16
得分:20 
估计没有人有耐心看这样的东西吧。。自己写的自己有耐心看~

我行我乐
我的博客:
http://blog.yuccn. net
2012-12-18 23:31



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-391892-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.058510 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved