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