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

📄 eludeobstacleview.cpp

📁 用C++开发的一个人工神经网络小游戏
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// EludeObstacleView.cpp : implementation of the CEludeObstacleView class
//

#include "stdafx.h"
#include "EludeObstacle.h"

#include "EludeObstacleDoc.h"
#include "EludeObstacleView.h"
#include "Aerocraft.h"
#include <mmsystem.h>
#include "MainFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


int g_WindowsWidth = 900;
int g_WindowsHeight = 400;

int g_MapWidth = 1800;
int g_MapHeight = 400;

int start_x = 20;
int start_y = 200;

int ifShowDirection = 0;
int ifShowSenceStar = 0;
int ifShowDiagram = 0;
int g_ShowWGenAlgDate = 0;

double PI = 3.14159265358979;

double g_GRAVITY = 2;
double g_TimeElapsed = 0.040;
double g_SCALING_FACTOR = 30;
double g_JetAcceleration = 5;
double g_AerocraftSize = 2.5;

double g_RotationRate = 0.2;
 
int g_NumObstacle = 9;


double g_AerocraftRadius = 4.5;
double g_DemoRate = 5;//机器一步一步想的时候的演示速度
double g_DemoRate2 = 1;//机器想好后的演示速度

/////////////////////////////////////

//double globe_dActivationResponse = 0.1;

int globe_dMaxPerturbation = 2;//行动时间变异的范围

int globe_iNumElite = 4;


double globe_dCrossoverRate = 0.2;
double globe_dMutationRate = 0.5;//对于基因时间变异的概率
//double globe_dBigMutationRate = 0.2;//对于基因组的概率
double globe_dMutationActionRate = 0.1;//对于基因行动变异的概率
double globe_dMutationInsert = 0.2;//对基因中随机插入一些动作的概率
int globe_dMutationInsertTimeRange = 10;//对基因中随即插入一些动作的时间范围



int globe_popsize = 500;
int globe_Generation = 200;
int globe_initTimeRange = 5;
//double globe_precision = 0.001;
int globe_numGen = 30;




/////////////////////////////////////

double globe_dActivationResponse = 0.5;
int globe_NumInput = 6;
int globe_NumOutput = 5;
int	globe_NumHiddenLayers = 2;
int globe_iNeuronsPerHiddenLayer = 5;
double globe_weightRange = 2;

///////////////////////////////////////
int g_WGeneration = 150;
int g_Wpopsize = 400;
double g_WdMaxPerturbation = 4;
int g_WiNumElite = 4;
double g_WdBigMutationRate = 0.4;
double g_WdBigPerturbation = 10;
double g_WdMutationRate = 0.8;
double g_WdCrossoverRate = 0.2;

double globe_UnitaryRate = 50;

////用于储存障碍地图的全局变量
CObstacle ObstacleMap[20];

////用于储存临时人口基因的全局变量(因为模板不能作为成员变量~~)
vector<SGenome> m_population;
vector<SWGenome> m_Wpopulation;

//用于储存权值向量
vector<double> m_weight;


/////////////////////////////////////////////////////////////////////////////
// CEludeObstacleView

IMPLEMENT_DYNCREATE(CEludeObstacleView, CView)

BEGIN_MESSAGE_MAP(CEludeObstacleView, CView)
	//{{AFX_MSG_MAP(CEludeObstacleView)
	ON_WM_TIMER()
	ON_WM_CHAR()
	ON_WM_KEYDOWN()
	ON_COMMAND(IDM_Demo, OnDemo)
	ON_COMMAND(IDM_PlayerControl, OnPlayerControl)
	ON_COMMAND(IDM_StartGenAlg, OnStartGenAlg)
	ON_COMMAND(IDM_StartStepGenAlg, OnStartStepGenAlg)
	ON_COMMAND(IDM_SetObstacle, OnSetObstacle)
	ON_WM_LBUTTONDOWN()
	ON_WM_RBUTTONUP()
	ON_WM_RBUTTONDOWN()
	ON_WM_CANCELMODE()
	ON_WM_LBUTTONUP()
	ON_WM_CAPTURECHANGED()
	ON_WM_MOUSEMOVE()
	ON_WM_ERASEBKGND()
	ON_WM_CONTEXTMENU()
	ON_COMMAND(IDM_SaveMap, OnSaveMap)
	ON_COMMAND(IDM_DefaultMap1, OnDefaultMap1)
	ON_COMMAND(IDM_DefaultMap2, OnDefaultMap2)
	ON_COMMAND(IDM_DefaultMap3, OnDefaultMap3)
	ON_COMMAND(IDM_SetParameter, OnSetParameter)
	ON_COMMAND(IDM_TrainNetwork, OnTrainNetwork)
	ON_COMMAND(IDM_DemoNetwork, OnDemoNetwork)
	ON_COMMAND(IDM_DefaultMap4, OnDefaultMap4)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)


	ON_COMMAND(IDM_SaveMap1, OnSaveMap1)
	ON_COMMAND(IDM_SaveMap2, OnSaveMap2)
	ON_COMMAND(IDM_SaveMap3, OnSaveMap3)
	ON_COMMAND(IDM_SaveMap4, OnSaveMap4)
	ON_COMMAND(IDM_SaveMap5, OnSaveMap5)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEludeObstacleView construction/destruction

CEludeObstacleView::CEludeObstacleView()
{
	// TODO: add construction code here

	//如果进入一步一步显示状态值为1
	ifStepByStep = 0;

	//不能设置障碍物
	m_setMode = 0;

	ifPressLButton = 0;
	
	ifPress = 0;
	//不用指出感应到的星球
	ifPointOut = 0;
	
	//m_Obstacle[0].center.x = 200;
	//m_Obstacle[0].center.y = 300;
	//m_Obstacle[0].radius = 30;
	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);

	Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
	
	m_weight.clear();
	//m_weight.push_back();

}

CEludeObstacleView::~CEludeObstacleView()
{
}

BOOL CEludeObstacleView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CEludeObstacleView drawing

void CEludeObstacleView::OnDraw(CDC* pDC)
{
	CEludeObstacleDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	
	/*
	EnableMenuItem(IDM_Demo,0);
	EnableMenuItem(IDM_DemoNetwork,0);
	*/


	//下次不再显示喷气
	Aerocraft.m_iJetDirection = 1;
	
}

/////////////////////////////////////////////////////////////////////////////
// CEludeObstacleView printing

BOOL CEludeObstacleView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CEludeObstacleView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CEludeObstacleView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CEludeObstacleView diagnostics

#ifdef _DEBUG
void CEludeObstacleView::AssertValid() const
{
	CView::AssertValid();
}

void CEludeObstacleView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CEludeObstacleDoc* CEludeObstacleView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CEludeObstacleDoc)));
	return (CEludeObstacleDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CEludeObstacleView message handlers

void CEludeObstacleView::OnInitialUpdate()
{
	FileHandle.init();
	AfxMessageBox("     主舰失事,你是乘着救生艇逃离灾难的唯一幸存者!\n目前你的前方是险象环生的陨石群,由于救生艇设计简陋\n只能用方向键控制前后左右加速,不过可喜的是里面也\n配置着一台智能电脑,她能分析当前的陨石棑布,模拟\n物理场景,分析可行控制...在这关键性的时刻,你会把\n人类的命运交给人工智能还是自己把握呢?恩,请尽快作\n出选择,时间无多!!!");
	
	//EnableMenuItem(GetMenu(hWnd),IDM_Demo,MF_ENABLED);

	
	//(1)创建内存区域
	CBitmap* pBmp = new CBitmap;
	CDC* pDC=GetDC();
	CRect rectTemp(0,0,g_MapWidth,g_MapHeight);//为绘图区域
	Mem.CreateCompatibleDC(pDC);
	pBmp->CreateCompatibleBitmap(pDC, rectTemp.Width(), rectTemp.Height());
	Mem.SelectObject(pBmp);

	updateObstacleDC();
	updateAerocraftDC();
}

void CEludeObstacleView::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if(nIDEvent == 1)
	{		
		if(m_end == 1)
		{
			KillTimer(1);
			return;
		}
		
		Invalidate();
		
		//每次重力都会改变速度,从而改变位移
		Aerocraft.updateTheVelocity1();
		Aerocraft.updateThePosition();
		ifPress = 1;
		
		if(Aerocraft.m_vPos.x + g_AerocraftRadius * Aerocraft.m_dScale > g_MapWidth)
		{
			m_end = 1;
			AfxMessageBox("你终于成功地逃离了陨石群,但下次就没那么走运了!!!");
			//
			return;
			//
		}
		if(ifCollide())
		{
			m_end = 1;
			//PlaySound("explosion", NULL, SND_ASYNC|SND_FILENAME);
			//PlaySound("TEST_SOUND", NULL, SND_RESOURCE|SND_ASYNC);
			//Sleep(1000);
			AfxMessageBox("救生仓与你一同化为星尘,此刻你是否有点后悔了?");
		}
	}


	else if(nIDEvent == 2)
	{
		static int i = 0,j = 0;
		
		if(m_end == 1)
		{
			KillTimer(2);
			return;
		}
		
		if(j >= m_ControlGen.time[i]){j = 0; i++;}
		if(i >= globe_numGen)
		{
			m_end = 1;
			i = 0;
			j = 0;
			AfxMessageBox("演示结束");
			return;
		}
		int action = m_ControlGen.action[i];
		j++;


		if(action == 0){}
		else if(action == 1){Aerocraft.updateTheVelocity2();Aerocraft.m_iJetDirection = 2;}
		else if(action == 2){Aerocraft.updateTheVelocity3();Aerocraft.m_iJetDirection = 3;}
		else if(action == 3){Aerocraft.updateTheVelocity4();Aerocraft.m_iJetDirection = 4;}
		else if(action == 4){Aerocraft.updateTheVelocity5();Aerocraft.m_iJetDirection = 5;}
		else {AfxMessageBox("行动数不对!!!(onTimer2)");return;}

		Invalidate();
		
		//每次重力都会改变速度,从而改变位移
		Aerocraft.updateTheVelocity1();
		Aerocraft.updateThePosition();

		if(Aerocraft.m_vPos.x + g_AerocraftRadius * Aerocraft.m_dScale > g_MapWidth)
		{
			m_end = 1;
			i = 0;
			j = 0;
			AfxMessageBox("终于成功地逃离了陨石群,你的选择是正确的!!!");
			//
			return;
			//
		}
		if(ifCollide())
		{
			m_end = 1;
			i = 0;
			j = 0;
			AfxMessageBox("救生仓与你化为了星尘,难道电脑也有不可靠的时候?!");
		}
	}

	//如果是一步一步演示过程
	else if(nIDEvent == 3)
	{
		static int i = 0,j = 0;
		
		if(m_end == 1)
		{
			static Generation = 0;
			Generation++;
			if(ThinkItStepByStep(m_population))
			{
				
				ifStepByStep = 0;
				KillTimer(3);
				AfxMessageBox("呵呵,小事一桩,我保证我们能脱险~~");
				Invalidate();
				return;
			}

			if(Generation <= globe_Generation)
			{
				m_end = 0;
				Aerocraft.init(20,g_MapHeight/2,0,g_AerocraftSize);
			}
			else
			{
				ifStepByStep = 0;
				KillTimer(3);
				AfxMessageBox("呜~~ 我投降了!!!");
			}
			Invalidate();
			return;
		}
		
		if(j >= m_ControlGen.time[i]){j = 0; i++;}
		if(i >= globe_numGen)
		{
			m_end = 1;
			i = 0;
			j = 0;
			//AfxMessageBox("演示结束");
			return;
		}
		int action = m_ControlGen.action[i];
		j++;


		if(action == 0){}
		else if(action == 1){Aerocraft.updateTheVelocity2();Aerocraft.m_iJetDirection = 2;}
		else if(action == 2){Aerocraft.updateTheVelocity3();Aerocraft.m_iJetDirection = 3;}
		else if(action == 3){Aerocraft.updateTheVelocity4();Aerocraft.m_iJetDirection = 4;}
		else if(action == 4){Aerocraft.updateTheVelocity5();Aerocraft.m_iJetDirection = 5;}
		else {AfxMessageBox("行动数不对!!!(onTimer3)");return;}

		Invalidate();
		
		//每次重力都会改变速度,从而改变位移
		Aerocraft.updateTheVelocity1();
		Aerocraft.updateThePosition();

		if(Aerocraft.m_vPos.x + g_AerocraftRadius * Aerocraft.m_dScale > g_MapWidth)
		{
			m_end = 1;
			i = 0;
			j = 0;
			//AfxMessageBox("你终于成功地躲开了陨石群!!!");
		}
		if(ifCollide())
		{
			m_end = 1;
			i = 0;
			j = 0;
			//AfxMessageBox("碰撞了!!!");
		}
	}

	else if(nIDEvent == 4)
	{
		
		if(m_end == 1)
		{
			ifPointOut = 0;
			KillTimer(4);
			return;
		}
		
		int action;
		
		vector <double> input,output;
		
		
		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]);
		}
		
		
		
		output = NeuralNet.Update(input);
		//取输出值最大的输出位置所代表的action值
		double temp = output[0];
		action = 0;
		for(int k = 1;k < 5;k++)
		{
			if(output[k] > temp)
			{
				temp = output[k];
				action = k;
			}
		}
		
		if(action == 0){}
		else if(action == 1){Aerocraft.updateTheVelocity2();Aerocraft.m_iJetDirection = 2;}
		else if(action == 2){Aerocraft.updateTheVelocity3();Aerocraft.m_iJetDirection = 3;}
		else if(action == 3){Aerocraft.updateTheVelocity4();Aerocraft.m_iJetDirection = 4;}
		else if(action == 4){Aerocraft.updateTheVelocity5();Aerocraft.m_iJetDirection = 5;}
		else {AfxMessageBox("行动数不对!!!(onTimer2)");return;}
		
		Invalidate();
		
		//每次重力都会改变速度,从而改变位移
		Aerocraft.updateTheVelocity1();
		Aerocraft.updateThePosition();
		
		if(Aerocraft.m_vPos.x + g_AerocraftRadius * Aerocraft.m_dScale > g_MapWidth)
		{
			m_end = 1;
			AfxMessageBox("终于成功地逃离了陨石群,你的选择是正确的!!!");
			//
			return;
			//
		}
		if(ifCollide())
		{
			m_end = 1;
			AfxMessageBox("救生仓与你化为了星尘,难道电脑也有不可靠的时候?!");
		}
	}

	CView::OnTimer(nIDEvent);
}

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

void CEludeObstacleView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	if(ifPress == 1)
	{
		if(nChar == VK_LEFT)
		{
			Aerocraft.updateTheVelocity4();
			Aerocraft.m_iJetDirection = 4;
			ifPress = 0;
		}
		else if(nChar == VK_RIGHT)
		{
			Aerocraft.updateTheVelocity5();
			Aerocraft.m_iJetDirection = 5;
			ifPress = 0;
		}
		else if(nChar == VK_DOWN)
		{
			Aerocraft.updateTheVelocity3();
			Aerocraft.m_iJetDirection = 3;
			ifPress = 0;
		}
		else if(nChar == VK_UP)

⌨️ 快捷键说明

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