⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mc.cpp

📁 用VC编制的集成的野人和八数码演示程序。其中野人程序用动态的效果演示
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-------------------------------------------------------------------------------------------------
//-------修道士野人问题的实现文件       作者:申徐洲       日期:2004年5月6日      AllRightsReserve
//-------------------------------------------------------------------------------------------------

#include "StdAfx.h"
#include ".\Mc.h"

//-------------------------------------------构造函数----------------------------------------------
CMissionarySavage::CMissionarySavage(void)
{
	m_tDirection[0].x = 0;    m_tDirection[0].y = 1;
	m_tDirection[1].x = 0;    m_tDirection[1].y = 2;
	m_tDirection[2].x = 1;    m_tDirection[2].y = 1;
	m_tDirection[3].x = 1;    m_tDirection[3].y = 0;
	m_tDirection[4].x = 2;    m_tDirection[4].y = 0;
	m_pHead = new TMissionarySavage;      // 头指针指向源结点
	m_pHead->nMissionary = 3;
	m_pHead->nSavage = 3;
	m_pHead->nBoat = 1;
	m_pHead->nDepth = 1;
	m_pHead->nBreadth = 1;
	m_pHead->nWeight = 4;
	m_pHead->bIsSolution = false;
	m_pHead->bIsVisited = false;
	m_pHead->pParent = NULL;
	m_pHead->pNext = NULL;
	m_pHead->pSibling = NULL;
	m_pTail = m_pHead;                // 尾指针指向源结点
	m_pLevel = new TMcLevel;          // 第一层结点数是1
	m_pLevel->nNodeNumber = 1;
	m_pLevel->pLevel = m_pHead;
	m_pLevel->pNext = NULL;
	m_pLevelTail = m_pLevel;
	m_nTotalNum = 1;          // 初始化总结点数
	m_nDepth = 1;             // 初始化深度
	m_pCurrent = m_pHead;
}

//----------------------------------------虚拟析构函数---------------------------------------------
CMissionarySavage::~CMissionarySavage(void)
{
	while( m_pHead )            // 删除修道士野人问题的状态内存空间
	{
		m_pTail = m_pHead;
		m_pHead = m_pHead->pNext;
		delete( m_pTail );
	}
	while( m_pLevel )           // 删除修道士野人问题的第N层结点数量的内存空间
	{
		m_pLevelTail = m_pLevel;
		m_pLevel = m_pLevel->pNext;
		delete( m_pLevelTail );
	} 
}

//----------------------------------A*算法搜索修道士野人问题-----------------------------------------
bool CMissionarySavage::searchByAlgorithm(void)
{
	TMissionarySavagePtr i_pTemp = m_pHead,i_pNew;
	int i_nDirection;
    while ( i_pTemp )            // 如果仍有路径可寻
	{
		i_pTemp = findMinCost();
		if ( !i_pTemp )
			return false;
		if ( isGoal( i_pTemp ) )
		{
			findAnswer( i_pTemp); 
			return true;
		}
		for ( i_nDirection = 0; i_nDirection<5; i_nDirection++ )
			if ( findNext( i_pTemp, i_nDirection ) )   // 判断下一状态是否合法
                i_pNew = newMissionarySavage ( i_pTemp ,i_nDirection ) ;
		if ( m_nTotalNum>4000 ) 
			return false;               // 如果结点总数大于1000 则认为该问题无解
		i_pTemp = i_pTemp->pNext;
	} 
	return false;     // 如果所以路径走完仍没找到 则返回 fasle
}
/*
//----------------------------------广度优先搜索八数码问题-----------------------------------------
bool CEightNumber::searchByBreadth(void)
{
	if ( isGoal ( m_pHead ) )    // 如果源状态等于目标状态 则返回 true
	{   
		findAnswer();
	    AfxMessageBox("恭喜你!算法成功");
		return true;
	}
	TEightNumberPtr i_pTemp = m_pHead;
	int i_nDirection;
    while ( i_pTemp )            // 如果仍有路径可寻
	{
		for ( i_nDirection=0; i_nDirection<4; i_nDirection++ )
			if ( findNext ( i_pTemp, i_nDirection ) )   // 按东南西北的顺序判判断下一状态是否合法
				if( isGoal ( newEightNumber ( i_pTemp ,i_nDirection ) ) ) // 如果下一状态是目标状态
				{                                                       
					findAnswer();       // 找出八数码问题的正解
					AfxMessageBox("恭喜你!算法成功");
					return true;
				}
		if ( m_nTotalNum>4000 ) 
		{
			AfxMessageBox("算法失败 只显示前50步!");
			return false;               // 如果结点总数大于1000 则认为该问题无解
		}
        i_pTemp = i_pTemp->pNext;    // 指向下一个状态
	} 
	AfxMessageBox("该问题无解 只显示前50步!");
	return false;     // 如果所以路径走完仍没找到 则返回 fasle
}

//----------------------------------深度优先搜索八数码问题-----------------------------------------
bool CEightNumber::searchByDepth(void)
{
	if ( isGoal ( m_pHead ) )    // 如果源状态等于目标状态 则返回 true
	{   
		findAnswer();
	    AfxMessageBox("恭喜你!算法成功");
		return true;
	}

	TEightNumberPtr i_pTemp = m_pHead;
	int i_nDirection;
    while ( i_pTemp )            // 如果仍有路径可寻
	{
		i_pTemp = findMaxDepth();
		if ( !i_pTemp )
		{
			AfxMessageBox("算法失败 只显示前50步!");
			return false;               // 如果结点总数大于1000 则认为该问题无解
		}
		for ( i_nDirection = 0; i_nDirection<4; i_nDirection++ )
			if ( findNext( i_pTemp, i_nDirection ) )   // 按东南西北的顺序判判断下一状态是否合法
			    if( isGoal ( newEightNumber ( i_pTemp ,i_nDirection ) ) ) // 如果下一状态是目标状态
			    {                                                       
				    findAnswer();       // 找出八数码问题的正解
					AfxMessageBox("恭喜你!算法成功");
				    return true;
				}

		if ( m_nTotalNum>4000 ) 
		{
			AfxMessageBox("算法失败 只显示前50步!");
			return false;               // 如果结点总数大于1000 则认为该问题无解
		}
	} 
	AfxMessageBox("该问题无解 只显示前50步!");
	return false;     // 如果所以路径走完仍没找到 则返回 fasle
}
*/
//------------------------------------显示修道士和野人的结果-------------------------------------
bool CMissionarySavage::show(CDC* pDC)
{
	CPen i_greenPen, i_oldPen;
	CBrush i_greenBrush, i_oldBrush;
    int i_nDispLeftX=10, i_nDispRightX=550, i_nDispY=10;       bool i_bIsFinished;
	int i_nLeftMissionary,i_nLeftSavage,i_nRightMissionary,i_nRightSavage;
	int i_nMissionary,i_nSavage,i_nTotalNum;
	i_greenPen.CreatePen( PS_SOLID, 2, RGB( 0, 255, 0 ) );
	i_oldPen.CreatePen( PS_SOLID, 1, RGB( 0, 0, 0 ) );
	i_greenBrush.CreateSolidBrush( RGB( 0, 255, 0 ) );
	i_oldBrush.CreateSolidBrush( RGB ( 255, 255, 255) );

	if ( m_pCurrent )
	{
	    if ( m_pCurrent == m_pHead )              // 如果是头指针
		{
		    showPerson( pDC, 3, 3, i_nDispLeftX, i_nDispY );
			m_pCurrent = m_pCurrent->pNext;
		}
		else
		{
			while ( !m_pCurrent->bIsSolution )
				m_pCurrent = m_pCurrent->pNext;
			if ( !m_bArriveShore )
			{
				if ( m_pCurrent->nBoat == -1 )       // 如果船在左岸
				{
					i_nLeftMissionary = m_pCurrent->nMissionary;
		            i_nLeftSavage = m_pCurrent->nSavage;
		            i_nRightMissionary = 3 - m_pCurrent->pParent->nMissionary;
		            i_nRightSavage = 3 - m_pCurrent->pParent->nSavage;
		            i_nMissionary = m_pCurrent->pParent->nMissionary - i_nLeftMissionary;
		            i_nSavage = m_pCurrent->pParent->nSavage - i_nLeftSavage;
		            i_nTotalNum = i_nMissionary + i_nSavage;
					i_nDispLeftX=showPerson(pDC,i_nLeftMissionary,i_nLeftSavage,i_nDispLeftX,i_nDispY);
					i_nDispRightX=showPerson(pDC,i_nRightMissionary,i_nRightSavage,i_nDispRightX,i_nDispY);					
					pDC->SelectObject( &i_oldPen );       pDC->SelectObject( &i_greenBrush );  
                    pDC->Rectangle( i_nDispLeftX+m_nTimer+5,i_nDispY+42,i_nDispLeftX+m_nTimer+25*i_nTotalNum,i_nDispY+47 );					
					i_nDispLeftX=showPerson(pDC,i_nMissionary,i_nSavage,i_nDispLeftX+m_nTimer+5,i_nDispY);
					m_nTimer += 10;
					if ( i_nDispLeftX>540 )
						m_bArriveShore = true; 
				}
				else       // 如果船在右岸
				{
					i_nLeftMissionary = m_pCurrent->pParent->nMissionary;
		            i_nLeftSavage = m_pCurrent->pParent->nSavage;
		            i_nRightMissionary = 3-m_pCurrent->nMissionary;
		            i_nRightSavage = 3-m_pCurrent->nSavage;
		            i_nMissionary = m_pCurrent->nMissionary - i_nLeftMissionary;
		            i_nSavage = m_pCurrent->nSavage - i_nLeftSavage;
		            i_nTotalNum = i_nMissionary + i_nSavage;
					i_nDispLeftX=showPerson(pDC,i_nLeftMissionary,i_nLeftSavage,i_nDispLeftX,i_nDispY);
					i_nDispRightX=showPerson(pDC,i_nRightMissionary,i_nRightSavage,i_nDispRightX,i_nDispY);					
				    i_nDispRightX = 550;    pDC->SelectObject(&i_oldPen);    pDC->SelectObject(&i_greenBrush);    
                    pDC->Rectangle( i_nDispRightX-m_nTimer-25*i_nTotalNum, i_nDispY+42 ,i_nDispRightX-m_nTimer-5, i_nDispY+47 );					
					i_nDispRightX=showPerson(pDC,i_nMissionary,i_nSavage,i_nDispRightX-m_nTimer-25*i_nTotalNum,i_nDispY);
					m_nTimer += 10;
					if ( i_nDispRightX-25*i_nTotalNum-10<i_nDispLeftX )
						m_bArriveShore = true; 
				}				
			}
			else       // 如果船到达岸边
			{
				i_nLeftMissionary = m_pCurrent->nMissionary;
			    i_nRightMissionary = 3 - i_nLeftMissionary;
			    i_nLeftSavage = m_pCurrent->nSavage;
			    i_nRightSavage = 3 - i_nLeftSavage;
           		i_nDispLeftX=showPerson(pDC,i_nLeftMissionary,i_nLeftSavage,i_nDispLeftX,i_nDispY);				
				pDC->SelectObject( &i_oldPen );    pDC->SelectObject( &i_greenBrush );
		        if ( m_pCurrent->nBoat==1 )
			        pDC->Rectangle( i_nDispLeftX+5, i_nDispY+22, i_nDispLeftX+25, i_nDispY+27 );
		        else
			        pDC->Rectangle( 525, i_nDispY+22 ,545, i_nDispY+27 );
				i_nDispRightX=showPerson(pDC,i_nRightMissionary,i_nRightSavage,i_nDispRightX,i_nDispY); 
				m_nTimer = 0;
			    m_bArriveShore = false;
			    m_pCurrent = m_pCurrent->pNext;
			}
		} 
		showPrompt( pDC );
		i_bIsFinished = false;
	}
	else
		i_bIsFinished = true;
	return i_bIsFinished;
}

//----------------------------------------设置定时器初始状态-------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -