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

📄 qiyuanview.cpp

📁 利用人工智能的经典算法实现迷宫游戏;里面的A星(a*)算法可以很方便的移植到应用程序中
💻 CPP
📖 第 1 页 / 共 4 页
字号:
						CRect windowTextCarposition(m_MazeWinWidth+20, 0+160,m_MazeWinWidth+100, 0+180);
						InvalidateRect(&windowTextCarposition);
					}				
				}
				break;
	case 39: //向右可走,(可走的条件是没超出边界且为空,下同)
				{
					if(ViewMaze.MazeMap[ViewMaze.CarPos.x][ViewMaze.CarPos.y+1]==0)				
					{
						//更新显示
						CRect windowSonRect(MapWidth*ViewMaze.CarPos.y,MapHeight*ViewMaze.CarPos.x,MapWidth*ViewMaze.CarPos.y+MapWidth,MapHeight*ViewMaze.CarPos.x+MapHeight);
						InvalidateRect(&windowSonRect);	

						CRect windowSonNextRect(MapWidth*(ViewMaze.CarPos.y+1),MapHeight*ViewMaze.CarPos.x,MapWidth*(ViewMaze.CarPos.y+1)+MapWidth,MapHeight*ViewMaze.CarPos.x+MapHeight);
						InvalidateRect(&windowSonNextRect);	
	//向右走一步
						ViewMaze.CarPos.y+=1;
						//更新文字——小车位置
						CRect windowTextCarposition(m_MazeWinWidth+20, 0+160,m_MazeWinWidth+100, 0+180);
						InvalidateRect(&windowTextCarposition);
					}				
				}
				break;
	case 40: //向下可走,(可走的条件是没超出边界且为空,下同)
				
				{
					if(ViewMaze.MazeMap[ViewMaze.CarPos.x+1][ViewMaze.CarPos.y]==0)				
					{
						//更新显示
						CRect windowSonRect(MapWidth*ViewMaze.CarPos.y,MapHeight*ViewMaze.CarPos.x,MapWidth*ViewMaze.CarPos.y+MapWidth,MapHeight*ViewMaze.CarPos.x+MapHeight);
						InvalidateRect(&windowSonRect);	

						CRect windowSonNextRect(MapWidth*(ViewMaze.CarPos.y),MapHeight*(ViewMaze.CarPos.x+1),MapWidth*ViewMaze.CarPos.y+MapWidth,MapHeight*(ViewMaze.CarPos.x+1)+MapHeight);
						InvalidateRect(&windowSonNextRect);	
	//向下走一步
						ViewMaze.CarPos.x+=1;
						//更新文字——小车位置
						CRect windowTextCarposition(m_MazeWinWidth+20, 0+160,m_MazeWinWidth+100, 0+180);
						InvalidateRect(&windowTextCarposition);
					}				
				}
				break;
			default :
				break;
			}
		if(ViewMaze.CarPos==ViewMaze.GoalPos)//如果不是终点小车位置加一
		{	
			//AfxMessageBox("走到终点!");	
			//在右端提示到达终点
			OnTheEndFlag=1;
			CRect windowText2Rect(m_MazeWinWidth+20, 0+340,m_MazeWinWidth+100, 0+360);
			InvalidateRect(&windowText2Rect);

		}
		else
		{
			OnTheEndFlag=0;
			CRect windowText2Rect(m_MazeWinWidth+20, 0+340,m_MazeWinWidth+100, 0+360);
			InvalidateRect(&windowText2Rect);
		}
	}
	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
//新建游戏
int CQiyuanView::GameNew()
{
return TRUE;
}
//绘图设备环境的初始化
int CQiyuanView::DcEnvInitial()
{
		return TRUE;
}

int CQiyuanView::DCEnvClear()
{
	//设备环境
	m_memDC.DeleteDC();
	m_memRectDC.DeleteDC();
	//位图资源
	DeleteObject(m_memBmp);
	DeleteObject(m_hMemRectBmp);
	delete(m_pBlackPen);
	delete(m_pWhiteBrush);
	delete(m_pBlackBrush);
return TRUE;
}

int CQiyuanView::DrawGame(CDC *pDC)
{
	int index1=50,index2=250;
//	CQiyuanDoc* pDoc = GetDocument();
//	ASSERT_VALID(pDoc);

//	BITMAP bmp;
//	wall.GetBitmap(&bmp);

//	CDC MemDC;
//	MemDC.CreateCompatibleDC(pDC);

//	dcCompatible.SelectObject(&wall);

//	dcCompatible.SelectObject(&wall);
	CRect rect;
	GetClientRect(&rect);
	m_WinWidth=rect.Width();
	m_WinHeight=rect.Height();
//	pDC -> SelectObject(m_pWhiteBrush);
//	pDC -> Rectangle(rect);		
	MapWidth=m_WinWidth/ViewMaze.col;
	MapHeight=m_WinHeight/ViewMaze.row;
//小方块的绘制
pDC->StretchBlt(index1*MapWidth,index2*MapHeight,MapWidth,MapHeight,&m_memRectDC,
0,0,50,50,SRCCOPY);
	if(1)
	{
	if(!m_FistPlay)
	{
	//pDC -> SelectObject(m_pBlackBrush);
	//pDC -> Rectangle(rect);	
		for (index1=0;index1<ViewMaze.row;index1++)
		{
			for (index2=0;index2<ViewMaze.col;index2++)
			{
				if (ViewMaze.MazeMap[index1][index2]==WALL)
				{
					//在游戏区域中状态为被占用状态的区域绘制小方块
//			pDC ->SelectObject(&m_memBmp);
//			pDC->BitBlt(x,y,nW,nH,&m_memRectDC,m_iBlockSytle*30,0,SRCCOPY);
//			pDC->StretchBlt(index1*MapWidth,index2*MapHeight,MapWidth,MapHeight,&m_memRectDC,
//			0,0,50,50,SRCCOPY);
//					pDC -> SelectObject(m_pBlackBrush);
//					pDC -> Rectangle(index2*MapWidth,index1*MapHeight,index2*MapWidth+MapWidth,index1*MapHeight+MapHeight);
				}
			}
		}
	}
	}

return TRUE;
}

int CQiyuanView::OnHelpAbout()
{
	HWND hwnd = ::AfxGetMainWnd()->GetSafeHwnd();

	ShellAbout(hwnd,"迷宫程序  作者:刘琼 ||","E-mail:liuqiong@sina.com",NULL);	
return TRUE;
}

void CQiyuanView::OnSize(UINT nType, int cx, int cy) 
{
	CView::OnSize(nType, cx, cy);
//	DCEnvClear();
//	m_FistPlay=TRUE;
	Invalidate();
	// TODO: Add your message handler code here
	
}
//======================================================================= 
// Description :  迷宫A*搜索算法程序()
// Parameters  :  链表定义,结合状态空间的定义等,在下面的综合链表程序中面完成
// 但本程序有一个不影响应用的 缺点就 是没有释放节点   。
// $Revision: 1.00 $
// Supplement  : 无 
// 好的。现在开始。
//========================================================================
list_node * CQiyuanView::Asearch(int a[][MOSTNUM],CPoint s_n,CPoint s_g)
{
   if(Astep==0)									//若是第一次扩展则将起始节点放入open表//
   {
	   Astep++;	//步数加一
	   open_list = listnode::insert_node(open_list, s_n.x,s_n.y,0);//起始节点加入open表
	   open_list->next->f_n=abs(s_n.x-s_g.x)+ abs(s_n.y-s_g.y);	// 计算起始节点的fn 
	   Asearch(a,s_n, s_g);//递归调用A*搜索算法
   }
   if(!HaveFoundFlag)
   {
	  if(listnode::IsMyListEmpty(open_list))//若open表里无数据说明没有路径									/* 若open表空或者不可能的步数出现失败退出*/
	  {
//		  AfxMessageBox("没有路径!:(");//输出没有路径提示
		  HaveFoundFlag=0;
		  return NULL;//退出搜索,FoundWayFlag
	  }
  else//open表中有数据说名有路径
  { 
	   list_node *best_node = listnode::find_fn(open_list);//查找最好路径
	   if((best_node->row==s_g.x)&&(best_node->collum==s_g.y))//若最佳节点为目标节点
		{	
			FoundWayFlag=1; 
			HaveFoundFlag=1;
//			ViewMaze.Road[best_node->g_n+1].y=ViewMaze.GoalPos.y;
//			ViewMaze.Road[best_node->g_n+1].x=ViewMaze.GoalPos.x;
			while (!((best_node->row==s_n.x)&&(best_node->collum==s_n.y)))
			{
				ViewMaze.Road[best_node->g_n].y=best_node->collum;
				ViewMaze.Road[best_node->g_n].x=best_node->row;
				best_node = best_node->father;
			}
//			printf("%d  %d	%d\n ", best_node->row,best_node->collum,best_node->f_n);
		if(ArtificialWalkFlag==0)//自动行走方式
		{
			//AfxMessageBox("找到路径!:)");//提示找到路径,并将路径存入Road[]
		}
			return NULL;
		}
//若不是目标节点则,扩展节点bestnode生成全部子节点subnode 
//计算subnode的f(n),设置指向bestnode的指针
//子节点subnodes全部放入open表 
	   if(a[best_node->row][best_node->collum+1]==0)//向右可走,(可走的条件是没超出边界且为空,下同)
		{  
		   list_node * sub_node1= listnode::create_node(best_node->row,best_node->collum+1,0);//扩展子节点
		   list_node * temp=sub_node1;
		   sub_node1->g_n=best_node->g_n+1;
		   sub_node1->h_n=abs(sub_node1->row-s_g.x)+ abs(sub_node1->collum-s_g.y);
		   sub_node1->f_n=sub_node1->g_n+sub_node1->h_n;
		   if((NULL==(listnode::find_closed(open_list,sub_node1->row,sub_node1->collum)))&&(NULL==(listnode::find_closed(closed_list,sub_node1->row,sub_node1->collum))))
		   {	// 若节点不在closed或open表中设置sub-node指向best-node的指针 */
		     sub_node1->father=best_node;//用于寻找路径,倒着指回去
			 best_node->son1=sub_node1;
		     open_list = listnode::insert_node2(open_list, sub_node1);// 新节点放入open表 
		   }
		   else	//若节点在closed或open表中比较gn谁小留谁 
		   {
			   if(!(NULL==(listnode::find_closed(open_list,sub_node1->row,sub_node1->collum))))
			   {
				   temp=listnode::find_closed(open_list,sub_node1->row,sub_node1->collum);
			   }
			   else
			   {
				   temp=listnode::find_closed(closed_list,sub_node1->row,sub_node1->collum);
			   }
			   if(sub_node1->g_n<temp->g_n)	// 若新的较小泽用新的替代旧的 */
			   {
				   temp->g_n=sub_node1->g_n;
				   temp->father=best_node;
				   if(!(NULL==(temp=listnode::find_closed(closed_list,sub_node1->row,sub_node1->collum))))
				   {					// 若在closed表中重新计算subnode的子孙节点的fn */
					   dg_n=temp->g_n-sub_node1->g_n;
					   listnode::son_fn(temp,dg_n);							/* 重新计算subnode的子孙节点的fn  */
				   }					///从subnode中删除son即不宽展他*/ 
			   }
			   else											
			   {						// 若原先的较小则放弃新的,即不扩展它 */
			   }
		   }
		}
	   if(a[best_node->row+1][best_node->collum]==0)//向下可走(可走的条件是没超出边界且为空,
		{  
		   list_node * sub_node2= listnode::create_node(best_node->row+1,best_node->collum,0);
		   list_node * temp=sub_node2;
		   sub_node2->g_n=best_node->g_n+1;
		   sub_node2->h_n=abs(sub_node2->row-s_g.x)+ abs(sub_node2->collum-s_g.y);
		   sub_node2->f_n=sub_node2->g_n+sub_node2->h_n;
		   if((NULL==(temp=listnode::find_closed(open_list,sub_node2->row,sub_node2->collum)))&&(NULL==(temp=listnode::find_closed(closed_list,sub_node2->row,sub_node2->collum))))
		   {							 //若节点不在closed或open表中设置sub-node指向best-node的指针 */
		     sub_node2->father=best_node;//用于寻找路径,倒着指回去
			 best_node->son2=sub_node2;
		     open_list = listnode::insert_node2(open_list, sub_node2);	// 放入open表 */
		   }
		   else		// 若节点在closed或open表中比较gn谁小留谁 */
		   {
			    if(!(NULL==(listnode::find_closed(open_list,sub_node2->row,sub_node2->collum))))
			   {
				   temp=listnode::find_closed(open_list,sub_node2->row,sub_node2->collum);
			   }
			   else
			   {
				   temp=listnode::find_closed(closed_list,sub_node2->row,sub_node2->collum);
			   }
			   if(sub_node2->g_n<temp->g_n)	// 若新的较小泽用新的替代旧的 */
			   {
				   temp->g_n=sub_node2->g_n;
				   temp->father=best_node;
				   if(!(NULL==(temp=listnode::find_closed(closed_list,sub_node2->row,sub_node2->collum))))
				   {	// 若在closed表中重新计算subnode的子孙节点的fn */
					   dg_n=temp->g_n-sub_node2->g_n;
					   listnode::son_fn(temp,dg_n);	// 重新计算subnode的子孙节点的fn  */
				   }    //从subnode中删除son即不宽展他
			   }
			   else											
			   {		//若原先的较小则放弃新的,即不扩展它
			   }
		   }
		}
	   if(a[best_node->row][best_node->collum-1]==0)//向左可走(可走的条件是没超出边界且为空,
		{  
		   list_node * sub_node3= listnode::create_node(best_node->row,best_node->collum-1,0);
		   list_node * temp=sub_node3;
		   sub_node3->g_n=best_node->g_n+1;
		   sub_node3->h_n=abs(sub_node3->row-s_g.x)+ abs(sub_node3->collum-s_g.y);
		   sub_node3->f_n=sub_node3->g_n+sub_node3->h_n;
		   if((NULL==(temp=listnode::find_closed(open_list,sub_node3->row,sub_node3->collum)))&&(NULL==(temp=listnode::find_closed(closed_list,sub_node3->row,sub_node3->collum))))
		   {
			   // 若节点不在closed或open表中设置sub-node指向best-node的指针
		     sub_node3->father=best_node;//用于寻找路径,倒着指回去
			 best_node->son3=sub_node3;
		     open_list = listnode::insert_node2(open_list, sub_node3);// 放入open表 
		   }
		   else	// 若节点在closed或open表中比较gn谁小留谁 
		   {
			    if(!(NULL==(listnode::find_closed(open_list,sub_node3->row,sub_node3->collum))))
			   {
				   temp=listnode::find_closed(open_list,sub_node3->row,sub_node3->collum);
			   }
			   else
			   {
				   temp=listnode::find_closed(closed_list,sub_node3->row,sub_node3->collum);
			   }
			   if(sub_node3->g_n<temp->g_n)	// 若新的较小泽用新的替代旧的 
			   {
				   temp->g_n=sub_node3->g_n;
				   temp->father=best_node;
				   if(!(NULL==(temp=listnode::find_closed(closed_list,sub_node3->row,sub_node3->collum))))
				   {//若在closed表中重新计算subnode的子孙节点的fn */
					   dg_n=temp->g_n-sub_node3->g_n;
					   listnode::son_fn(temp,dg_n);	// 重新计算subnode的子孙节点的fn  */
				   }//从subnode中删除son即不宽展他*/ 
			   }
			   else											
			   {	//若原先的较小则放弃新的,即不扩展它 */
			   }
		   }
		}
	   if(a[best_node->row-1][best_node->collum]==0)//向上可走(可走的条件是没超出边界且为空,
		{  
		   list_node * sub_node4= listnode::create_node(best_node->row-1,best_node->collum,0);
		   list_node * temp=sub_node4;
		   sub_node4->g_n=best_node->g_n+1;
		   sub_node4->h_n=abs(sub_node4->row-s_g.x)+ abs(sub_node4->collum-s_g.y);
		   sub_node4->f_n=sub_node4->g_n+sub_node4->h_n;
		   if((NULL==(temp=listnode::find_closed(open_list,sub_node4->row,sub_node4->collum)))&&(NULL==(temp=listnode::find_closed(closed_list,sub_node4->row,sub_node4->collum))))
		   {	//若节点不在closed或open表中设置sub-node指向best-node的指针 
		     sub_node4->father=best_node;//用于寻找路径,倒着指回去
			 best_node->son4=sub_node4;
		     open_list = listnode::insert_node2(open_list, sub_node4);	//放入open表 */
		   }
		   else	// 若节点在closed或open表中比较gn谁小留谁
		   {
			    if(!(NULL==(listnode::find_closed(open_list,sub_node4->row,sub_node4->collum))))
			   {
				   temp=listnode::find_closed(open_list,sub_node4->row,sub_node4->collum);
			   }
			   else
			   {
				   temp=listnode::find_closed(closed_list,sub_node4->row,sub_node4->collum);
			   }
			   if(sub_node4->g_n<temp->g_n)	//若新的较小泽用新的替代旧的 
			   {
				   temp->g_n=sub_node4->g_n;
				   temp->father=best_node;
				   if(!(NULL==(temp=listnode::find_closed(closed_list,sub_node4->row,sub_node4->collum))))
				   {		// 若在closed表中重新计算subnode的子孙节点的fn 
					   dg_n=temp->g_n-sub_node4->g_n;
					   listnode::son_fn(temp,dg_n);	// 重新计算subnode的子孙节点的fn  */
				   }		//从subnode中删除son即不宽展他 
			   }
			   else											
			   {			// 若原先的较小则放弃新的,即不扩展它 
			   }
		   }
		}
//	   open_list=link_list(open_list,sub_nodes);
//	   sub_node3->father=best_node;
//从open表中删除bestnode,放入closed表 
	   listnode::del_node2(open_list,best_node);
	   closed_list=listnode::insert_node2(closed_list,best_node);

⌨️ 快捷键说明

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