// RobotView.cpp : implementation of the CRobotView class
//
#include "stdafx.h"
#include "Robot.h"
#include "RobotDoc.h"
#include "RobotView.h"
#include "MainFrm.h"
#include "math.h"
#include "SetPara.h"
#include "MyGA.h"
#include "string.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CString filepath;
extern double Patterns[100][2];
extern double xmin,xmax,ymin,ymax;
extern int gridWidthX,gridWidthY,gridWidth;
extern int chart[500][500];
float a;
float dist=0.0;
/////////////////////////////////////////////////////////////////////////////
// CRobotView
IMPLEMENT_DYNCREATE(CRobotView, CView)
BEGIN_MESSAGE_MAP(CRobotView, CView)
//{{AFX_MSG_MAP(CRobotView)
ON_WM_SIZE()
ON_COMMAND(ID_BTSTART, OnBtstart)
ON_COMMAND(ID_BTERASE, OnBterase)
ON_COMMAND(ID_BTADD, OnBtadd)
ON_COMMAND(ID_BTPARA, OnBtpara)
ON_COMMAND(ID_MENUADD, OnMenuadd)
ON_COMMAND(ID_MENUERASE, OnMenuerase)
ON_COMMAND(ID_MENUPARA, OnMenupara)
ON_COMMAND(ID_MENUSTART, OnMenustart)
ON_WM_LBUTTONDOWN()
ON_COMMAND(ID_BTPAUSE, OnBtpause)
ON_WM_CANCELMODE()
ON_WM_CREATE()
ON_COMMAND(IDD_OBSTACLE, OnObstacle)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRobotView construction/destruction
CRobotView::CRobotView()
{
// TODO: add construction code here
m_origX=m_origY=20;
//m_origX =xmin;
//m_origY =ymin;//画图的起点
m_bEraseBlock = m_bAddBlock = m_bSetPara = false;
m_bAlreadyStarted = false;
m_bNeedInit = true;
m_CurOpID = ID_APP_ABOUT;
m_preState = &m_bEraseBlock;
m_pThread = NULL;
}
CRobotView::~CRobotView()
{
}
BOOL CRobotView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CRobotView drawing
void CRobotView::OnDraw(CDC* pDC)
{
CRobotDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
DrawChart(pDC,m_origX,m_origY);
DrawBlocks(pDC,m_origX,m_origY);
DrawPath(pDC,pDoc->GARoad->curBestGenome,pDoc->generation);
ShowPara(pDC,pDoc->GARoad->curBestGenome);
}
/////////////////////////////////////////////////////////////////////////////
// CRobotView diagnostics
#ifdef _DEBUG
void CRobotView::AssertValid() const
{
CView::AssertValid();
}
void CRobotView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CRobotDoc* CRobotView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CRobotDoc)));
return (CRobotDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CRobotView message handlers
void CRobotView::DrawChart(CDC* pDC,int originX,int originY)
{
CRobotDoc* pDoc = GetDocument();
int chartWidth = m_CurPara.width;
//int chartHeight = m_CurPara.height;
//gridWidth = min(m_cxWnd/chartWidth,(int)(m_cyWnd*7/8/chartHeight));
//gridWidth=int(m_cxWnd/chartWidth);
gridWidthX=int(xmax-xmin)/chartWidth+1;
gridWidthY=int(ymax-ymin)/chartWidth+1;
gridWidth = min(m_cxWnd/gridWidthX,(int)(m_cyWnd*7/8/gridWidthY));
//gridWidth=20;.
/*CString strHint;
strHint.Format ("(%f,%f),(%f,%f),chartWidth=%d,gridWidth=%d",xmin,ymin,xmax,ymax,chartWidth,gridWidth);
AfxMessageBox(strHint);
strHint.Format ("gridWidthX=%d,gridWidthY=%d",gridWidthX,gridWidthY);
AfxMessageBox(strHint);*/
//a=gridWidth;
CPen m_ChartPen(PS_SOLID,1,RGB(0,0,0));
CPen* m_OldPen = pDC->SelectObject (&m_ChartPen);
//先画横线
for (int i = 0; i <= gridWidthX; i++)
{
int x0 = originX;
int x1 = x0+gridWidthY*gridWidth;
int y = originY + gridWidth*i;
pDC->MoveTo(x0,y);
pDC->LineTo(x1,y);
}
//画竖线
for (i = 0; i <= gridWidthY; i++)
{
int y0 = originY;
int y1 = y0 + gridWidth*gridWidthX;
int x = originX + gridWidth*i;
pDC->MoveTo(x,y0);
pDC->LineTo(x,y1);
}
/*//画竖线
for (i = 0; i <= chartWidth; i++)
{
int y0 = originY;
int y1 = y0 + gridWidth*chartHeight;
int x = originX + gridWidth*i;
pDC->MoveTo(x,y0);
pDC->LineTo(x,y1);
}*/
//显示起点和终点
/* CFont font;
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
lf.lfHeight = gridWidth/2;
strcpy(lf.lfFaceName, "Arial");
VERIFY(font.CreateFontIndirect(&lf));
CFont* oldFont = pDC->SelectObject(&font);
int startX = originX+gridWidth/3;
int startY = originY+gridWidth/3;
pDC->TextOut(startX,startY,"S");//output S
int endX = originX+(chartWidth-1)*gridWidth+gridWidth/3;
int endY = originY+(chartHeight-1)*gridWidth+gridWidth/3;
pDC->TextOut(endX,endY,"E");//output E*/
pDC->SelectObject(m_OldPen);
//pDC->SelectObject(oldFont);
}
void CRobotView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
m_cxWnd = cx;
m_cyWnd = cy;
}
void CRobotView::DrawBlocks(CDC* pDC,int originX,int originY)
{
CRobotDoc* pDoc = GetDocument();
int width = gridWidthX;
int height = gridWidthY;
int upleftX,upleftY,lowrightX,lowrightY;
CRect blockRect;
CBrush m_BlockBrush;
m_BlockBrush.CreateSolidBrush(RGB(0,0,0));
CBrush* oldBrush = pDC->SelectObject(&m_BlockBrush);
//CString strHint;
//strHint.Format ("width:%d,height:%d",width,height);
//AfxMessageBox(strHint);
for (int i=0; i<=width; i++)
for (int j=0; j<=height; j++)
{
//if (pDoc->GARoad->IsBlock(i,j))
if(chart[i][j]==1)
{
//CString strHint;
//strHint.Format ("i:%d,j:%d",i,j);
//AfxMessageBox(strHint);
upleftX = originX+j*gridWidth;
upleftY = originY+i*gridWidth;
lowrightX = upleftX+gridWidth+1;
lowrightY = upleftY+gridWidth+1;
blockRect.SetRect(upleftX,upleftY,lowrightX,lowrightY);
pDC->Rectangle(blockRect);
}
}
pDC->SelectObject(oldBrush);
}
void CRobotView::DrawPath(CDC* pDC,Gen* path,int generation)
{
if (path)
{
CRobotDoc* pDoc = GetDocument();
int chartH,chartW;
pDoc->GARoad->GetChartSize(chartH,chartW);
BYTE red = (20*generation)%256;
BYTE green = (50*generation)%256;
BYTE blue = (80*generation)%256;
COLORREF m_PathColor = RGB(red,green,blue);
CPen m_PathPen(PS_DASH,2,m_PathColor);
CPen* m_OldPen = pDC->SelectObject(&m_PathPen);
if (path->genVec.size()!=0 && chartH!=0 && chartW!=0)
{
int len = path->genVec.size();
int curY,curX,curY1,curX1;
curY = path->genVec[0]/chartW;
curX = path->genVec[0]%chartW;
curY = m_origY + curY*gridWidth + (gridWidth+1)/2;
curX = m_origX + curX*gridWidth + (gridWidth+1)/2;
pDC->MoveTo(curX,curY);
dist=sqrt((m_origX-curX)*(m_origX-curX)+(m_origY-curY)*(m_origY-curY));
for (int i = 1; i < len; i++)
{
curY1=curY;
curX1=curX;
curY = path->genVec[i]/chartW;
curX = path->genVec[i]%chartW;
curY = m_origY + curY*gridWidth + (gridWidth+1)/2;
curX = m_origX + curX*gridWidth + (gridWidth+1)/2;
pDC->LineTo(curX,curY);
dist+=sqrt((curX-curX1)*(curX-curX1)+(curY-curY1)*(curY-curY1));
pDC->MoveTo(curX,curY);
}
}
pDC->SelectObject(m_OldPen);
}
}
UINT ThreadFunc(LPVOID pParam)
{
CRobotView* m_CurView = (CRobotView*)pParam;
CRobotDoc* pDoc = m_CurView->GetDocument();
MyGA* m_Robot = pDoc->GARoad;
if (m_Robot)
{
//刚开始执行,需要初始化
if (m_CurView->m_bNeedInit)
{
m_Robot->releaseData();
m_Robot->initialData(m_CurPara);
m_Robot->InitialPop();
m_Robot->EvalPop();
pDoc->generation = 0;
}
int dstTime,srcTime;
while (pDoc->generation < m_Robot->GetGeneration())
{
m_Robot->GenerateNextPop();
m_Robot->EvalPop();
m_Robot->PerformEvoltion();
pDoc->generation++;
m_CurView->Invalidate();
m_CurView->UpdateWindow();
dstTime = srcTime = GetTickCount();
do {
dstTime = GetTickCount();
} while((dstTime-srcTime)<=1500);
}
//进化完之后在对最后的序列进行一次插值
//使之更加连续
if (pDoc->generation == m_Robot->GetGeneration())
{
int len = m_Robot->curBestGenome->genVec.size();
int insertResult;
for (int j = 1; j < len;)
{
insertResult = m_Robot->Insertpt(m_Robot->curBestGenome,j);
if (insertResult == 0)
j += 1;
else
j += 2;
len = m_Robot->curBestGenome->genVec.size();
}
m_CurView->Invalidate();
m_CurView->UpdateWindow();
m_Robot->releaseData();
m_Robot->initialData(m_CurPara);
m_CurView->m_bNeedInit = true;
m_CurView->m_bAlreadyStarted = false;
}
}
return 0;
}
void CRobotView::OnBtstart()
{
// TODO: Add your command handler code here
((CMainFrame*)::AfxGetMainWnd())->checkButton(m_CurOpID,FALSE);
*m_preState = false;
m_CurOpID = ID_BTSTART;
((CMainFrame*)::AfxGetMainWnd())->checkButton(m_CurOpID,TRUE);
if (!m_bAlreadyStarted)
{
m_bAlreadyStarted = true;
m_pThread = AfxBeginThread(ThreadFunc,this);
}
else if (m_pThread)
{
m_bNeedInit = false;
m_pThread->ResumeThread();
}
}
void CRobotView::OnBtpause()
{
// TODO: Add your command handler code here
((CMainFrame*)::AfxGetMainWnd())->checkButton(m_CurOpID,FALSE);
*m_preState = false;
m_CurOpID = ID_BTPAUSE;
((CMainFrame*)::AfxGetMainWnd())->checkButton(m_CurOpID,TRUE);
if(m_pThread)
{
m_pThread->SuspendThread();
//暂停时对当前最优的序列进行一次插值
//使之更加连续
CRobotDoc* pDoc = GetDocument();
MyGA* m_Robot = pDoc->GARoad;
int len = m_Robot->curBestGenome->genVec.size();
int insertResult;
for (int j = 1; j < len;)
{
insertResult = m_Robot->Insertpt(m_Robot->curBestGenome,j);
if (insertResult == 0)
j += 1;
else
j += 2;
len = m_Robot->curBestGenome->genVec.size();
}
Invalidate();
UpdateWindow();
}
}
void CRobotView::OnBterase()
{
// TODO: Add your command handler code here
((CMainFrame*)::AfxGetMainWnd())->checkButton(m_CurOpID,FALSE);
*m_preState = false;
m_bEraseBlock = !m_bEraseBlock;
m_preState = &m_bEraseBlock;
m_CurOpID = ID_BTERASE;
if (m_bEraseBlock)
((CMainFrame*)::AfxGetMainWnd())->checkButton(m_CurOpID,TRUE);
else
((CMainFrame*)::AfxGetMainWnd())->checkButton(m_CurOpID,FALSE);
}
void CRobotView::OnBtadd()
{
// TODO: Add your command handler code here
((CMainFrame*)::AfxGetMainWnd())->checkButton(m_CurOpID,FALSE);
*m_preState = false;
m_bAddBlock = !m_bAddBlock;
m_preState = &m_bAddBlock;
m_CurOpID = ID_BTADD;
if (m_bAddBlock)
((CMainFrame*)::AfxGetMainWnd())->checkButton(m_CurOpID,TRUE);
else
((CMainFrame*)::AfxGetMainWnd())->checkButton(m_CurOpID,FALSE);
}
void CRobotView::OnBtpara()
{
// TODO: Add your command handler code here
((CMainFrame*)::AfxGetMainWnd())->checkButton(m_CurOpID,FALSE);
*m_preState = false;
m_bSetPara = !m_bSetPara;
m_preState = &m_bSetPara;
m_CurOpID = ID_BTPARA;
SetPara m_ChangePara;
if (m_ChangePara.DoModal() == IDOK)
{
//注意参数变了之后,需要对chart的大小进行调整
CRobotDoc* pDoc = GetDocument();
pDoc->GARoad->AdjustChart(m_ChangePara.m_Height,m_ChangePara.m_Width);
m_CurPara.height = m_ChangePara.m_Height;
m_CurPara.width = m_ChangePara.m_Width;
m_CurPara.propC = m_ChangePara.m_Cross;
m_CurPara.propM = m_ChangePara.m_Mutation;
m_CurPara.pSize = m_ChangePara.m_PopSize;
m_CurPara.T = m_ChangePara.m_GenNum;
Invalidate();
UpdateWindow();
}
}
void CRobotView::OnMenuadd()
{
// TODO: Add your command handler code here
OnBtadd();
}
void CRobotView::OnMenuerase()
{
// TODO: Add your command handler code here
OnBterase();
}
void CRobotView::OnMenupara()
{
// TODO: Add your command handler code here
OnBtpara();
}
void CRobotView::OnMenustart()
{
// TODO: Add your command handler code here
OnBtstart();
}
void CRobotView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CView::OnLButtonDown(nFlags, point);
int curBlockULX = (point.x-m_origX)/gridWidth;
int curBlockULY = (point.y-m_origY)/gridWidth;
CRobotDoc* pDoc = GetDocument();
if (m_bEraseBlock)
{
pDoc->GARoad->ClearBlock(curBlockULY,curBlockULX);
Invalidate();
UpdateWindow();
}
else if (m_bAddBlock)
{
pDoc->GARoad->SetBlock(curBlockULY,curBlockULX);
Invalidate();
UpdateWindow();
}
}
void CRobotView::ShowPara(CDC* pDC,Gen* path)
{
CRobotDoc* pDoc = GetDocument();
int gridWidth = min(m_cxWnd/gridWidthX,(int)(m_cyWnd*7/8/gridWidthY));
int curBound = xmin+gridWidthY*gridWidth;
int startX = curBound+40;
int startY = 20;
CFont font;
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
lf.lfHeight = 16;
strcpy(lf.lfFaceName, "Arial");
VERIFY(font.CreateFontIndirect(&lf));
CFont* oldFont = pDC->SelectObject(&font);
pDC->TextOut(startX,startY,"当前种群规模:");
pDC->TextOut(startX,startY+30,"当前进化代数:");
pDC->TextOut(startX,startY+60,"当前适应度:");
pDC->TextOut(startX,startY+90,"gridWidth:");
pDC->TextOut(startX,startY+120,"路径长度:");
pDC->TextOut(startX,startY+150,"左上角坐标:");
pDC->TextOut(startX,startY+180,"右下角坐标:");
pDC->SelectObject(oldFont);
COLORREF oldColor = pDC->SetTextColor(RGB(255,0,255));
CString gen;
gen.Format(_T("%d"),m_CurPara.pSize);
pDC->TextOut(startX+120,startY,gen);
gen.Format(_T("%d"),pDoc->generation);
pDC->TextOut(startX+120,startY+30,gen);
gen.Format(_T("%.3f"),pDoc->GARoad->curBestGenome->fitness);
pDC->TextOut(startX+120,startY+60,gen);
gen.Format(_T("%.2f"),a);
pDC->TextOut(startX+120,startY+90,gen);
gen.Format(_T("%.2f"),dist);
pDC->TextOut(startX+120,startY+120,gen);
gen.Format(_T("%f,%f"),xmin,ymin);
pDC->TextOut(startX+120,startY+150,gen);
gen.Format(_T("%f,%f"),xmax,ymax);
pDC->TextOut(startX+120,startY+180,gen);
pDC->SetTextColor(oldColor);
}
void CRobotView::OnObstacle()
{
// TODO: Add your command handler code here
CDC* pDC;
int curBound = m_origX+m_CurPara.width*gridWidth+1;
int startX = curBound+20;
int startY = 20;
CString strFilter,word,s,strHint,c,line,b;
FILE *InFilePtr;
int Columns=2,Numpatterns=0,i,j;
double x;
strFilter="Text Files(*.txt)|*.txt||";
CFileDialog dlg(TRUE,NULL,NULL,OFN_EXPLORER|OFN_HIDEREADONLY|OFN_ENABLESIZING|OFN_FILEMUSTEXIST,strFilter);
dlg.m_ofn .lStructSize =sizeof(OPENFILENAME);
if(dlg.DoModal ()==IDOK)
{
filepath=dlg.GetPathName();
}
if((InFilePtr = fopen(filepath, "r")) == NULL)
{
strHint.Format ("文件%s不存在",filepath);
AfxMessageBox(strHint);
return;
}
fscanf(InFilePtr,"%s",word);
while(!feof(InFilePtr))
{
if (strcmp(word,"POINT")==0 )
Numpatterns++;
fscanf(InFilePtr,"%s",word);
}
fclose(InFilePtr);
if((InFilePtr = fopen(filepath, "r")) == NULL)
return;
for (i=0;i<Numpatterns;i++)
{
fscanf(InFilePtr,"%s",b);
for (j=0; j<Columns; j++)
{
fscanf(InFilePtr,"%lg",&x);
Patterns[i][j]=x;
}
}
xmin=Patterns[0][0];
xmax=Patterns[0][0];
ymin=Patterns[0][1];
ymax=Patterns[0][1];
for(i=0;i<Numpatterns;i++)
for(j=0;j<Columns;j++)
if(!j)
{
if(Patterns[i][j]<xmin)
xmin=Patterns[i][j];
if(Patterns[i][0]>xmax)
xmax=Patterns[i][j];
}
for(i=0;i<Numpatterns;i++)
for(j=0;j<Columns;j++)
if(j)
{
if(Patterns[i][j]<ymin)
ymin=Patterns[i][j];
if(Patterns[i][1]>ymax)
ymax=Patterns[i][j];
}
strHint.Format ("左上角:%f,%f,右下角:%f,%f",xmin,ymin,xmax,ymax);
AfxMessageBox(strHint);
int chartWidth = m_CurPara.width;
gridWidthX=int(xmax-xmin)/chartWidth+1;
gridWidthY=int(ymax-ymin)/chartWidth+1;
gridWidth = min(m_cxWnd/gridWidthX,(int)(m_cyWnd*7/8/gridWidthY));
strHint.Format ("chartWidth:%d,gridWidthX:%d,gridWidthY:%d",chartWidth,gridWidthX,gridWidthY);
AfxMessageBox(strHint);
for(i=0;i<Numpatterns;i++)
{
int w=int(Patterns[i][1]-ymin)/chartWidth;
int h=int(Patterns[i][0]-xmin)/chartWidth;
//strHint.Format ("h:%d,w:%d",h,w);
//AfxMessageBox(strHint);
if (h>=0 && h<=gridWidthX && w>=0 && w<=gridWidthY)
{
chart[h][w] = 1;
}
}
Invalidate();
UpdateWindow();
}
char * CRobotView::getline(FILE *inputfile)
{
int c;
char* newline;
int n = 0;
int size = 1023;
char* line = (char*)malloc((size_t)(size+1)*sizeof(char));
while ((c = getc(inputfile))!='\n' && c != EOF)
{
if (c!=' ')
{
if (n == size)
{
size *= 2;
newline = (char*)malloc((size_t)(size+1)*sizeof(char));
strncpy (newline, line, n);
free (line);
line = newline;
}
line[n] = c;
n++;
}
}
if (n==0)
{
free (line);
return 0;
}
line[n] = '\0';
newline = (char*)malloc((size_t)(n+1)*sizeof(char));
strcpy (newline, line);
free(line);
return newline;
}









