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

📄 eightnumber.cpp

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

#include "StdAfx.h"
#include ".\EightNumber.h"

//-------------------------------------------构造函数----------------------------------------------
CEightNumber::CEightNumber(void)
{
	int i_nRowNum, i_nColNum;
	for ( i_nRowNum=0; i_nRowNum<4; i_nRowNum++ )
		m_tDirection[i_nRowNum].x = g_aHorizon[i_nRowNum];   // 初始化搜索方向的水平分量
	for ( i_nColNum=0; i_nColNum<4; i_nColNum++ )
		m_tDirection[i_nColNum].y = g_aVertical[i_nColNum];  // 初始化搜索方向的垂直分量
	for ( i_nRowNum=0; i_nRowNum<3; i_nRowNum++ )
		for ( i_nColNum=0; i_nColNum<3; i_nColNum++ )
			m_aGoal[i_nRowNum][i_nColNum] = g_aGoal[i_nRowNum][i_nColNum]; // 初始化目标状态
	m_pHead = NULL;           // 初始化头指针
	m_pTail = NULL;           // 初始化尾指针
	m_pLevel = NULL;          // 初始化第N层结点数量的头指针
	m_pLevelTail = NULL;      // 初始化第N层结点数量的头指针
	m_nTotalNum = 0;          // 初始化总结点数
	m_nDepth = 0;             // 初始化深度
}

//----------------------------------------虚拟析构函数---------------------------------------------
CEightNumber::~CEightNumber(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 );
	}
}

//--------------------------------------初始化八数码问题-------------------------------------------
bool CEightNumber::initEightNumber(int aCurrent[3][3])
{
	if( isValid ( aCurrent ) )
	{
		while( m_pHead )            // 删除八数码问题的状态内存空间
	    {
		    m_pTail = m_pHead;
		    m_pHead = m_pHead->pNext;
		    delete( m_pTail );
	    }
		m_pHead = new TEightNumber;      // 头指针指向源结点
		int i_nRowNum, i_nColNum;
		for ( i_nRowNum=0; i_nRowNum<3; i_nRowNum++ )   
			for ( i_nColNum=0; i_nColNum<3; i_nColNum++ )
				m_pHead->aState[i_nRowNum][i_nColNum] = aCurrent[i_nRowNum][i_nColNum];
		m_pHead->nDepth = 1;
		m_pHead->nBreadth = 1;
		m_pHead->nChildren = 0;
		m_pHead->nWeight = 0;
		m_pHead->nDirection = 0;
		m_pHead->bIsSolution = false;
		m_pHead->bIsVisited = false;
		m_pHead->pParent = NULL;
		m_pHead->pChildren = NULL;
		m_pHead->pSibling = NULL;
		m_pHead->pPrev = NULL;
		m_pHead->pNext = NULL;
		m_pTail = m_pHead;                // 尾指针指向源结点
		m_pLevel = new TLevel;            // 第一层结点数是1
		m_pLevel->nNodeNumber = 1;
		m_pLevel->pNext = NULL;
		m_pLevelTail = m_pLevel;
		m_nTotalNum = 1;                  // 总结点数量是1
		m_nDepth = 1;                     // 深度是1

		return true;
	}
	else
		return false;
}

//------------------------------------A*算法搜索八数码问题-------------------------------------------
bool CEightNumber::searchByAlgorithm(void)
{
	calcWeight( m_pHead );
	TEightNumberPtr i_pTemp = m_pHead,i_pNew;
	int i_nDirection;
    while ( i_pTemp )            // 如果仍有路径可寻
	{
		i_pTemp = findMinCost();
		if ( !i_pTemp )
			return false;               // 如果结点总数大于1000 则认为该问题无解
		if ( isGoal( i_pTemp) )
		{
			findAnswer( i_pTemp );
			return true;
		}
		for ( i_nDirection = 0; i_nDirection<4; i_nDirection++ )
			if ( findNext( i_pTemp, i_nDirection ) )   // 按东南西北的顺序判判断下一状态是否合法
			{
                i_pNew = newEightNumber ( i_pTemp ,i_nDirection ) ;
                calcWeight( i_pNew );
			}
		if ( m_nTotalNum>4000 ) 
			return false;               // 如果结点总数大于1000 则认为该问题无解
	} 
	AfxMessageBox("该问题无解 只显示前50步!");
	return false;     // 如果所以路径走完仍没找到 则返回 fasle
}

//----------------------------------广度优先搜索八数码问题-----------------------------------------
bool CEightNumber::searchByBreadth(void)
{
	if ( isGoal ( m_pHead ) )    // 如果源状态等于目标状态 则返回 true
	{   
		findAnswer( m_pHead );
	    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( m_pTail );       // 找出八数码问题的正解
					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( m_pHead );
	    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( m_pTail );       // 找出八数码问题的正解
					AfxMessageBox("恭喜你!算法成功");
				    return true;
				}

		if ( m_nTotalNum>4000 ) 
		{
			AfxMessageBox("算法失败 只显示前50步!");
			return false;               // 如果结点总数大于1000 则认为该问题无解
		}
	} 
	AfxMessageBox("该问题无解 只显示前50步!");
	return false;     // 如果所以路径走完仍没找到 则返回 fasle
}

//-------------------------------------------获取结果链表----------------------------------------
TEightNumberPtr CEightNumber::getResultList(void)
{
	return m_pHead;
}

//----------------------------------------获取结果总结点数量-------------------------------------
int CEightNumber::getResultNum(void)
{
	return m_nTotalNum;
}

//-------------------------------------------获取结果深度----------------------------------------
int CEightNumber::getResultDepth(void)
{
	return m_nDepth;
}

//---------------------------------------显示全部结点----------------------------------------------
CSize CEightNumber::showAll(CDC* pDC, TEightNumberPtr pResultList, int nResultNum)
{
	TEightNumberPtr i_pResultList = pResultList;
	int i_nResultNum = nResultNum;      
	int i_nRowNum, i_nColNum, i_nTempNum;
	int i_nDispX, i_nDispY, i_nMaxX = 100 , i_nMaxY = 100;
	CString i_strDispItem;
    for ( i_nTempNum=0; i_nTempNum<i_nResultNum; i_nTempNum++ )
	{ 
		i_nDispY = i_pResultList->nDepth;
		i_nDispX = i_pResultList->nBreadth;
		i_nDispX = 10 + ( i_nDispX -1 ) * 70;
        i_nDispY = 20 + ( i_nDispY -1 ) * 130;
		if ( i_pResultList->bIsSolution )
			pDC->SetTextColor( RGB ( 0, 0, 255 ) );
		else
			pDC->SetTextColor( RGB ( 0, 0, 0 ) );
		if ( i_pResultList->nWeight !=0 )
		{
			i_strDispItem.Format("%d", i_pResultList->nWeight - i_pResultList->nDepth +1 );
			pDC->TextOut( i_nDispX+20, i_nDispY-20, i_strDispItem );
			i_strDispItem.Format("%d", i_pResultList->nWeight);
			pDC->TextOut( i_nDispX+35, i_nDispY-20, i_strDispItem );
		}
		for ( i_nRowNum=0; i_nRowNum<3; i_nRowNum++ )
		{	
			for (i_nColNum=0; i_nColNum<3; i_nColNum++ )
			{
				pDC->Rectangle( i_nDispX-1, i_nDispY-1, i_nDispX+20, i_nDispY+20 );
				if ( i_pResultList->aState[i_nRowNum][i_nColNum] !=0 )
					i_strDispItem.Format("%d",i_pResultList->aState[i_nRowNum][i_nColNum]);
				else
					i_strDispItem=" ";
				pDC->TextOut( i_nDispX+6, i_nDispY+2, i_strDispItem );
				i_nDispX+=20;
			} 
			i_nDispX-=60;
			i_nDispY+=20;
		}
		if ( i_pResultList->pParent )
		{
			pDC->MoveTo( i_nDispX+30, i_nDispY-62 );
			i_nRowNum = i_pResultList->pParent->nBreadth;
			i_nColNum = i_pResultList->pParent->nDepth;
			i_nRowNum = 10 + (i_nRowNum-1) * 70 + 60;
			i_nColNum = 20 + (i_nColNum-1) * 130 + 60;
			pDC->LineTo ( i_nRowNum-30 ,i_nColNum );
		}
        if ( i_nDispX + 60 > i_nMaxX )
			i_nMaxX = i_nDispX+60;
        if ( i_nDispY > i_nMaxY )
			i_nMaxY = i_nDispY;
	    i_pResultList = i_pResultList->pNext; 
	}
	//判断是否生成滚动条
	CSize i_cSize;
	i_cSize.cx = i_nMaxX+20;
	i_cSize.cy = i_nMaxY+20;
	return i_cSize;
}

//----------------------------------------只显示结果-----------------------------------------------
CSize CEightNumber::showResult(CDC* pDC, TEightNumberPtr pResultList, int nResultNum)
{
	TEightNumberPtr i_pResultList = pResultList;
	int i_nResultNum = nResultNum;
	int i_nRowNum, i_nColNum, i_nTempNum;
	int i_nDispX = 100, i_nDispY= 100;       int i_nMaxX = 100, i_nMaxY = 100;
	CString i_strDispItem;
    for ( i_nTempNum=0; i_nTempNum<i_nResultNum; i_nTempNum++ )
	{ 
		i_nDispY = i_pResultList->nDepth;

⌨️ 快捷键说明

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