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

📄 eludeobstacleview.cpp

📁 用C++开发的一个人工神经网络小游戏
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		{
			Aerocraft.updateTheVelocity2();
			Aerocraft.m_iJetDirection = 2;
			ifPress = 0;
		}
	}
	//Invalidate();
	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CEludeObstacleView::showTheObstacle(CDC* pDC)
{

	

	//计算出障碍物懂的偏移量。
	int distance;
	if(Aerocraft.m_vPos.x <= g_WindowsWidth/2)
	{
		distance = 0;
	}
	else if(Aerocraft.m_vPos.x >= g_MapWidth - g_WindowsWidth/2)
	{
		distance = g_MapWidth - g_WindowsWidth;
	}
	else
	{
		distance = Aerocraft.m_vPos.x - g_WindowsWidth/2;
	}
	//pDC->BitBlt(0,0,g_MapWidth,g_MapHeight,&ObstacleDC,0,0,SRCCOPY);
	TransparentBlt(pDC->GetSafeHdc(),-distance,0,g_MapWidth,g_MapHeight,ObstacleDC.GetSafeHdc(),0,0,g_MapWidth,g_MapHeight,RGB(0xff,0xff,0xff));

	if(ifPointOut)
	{
		for(int i = 0;i < globe_NumInput/2 - 2;i++)
		{
			//Mem.SetPixel(ObstacleMap[m_ShortStar[i]].center.x , ObstacleMap[m_ShortStar[i]].center.y,  RGB(255,240,0));
			int x = ObstacleMap[m_ShortStar[i]].center.x - distance;
			int y = ObstacleMap[m_ShortStar[i]].center.y;
			int r = ObstacleMap[m_ShortStar[i]].radius;
			CRect rcBounds(x - r,y - r,x + r,y + r);
			//CRect rcBounds(100,100,200,200);
			//Mem.Ellipse(rcBounds);
	
			if(ifShowSenceStar == 0)
			{
				CPen pen,pen2,*p_pen;
				pen.CreatePen(PS_SOLID,3,RGB(117,244,255));
				p_pen = pDC->SelectObject(&pen);
				
				
				pDC->MoveTo(x + r ,y);
				for(int j = 1;j < 30;j++)
				{
					double angle = PI/15*j;
					pDC->LineTo(cos(angle) * r + x, sin(angle) * r + y);
				}
				pDC->LineTo(x + r ,y);
				//pDC->SelectObject(p_pen);
				
				
				x = Aerocraft.m_vPos.x + m_distanceX[i] - distance;
				y = Aerocraft.m_vPos.y + m_distanceY[i];
				CRect rcBounds2(x - 4,y - 4,x + 4,y + 4);
				//CRect rcBounds2(m_distanceX[i] + 100,m_distanceX[i] + 100,m_distanceX[i] + 120,m_distanceX[i] + 120);
				//pDC->SetBkMode(TRANSPARENT);
				Mem.Ellipse(rcBounds2);
				
				
				pen.CreatePen(PS_DASH,1,RGB(255,255,0));
				p_pen = pDC->SelectObject(&pen);
				pDC->MoveTo(x, 0);
				pDC->LineTo(x, g_WindowsHeight);
				
				pDC->MoveTo(0, y);
				pDC->LineTo(g_WindowsWidth, y);
			}
		}

	}
	
}

//如果碰撞了就返回1
int CEludeObstacleView::ifCollide()
{
	//memset(m_distanceX,9999,10);
	//memset(m_distanceY,9999,10);
	
	for(int t = 0;t < 10;t++)
	{
		m_distanceX[t] = 99999;
		m_distanceY[t] = 99999;
	}
	/**/

	double localShortestDistance = 0;
	for(int i = 0;i < g_NumObstacle;i++)
	{
		int dx = ObstacleMap[i].center.x - Aerocraft.m_vPos.x;
		int dy = ObstacleMap[i].center.y - Aerocraft.m_vPos.y;
		//距离的平方
		double distance = dx * dx + dy * dy;

	
		if(localShortestDistance > distance)
		{	
			localShortestDistance = distance;
		}
		if(distance <= (ObstacleMap[i].radius + g_AerocraftRadius * Aerocraft.m_dScale) * (ObstacleMap[i].radius + g_AerocraftRadius * Aerocraft.m_dScale))
		{
			return 1;
		}
		
		double wholeDistance = sqrt(distance);
		double realDistance = wholeDistance - ObstacleMap[i].radius;
		for(int j = 0;j < globe_NumInput/2 - 2;j++)
		{
			if(realDistance * realDistance < m_distanceX[j] * m_distanceX[j] + m_distanceY[j] * m_distanceY[j])
			{
				for(int k = globe_NumInput/2 - 2 - 1;k > j;k--)
				{
					m_ShortStar[k] = m_ShortStar[k-1];
					m_distanceX[k] = m_distanceX[k-1];
					m_distanceY[k] = m_distanceY[k-1];
				}
				m_ShortStar[j] = i;
				m_distanceX[j] = (wholeDistance - ObstacleMap[i].radius)/wholeDistance * dx;//dx有正负之分,所以包含了方向
				m_distanceY[j] = (wholeDistance - ObstacleMap[i].radius)/wholeDistance * dy;//dy有正负之分,所以包含了方向				
				break;
			}
		}
	}

	for(int j = 0;j < globe_NumInput/2 - 2;j++)
	{
		int realDistance = m_distanceX[j] * m_distanceX[j] + m_distanceY[j] * m_distanceY[j];
		if(realDistance > 360000 || (realDistance > 40000 && m_distanceX[j] < 0))
		{
			m_distanceY[j] = 99999;
		}
	}
	
	if(Aerocraft.m_vPos.y < localShortestDistance)
	{
		localShortestDistance = Aerocraft.m_vPos.y * Aerocraft.m_vPos.y;
	}
	else if(g_MapHeight - Aerocraft.m_vPos.y < localShortestDistance)
	{
		localShortestDistance = (g_MapHeight - Aerocraft.m_vPos.y) * (g_MapHeight - Aerocraft.m_vPos.y);
	}

	if(Aerocraft.m_vPos.x - g_AerocraftRadius * Aerocraft.m_dScale < 0
		|| Aerocraft.m_vPos.y - g_AerocraftRadius * Aerocraft.m_dScale < 0
		|| Aerocraft.m_vPos.y + g_AerocraftRadius * Aerocraft.m_dScale > g_MapHeight
		)
	{
		return 1;
	}

	m_theShortestDistance += localShortestDistance;

	return 0;
}

void CEludeObstacleView::OnStartGenAlg() 
{
	// TODO: Add your command handler code here
	
	srand( (unsigned)time( NULL ) );

	//不可以设置障碍
	m_setMode = 0;
	

	

	GenAlg.init(globe_popsize,
                 globe_dMutationRate,
                 globe_dCrossoverRate,
                 globe_numGen);

	//vector<SGenome> population;
	m_population.clear();
	m_population = GenAlg.m_vecPop;

	double x1 = m_population[3].action[1];
	double x2 = m_population[3].action[2];
	double x3 = m_population[3].action[3];
	
	int ifBreak = 0;
	for(int Generation = 0;Generation <= globe_Generation;Generation++)
	{
		for(int i=0;i<globe_popsize;i++)//里面是对每一条基因组操作
		{
			Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
			m_theShortestDistance = 0;
			for(int j = 0;j < globe_numGen;j++)//里面是对每条基因组的一个基因操作
			{
				ifBreak = 0;
				int action = m_population[i].action[j];
				for(int k = 0;k < m_population[i].time[j];k++)
				{
					//action = 4;
					if(action == 0){}
					else if(action == 1){Aerocraft.updateTheVelocity2();}
					else if(action == 2){Aerocraft.updateTheVelocity3();}
					else if(action == 3){Aerocraft.updateTheVelocity4();}
					else if(action == 4){Aerocraft.updateTheVelocity5();}
					else 
					{						
						char buf[4];
						sprintf(buf,"action%d i%d j%d 你的行动数不对!!!(OnStartGenAlg)",action,i,j);

						AfxMessageBox(buf);
						return;
					}
					Aerocraft.updateTheVelocity1();
					Aerocraft.updateThePosition();
					if(ifCollide())//碰撞就不再测试后续基因
					{
						ifBreak = 1;
						break;
					}
					if(Aerocraft.m_vPos.x + g_AerocraftRadius * Aerocraft.m_dScale > g_MapWidth)
					{
						SGenome temp(m_population[i].action,m_population[i].time,g_MapWidth + 1);
						m_ControlGen = temp;
						AfxMessageBox("呵呵,小事一桩,我保证我们能脱险~~");
						EnableMenuItem(IDM_Demo,1);
						return;
					}
					
				}
				
				if(ifBreak==1){break;}
			}
			//计算适应性
			m_population[i].dFitness = CalculateFitness();
			
		}
		GenAlg.Epoch(m_population);
		//显示遗传算法相关数据
		showTheGenAlgData();
	}
	SGenome temp(GenAlg.m_vecPop[globe_popsize-1].action,
		GenAlg.m_vecPop[globe_popsize-1].time,0);
	m_ControlGen = temp;

	EnableMenuItem(IDM_Demo,1);
	
	AfxMessageBox("呜~~ 我投降了!!!似乎我们这次劫数难逃了~~");
}	

void CEludeObstacleView::OnDemo()
{
	// TODO: Add your command handler code her

	//不可以设置障碍
	m_setMode = 0;

	SetTimer(2,25/g_DemoRate2,NULL);
	Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
	Invalidate();
	m_end = 0;
}

void CEludeObstacleView::OnPlayerControl()
{
	// TODO: Add your command handler code here

		AfxMessageBox("请按下Enter键开始游戏(提示:按住方向键不松开,加速效果更好.)祝你好运!!!");

	//不可以设置障碍
	m_setMode = 0;
	ifPointOut = 0;

	SetTimer(1,25,NULL);
	Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
	Invalidate();
	m_end = 0;
}

void CEludeObstacleView::OnStartStepGenAlg() 
{
	// TODO: Add your command handler code here
	
	//不可以设置障碍
	m_setMode = 0;

	ifStepByStep = 1;

	srand( (unsigned)time( NULL ) );

	GenAlg.init(globe_popsize,
                 globe_dMutationRate,
                 globe_dCrossoverRate,
                 globe_numGen);

	m_population.clear();
	m_population = GenAlg.m_vecPop;
	ThinkItStepByStep(m_population);

	SetTimer(3,25/g_DemoRate,NULL);
	Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
	Invalidate();
	m_end = 0;
	//AfxMessageBox("呜~~ 我投降了!!!");
}

int CEludeObstacleView::ThinkItStepByStep(vector<SGenome> &population)
{
	int ifBreak = 0;
	for(int i=0;i<globe_popsize;i++)//里面是对每一条基因组操作
	{
		Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
		m_theShortestDistance = 0;
		for(int j = 0;j < globe_numGen;j++)//里面是对每条基因组的一个基因操作
		{
			ifBreak = 0;
			int action = population[i].action[j];
			
			for(int k = 0;k < population[i].time[j];k++)
			{
				//action = 4;
				if(action == 0){}
				else if(action == 1){Aerocraft.updateTheVelocity2();}
				else if(action == 2){Aerocraft.updateTheVelocity3();}
				else if(action == 3){Aerocraft.updateTheVelocity4();}
				else if(action == 4){Aerocraft.updateTheVelocity5();}
				else 
				{
					char buf[4];
					sprintf(buf,"action%d i%d j%d 你的行动数不对!!!(StepByStep)",action,i,j);
					AfxMessageBox(buf);
					return 0;
				}
				Aerocraft.updateTheVelocity1();
				Aerocraft.updateThePosition();
				if(Aerocraft.m_vPos.x + g_AerocraftRadius * Aerocraft.m_dScale > g_MapWidth)
				{
					SGenome temp(population[i].action,population[i].time,g_MapWidth + 1);
					m_ControlGen = temp;
					EnableMenuItem(IDM_Demo,1);
					//AfxMessageBox("呵呵,我会玩啦! 来,让我教教你!");
					return 1;
				}
				if(ifCollide())//碰撞就不再测试后续基因
				{
					ifBreak = 1;
					break;
				}
			}
			if(ifBreak==1){break;}
		}
		//计算适应性
		population[i].dFitness = CalculateFitness();
	}
	//把最好的基因作为控制基因
	SGenome temp(GenAlg.m_vecPop[globe_popsize-1].action,
		GenAlg.m_vecPop[globe_popsize-1].time,0);
	m_ControlGen = temp;
	EnableMenuItem(IDM_Demo,1);
	GenAlg.Epoch(population);
	return 0;
}

inline double CEludeObstacleView::CalculateFitness()
{
	return Aerocraft.m_vPos.x;
}

void CEludeObstacleView::OnSetObstacle()
{
	// TODO: Add your command handler code here
	g_NumObstacle = 0;
	updateObstacleDC();
	Invalidate();
	m_setMode = 1;
	Aerocraft.m_vPos.x = g_WindowsWidth/2;
}

void CEludeObstacleView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(m_setMode == 1)
	{
		ifPressLButton = 1;
		
		g_NumObstacle ++;

		ObstacleMap[g_NumObstacle-1].center.x = point.x + Aerocraft.m_vPos.x - g_WindowsWidth/2;
		ObstacleMap[g_NumObstacle-1].center.y = m_centerY = point.y;
		m_centerX = point.x;
	}
	CView::OnLButtonDown(nFlags, point);
}

void CEludeObstacleView::OnRButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	CView::OnRButtonUp(nFlags, point);
}

void CEludeObstacleView::OnRButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	CView::OnRButtonDown(nFlags, point);
}

void CEludeObstacleView::OnCancelMode() 
{
	CView::OnCancelMode();
	
	// TODO: Add your message handler code here
	
}

void CEludeObstacleView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(m_setMode == 1)
	{
		ifPressLButton = 0;
		ObstacleMap[g_NumObstacle-1].radius = sqrt((m_centerX - point.x) * (m_centerX - point.x) + (m_centerY - point.y) * (m_centerY - point.y));
		updateObstacleDC();
		Invalidate();
	}
	CView::OnLButtonUp(nFlags, point);
}

void CEludeObstacleView::OnCaptureChanged(CWnd *pWnd) 
{
	// TODO: Add your message handler code here
	
	CView::OnCaptureChanged(pWnd);
}

void CEludeObstacleView::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(m_setMode == 1)
	{
		if(ifPressLButton == 1)
		{
			ObstacleMap[g_NumObstacle-1].radius = sqrt((m_centerX - point.x) * (m_centerX - point.x) + (m_centerY - point.y) * (m_centerY - point.y));
			updateObstacleDC();
			Invalidate();
		}
	}
	if(m_setMode == 1)
	{
		if(point.x > g_WindowsWidth - 15)
		{
			Aerocraft.m_vPos.x += 30;
			if(Aerocraft.m_vPos.x > g_MapWidth - g_WindowsWidth/2)
				Aerocraft.m_vPos.x = g_MapWidth - g_WindowsWidth/2;
			else if(Aerocraft.m_vPos.x < g_WindowsWidth/2)
				Aerocraft.m_vPos.x = g_WindowsWidth/2;
		}
		else if(point.x < 15)
		{
			Aerocraft.m_vPos.x -= 30;
			if(Aerocraft.m_vPos.x < g_WindowsWidth/2)
				Aerocraft.m_vPos.x = g_WindowsWidth/2;
			else if(Aerocraft.m_vPos.x > g_MapWidth - g_WindowsWidth/2)
				Aerocraft.m_vPos.x = g_MapWidth - g_WindowsWidth/2;
		}
		Invalidate();
	}
	CView::OnMouseMove(nFlags, point);
}



BOOL CEludeObstacleView::OnEraseBkgnd(CDC* pDC)
{
	// TODO: Add your message handler code here and/or call default

	////创建一个DC载入背景,然后在如背景图,然后把背景画到另外一个DC上
	CDC Mem2;
	CBitmap bm2;
	BITMAP bmMetric;
	
	bm2.LoadBitmap(IDB_BITMAP1);

	bm2.GetBitmap(&bmMetric);
	Mem2.CreateCompatibleDC(&Mem);
	Mem2.SelectObject(bm2);
	Mem.StretchBlt(0,0,g_WindowsWidth,g_WindowsHeight,&Mem2,0,0,650,300,SRCCOPY);
	Mem2.DeleteDC();
	////

	/*
	CDC ImageDC;
	CBitmap ForeBMP;
	BITMAP bm;
	ForeBMP.LoadBitmap(IDB_BITMAP2);
	ForeBMP.GetBitmap(&bm);
	ImageDC.CreateCompatibleDC(pMem);
	ImageDC.SelectObject(&ForeBMP);
	
	TransparentBlt(pMem->GetSafeHdc(),0,0,bm.bmWidth,bm.bmHeight,ImageDC.GetSafeHdc(),0,0,bm.bmWidth,bm.bmHeight,RGB(0xff,0xff,0xff));
	
	ImageDC.DeleteDC();
	*/

	//(2)进行图形绘制
	//pMem->LineTo(...);  //进行绘图处理
	
	//SetBkColor(pDC, RGB(0, 0, 0));
	/*
	RECT r;
	GetClientRect(&r);
	CBrush Brush_Bak(RGB(0,0,0));
	CBrush *oldBrush=pDC->SelectObject(&Brush_Bak);
	pMem->SelectObject(Brush_Bak);
	pMem->FillRect(&r,&Brush_Bak);
	*/

	DrawStar(&Mem);


	showTheObstacle(&Mem);
	
	
	
	if(m_setMode != 1)
	{
		showTheAerocraft(&Mem);
	}
	//如果进去一步一步显示状态
	if(ifStepByStep)
	{
		GenAlg.outputTheData(&Mem);
		m_ControlStepByStep = 0;
	}
	
	if(g_ShowWGenAlgDate)
	{
		WGenAlg.outputTheData(&Mem);
	}

	//(3)拷贝到屏幕
	pDC->BitBlt(0,0,g_MapWidth,g_MapHeight,&Mem,0,0,SRCCOPY);

	

	return TRUE;

	//return CView::OnEraseBkgnd(pDC);
}

void CEludeObstacleView::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	// TODO: Add your message handler code here
	
}

⌨️ 快捷键说明

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