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

📄 eludeobstacleview.cpp

📁 用C++开发的一个人工神经网络小游戏
💻 CPP
📖 第 1 页 / 共 3 页
字号:
void CEludeObstacleView::OnSaveMap() 
{
	// TODO: Add your command handler code here
	FileHandle.SaveCurrentMap();
}

void CEludeObstacleView::OnSaveMap1()
{
	FileHandle.ReadMap(1);
	updateObstacleDC();
	Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
	Invalidate();
}

void CEludeObstacleView::OnSaveMap2()
{
	FileHandle.ReadMap(2);
	updateObstacleDC();
	Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
	Invalidate();
}

void CEludeObstacleView::OnSaveMap3()
{
	FileHandle.ReadMap(3);
	updateObstacleDC();
	Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
	Invalidate();
}

void CEludeObstacleView::OnSaveMap4()
{
	FileHandle.ReadMap(4);
	updateObstacleDC();
	Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
	Invalidate();
}

void CEludeObstacleView::OnSaveMap5()
{
	FileHandle.ReadMap(5);
	updateObstacleDC();
	Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
	Invalidate();
}

void CEludeObstacleView::showTheGenAlgData()
{
	CDC *pDC = GetDC();
	OnEraseBkgnd(pDC);
	GenAlg.outputTheData(pDC);

	ReleaseDC(pDC);
}

void CEludeObstacleView::EnableMenuItem(UINT uID, bool boEnable)
{
	CWnd* pParent = GetParent();
	CMenu* pMenu = pParent->GetMenu();
	int nResult;
	if(boEnable)
		nResult = pMenu->EnableMenuItem(uID, MF_BYCOMMAND | MF_ENABLED);
	else
		nResult = pMenu->EnableMenuItem(uID, MF_BYCOMMAND | MF_GRAYED | MF_DISABLED);
	//DrawMenuBar();
	Invalidate();
}

void CEludeObstacleView::OnDefaultMap1() 
{
	// TODO: Add your command handler code here
	ObstacleMap[6].init(200,250,40);
	ObstacleMap[5].init(150,50,60);
	ObstacleMap[7].init(350,130,20);
	ObstacleMap[0].init(300,350,30);
	ObstacleMap[1].init(450,180,40);
	ObstacleMap[8].init(530,320,30);
	ObstacleMap[2].init(600,50,30);
	ObstacleMap[3].init(700,350,40);
	ObstacleMap[4].init(800,150,60);
	g_NumObstacle = 9;
	updateObstacleDC();
	Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
	Invalidate();
}

void CEludeObstacleView::OnDefaultMap2() 
{
	// TODO: Add your command handler code here
	
	ObstacleMap[0].init(225,121,53);
	ObstacleMap[1].init(228,282,48);
	ObstacleMap[2].init(469,16,56);
	ObstacleMap[3].init(471,188,42);
	ObstacleMap[4].init(473,369,63);
	ObstacleMap[5].init(676,94,58);
	ObstacleMap[6].init(679,286,45);
	g_NumObstacle = 7;
	updateObstacleDC();
	Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
	Invalidate();
}

void CEludeObstacleView::OnDefaultMap3() 
{
	// TODO: Add your command handler code here
	ObstacleMap[0].init(154,97,23);
	ObstacleMap[1].init(154,243,25);
	ObstacleMap[2].init(326,169,23);
	ObstacleMap[3].init(326,21,23);
	ObstacleMap[4].init(461,94,25);
	ObstacleMap[5].init(458,259,26);
	ObstacleMap[6].init(597,173,27);
	ObstacleMap[7].init(595,342,24);
	ObstacleMap[8].init(716,100,15);
	ObstacleMap[9].init(705,270,20);
	ObstacleMap[10].init(821,22,23);
	ObstacleMap[11].init(809,184,23);
	ObstacleMap[12].init(814,344,24);
	ObstacleMap[13].init(323,341,24);
	ObstacleMap[14].init(608,13,22);
	g_NumObstacle = 15;	
	updateObstacleDC();
	Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
	Invalidate();
}

void CEludeObstacleView::OnDefaultMap4() 
{
	// TODO: Add your command handler code here
	ObstacleMap[0].init(332,19,158);
	ObstacleMap[1].init(724,329,168);
	ObstacleMap[2].init(1129,90,147);
	ObstacleMap[3].init(1527,295,157);
	g_NumObstacle = 4;
	updateObstacleDC();
	Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
	Invalidate();
}

void CEludeObstacleView::DrawStar(CDC *pDC)
{
	static position[600];
	static show = 0;
	if(show%10 == 0)
	{
		for(int i = 0;i < 100;i++)
		{
			position[i] = rand()%g_MapWidth;
			position[i*2] = rand()%g_MapHeight;
			pDC->SetPixel(position[i], position[i*2], RGB(255,240,rand()%255));
			pDC->SetPixel(position[i+1], position[i*2], RGB(255,240,rand()%255));
			pDC->SetPixel(position[i], position[i*2+1], RGB(255,240,rand()%255));
			pDC->SetPixel(position[i+1], position[i*2+1], RGB(255,240,rand()%255));
		}
		for(i = 100;i < 300;i++)
		{
			position[i] = rand()%g_MapWidth;
			position[i*2] = rand()%g_MapHeight;
			pDC->SetPixel(position[i], position[i*2], RGB(255,240,rand()%255));
		}
		show -= 10;
	}
	else
	{	
		for(int i = 0;i < 100;i++)
		{
			pDC->SetPixel(position[i], position[i*2], RGB(255,240,rand()%255));
			pDC->SetPixel(position[i+1], position[i*2], RGB(255,240,rand()%255));
			pDC->SetPixel(position[i], position[i*2+1], RGB(255,240,rand()%255));
			pDC->SetPixel(position[i+1], position[i*2+1], RGB(255,240,rand()%255));
		}
		for(i = 100;i < 300;i++)
		{
			pDC->SetPixel(position[i], position[i*2], RGB(255,240,rand()%255));
		}
	}
	show++;
}

void CEludeObstacleView::OnSetParameter()
{
	// TODO: Add your command handler code here
	//m_DlgChangeParameter.init();
	//m_DlgChangeParameter.DoModal();
	//m_prop1.init();
	CPropSheet m_propSheet("参数设置");
	m_propSheet.DoModal();
}

void CEludeObstacleView::updateObstacleDC()
{
	CDC ImageDC;
	CBitmap ForeBMP;
	BITMAP bm;
	ForeBMP.LoadBitmap(IDB_BITMAP2);
	ForeBMP.GetBitmap(&bm);
	ImageDC.CreateCompatibleDC(&ObstacleDC);
	ImageDC.SelectObject(&ForeBMP);
	
	ObstacleDC.DeleteDC();
	ObstacleDC.CreateCompatibleDC(&Mem);
	CBitmap Bmp;
	Bmp.CreateCompatibleBitmap(&Mem, g_MapWidth,g_MapHeight);
	ObstacleDC.SelectObject(&Bmp);


	
	CRect r(0,0,g_MapWidth,g_MapHeight);
	//GetClientRect(&r);
	CBrush Brush_Bak(RGB(255,255,255));
	ObstacleDC.SelectObject(Brush_Bak);
	ObstacleDC.FillRect(&r,&Brush_Bak);
	
	
	
	Mem.SetBkMode(TRANSPARENT);
	/*
	CPen pen,pen2,*p_pen;
	pen.CreatePen(PS_SOLID,1,RGB(4,197,206));
	p_pen = pDC->SelectObject(&pen);

	CBrush bkBrush(RGB(10,31,105));
	CBrush *pOldBrush = pDC->SelectObject(&bkBrush);
	*/

	for(int i = 0;i < g_NumObstacle;i++)
	{
		int x = ObstacleMap[i].center.x;
		int y = ObstacleMap[i].center.y;
		double r = ObstacleMap[i].radius;

		TransparentBlt(ObstacleDC.GetSafeHdc(),x - r,y - r,2 * r,2 * r,ImageDC.GetSafeHdc(),0,0,bm.bmWidth,bm.bmHeight,RGB(0xff,0xff,0xff));
		//StretchBlt(pDC->GetSafeHdc(),x - r,y - r,2 * r,2 * r,ImageDC.GetSafeHdc(),0,0,bm.bmWidth,bm.bmHeight,RGB(0xff,0xff,0xff));
		/*
		pDC->MoveTo(x + r ,y);
		for(int i = 1;i < 30;i++)
		{
			double angle = PI/15*i;
			pDC->LineTo(cos(angle) * r + x, sin(angle) * r + y);
		}
		pDC->LineTo(x + r ,y);
		
		CRect rcBounds(x - r,y - r,x + r,y + r);
		//CRect rcBounds(100,100,200,200);
		pDC->Ellipse(rcBounds);
		*/
	}
	ImageDC.DeleteDC();
}

void CEludeObstacleView::updateAerocraftDC()
{
	CDC ImageDC;
	CBitmap ForeBMP;
	ForeBMP.LoadBitmap(IDB_BITMAP3);
	AerocraftDC.CreateCompatibleDC(&Mem);
	AerocraftDC.SelectObject(&ForeBMP);
}

void CEludeObstacleView::showTheAerocraft(CDC *pDC)
{
	CPen pen;
	pen.CreatePen(PS_SOLID,2,RGB(241,219,141));
	pDC->SelectObject(&pen);
	
	
	double size = g_AerocraftSize * 6;
	int drawX;
	if(Aerocraft.m_vPos.x <= g_WindowsWidth/2)
	{
		drawX = Aerocraft.m_vPos.x;
	}
	else if(Aerocraft.m_vPos.x >= g_MapWidth - g_WindowsWidth/2)
	{
		drawX = g_WindowsWidth - g_MapWidth + Aerocraft.m_vPos.x;
	}
	else
	{
		drawX = g_WindowsWidth/2;
	}

	Aerocraft.showTheJet(pDC,drawX);
	TransparentBlt(pDC->GetSafeHdc(),drawX - size,Aerocraft.m_vPos.y - size,size*2,size*2,AerocraftDC.GetSafeHdc(),0,0,312,312,RGB(0xff,0xff,0xff));
}

void CEludeObstacleView::DrawArrowhead(CDC *pDC,int category)
{
	int centerX = 700;
	int centerY = 200;
	if(category == 1)
	{
		CPen pen,pen2,*p_pen;
		pen.CreatePen(PS_SOLID,1,RGB(4,197,206));
		p_pen = pDC->SelectObject(&pen);
		pDC->MoveTo(-40 + centerX,0 + centerY);
		pDC->LineTo(-30 + centerX,10 + centerY);
		pDC->LineTo(-30 + centerX,5 + centerY);
		pDC->LineTo(-10 + centerX,5 + centerY);
		pDC->LineTo(-10 + centerX,-5 + centerY);
		pDC->LineTo(-30 + centerX,-5 + centerY);
		pDC->LineTo(-30 + centerX,-10 + centerY);
		pDC->LineTo(-40 + centerX,-0 + centerY);
	}
}

DWORD WINAPI ThreadForTrainNetWork(
  LPVOID lpParameter   // thread data
)
{
	((CEludeObstacleView *)lpParameter)->TrainTheNetwork();
	return 0;
}

void CEludeObstacleView::OnTrainNetwork()
{
	// TODO: Add your command handler code here
	
	HANDLE hThread;
	CEludeObstacleView * pView = (CEludeObstacleView *)((CMainFrame*)AfxGetApp()->m_pMainWnd)->GetActiveView(); 

	hThread = CreateThread(NULL,0,ThreadForTrainNetWork,pView,0,NULL);
	CloseHandle(hThread);
	
}

void CEludeObstacleView::showTheWGenAlgData()
{
	CDC *pDC = GetDC();
	g_ShowWGenAlgDate = 1;
	OnEraseBkgnd(pDC);
	g_ShowWGenAlgDate = 0;
	ReleaseDC(pDC);
}

void CEludeObstacleView::OnDemoNetwork()
{
	// TODO: Add your command handler code here
	//不可以设置障碍
	m_setMode = 0;
	//指出感应到的星球
	ifPointOut = 1;

	SetTimer(4,25/g_DemoRate2,NULL);
	Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
	NeuralNet.PutWeights(m_weight);
	//用于初始化,距离数组
	ifCollide();
	Invalidate();
	m_end = 0;
}



double CEludeObstacleView::CalculateFitnessForANN()
{
	return 1000 + Aerocraft.m_vPos.x - abs(Aerocraft.m_vVelocity.x) * 50 - abs(Aerocraft.m_vVelocity.y) * 20;// - Aerocraft.m_vPos.y/3;//+ m_theShortestDistance/20;
}

void CEludeObstacleView::TrainTheNetwork()
{
	srand( (unsigned)time( NULL ) );
	
	//不可以设置障碍
	m_setMode = 0;
	
	
	NeuralNet.CreateNet();
	
	WGenAlg.init(g_Wpopsize,
		g_WdMutationRate,
		g_WdCrossoverRate,
		NeuralNet.m_Weights);
		
	//vector<SGenome> population;
	m_Wpopulation.clear();
	
	vector<double> newGenome;


	//进化的初代
	//对每一个基因作处理(每一条基因代表神经网络的一套权值)
	for(int i = 0;i < g_Wpopsize;i++)
	{		
		NeuralNet.CreateNet();
	
		newGenome = NeuralNet.GetWeights();

		//把权值基因放到人口里面
		m_Wpopulation.push_back(SWGenome(newGenome,0));

	}
		
	//后续世代
	for(int Generation = 1;Generation <= g_WGeneration;Generation++)
	{
		for(int t = 0;t < 4;t++)
		{			
			if(t == 0)
			{
				ObstacleMap[6].init(200,250,40);
				ObstacleMap[5].init(150,50,60);
				ObstacleMap[7].init(350,130,20);
				ObstacleMap[0].init(300,350,30);
				ObstacleMap[1].init(450,180,40);
				ObstacleMap[8].init(530,320,30);
				ObstacleMap[2].init(600,50,30);
				ObstacleMap[3].init(700,350,40);
				ObstacleMap[4].init(800,150,60);
				g_NumObstacle = 9;
			}
			else if(t == 1)
			{
				ObstacleMap[0].init(225,121,53);
				ObstacleMap[1].init(228,282,48);
				ObstacleMap[2].init(469,16,56);
				ObstacleMap[3].init(471,188,42);
				ObstacleMap[4].init(473,369,63);
				ObstacleMap[5].init(676,94,58);
				ObstacleMap[6].init(679,286,45);
				g_NumObstacle = 7;
			}
			else if(t == 2)
			{
				ObstacleMap[0].init(154,97,23);
				ObstacleMap[1].init(154,243,25);
				ObstacleMap[2].init(326,169,23);
				ObstacleMap[3].init(326,21,23);
				ObstacleMap[4].init(461,94,25);
				ObstacleMap[5].init(458,259,26);
				ObstacleMap[6].init(597,173,27);
				ObstacleMap[7].init(595,342,24);
				ObstacleMap[8].init(716,100,15);
				ObstacleMap[9].init(705,270,20);
				ObstacleMap[10].init(821,22,23);
				ObstacleMap[11].init(809,184,23);
				ObstacleMap[12].init(814,344,24);
				ObstacleMap[13].init(323,341,24);
				ObstacleMap[14].init(608,13,22);
				g_NumObstacle = 15;
			}
			else if(t == 3)
			{
				ObstacleMap[0].init(332,19,158);
				ObstacleMap[1].init(724,329,168);
				ObstacleMap[2].init(1129,90,147);
				ObstacleMap[3].init(1527,295,157);
				g_NumObstacle = 4;
			}


			
			//对每一个基因作处理(每一条基因代表神经网络的一套权值)
			for(int i = 0;i < g_Wpopsize;i++)
			{
				NeuralNet.PutWeights(m_Wpopulation[i].vecWeights);
				
				
				//Aerocraft.init(rand()%50+10,g_MapHeight/2 + rand()%200 - 100,0,g_AerocraftSize);
				Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
				
				//Aerocraft.init(20,200,0,g_AerocraftSize);
				//防止神经网络总是保持在某个地方不动
				int times = 0;
				vector<double> input;
				vector<double> output;
				int control = 0;
				while(!ifCollide())
				{
					int action;
					
					
					input.clear();			
					input.push_back(globe_UnitaryRate/(g_MapHeight - Aerocraft.m_vPos.y));
					input.push_back(globe_UnitaryRate/(Aerocraft.m_vPos.y));
					input.push_back(Aerocraft.m_vVelocity.x);
					input.push_back(Aerocraft.m_vVelocity.y);
					for(int j = 0;j < globe_NumInput/2 - 2;j++)
					{
						input.push_back(globe_UnitaryRate/m_distanceX[j]);
						input.push_back(globe_UnitaryRate/m_distanceY[j]);
					}
					
					vector<double> output = NeuralNet.Update(input);
					//取输出值最大的输出位置所代表的action值
					double temp = output[0];
					action = 0;
					for(int k = 1;k < 5;k++)
					{
						////////
						double X1 = output[k];
						//////////
						
						if(output[k] > temp)
						{
							temp = output[k];
							action = k;
						}
					}
					
					//在实际环境中演绎
					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(Aerocraft.m_vPos.x + g_AerocraftRadius * Aerocraft.m_dScale > g_MapWidth)
					{
						//AfxMessageBox("呵呵,小事一桩,我保证我们能脱险~~");
						//m_weight = NeuralNet.GetWeights();
						//return;
						control = 1;
						break;
					}
					
					times++;
					if(times > 80 && Aerocraft.m_vPos.x < 80){break;}
					if(times > 240 && Aerocraft.m_vPos.x < 400){break;}
					if(times > 900){break;}
				}
				
				//计算适应性函数
				//double dFitness =
				
				if(control == 0){m_Wpopulation[i].dFitness += CalculateFitnessForANN() + times;}
				else{m_Wpopulation[i].dFitness += 3000 + times + (Aerocraft.m_vVelocity.x) * 60;}
				/*
				newGenome = NeuralNet.GetWeights();
				//把权值基因放到人口里面
				m_Wpopulation[i] = SWGenome(newGenome,dFitness);
				*/
			}
		}
		
		WGenAlg.Epoch(m_Wpopulation);
		showTheWGenAlgData();
	}

	m_weight = WGenAlg.m_vecPop[g_Wpopsize-1].vecWeights;

	OnDefaultMap1();
	showTheWGenAlgData();

	CString s;
	s.Format("训练完成,得分为%lf!",WGenAlg.m_vecPop[g_Wpopsize-1].dFitness);
	AfxMessageBox(s);
}

⌨️ 快捷键说明

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