📄 eludeobstacleview.cpp
字号:
// 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 + -