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

📄 fjview.cpp

📁 停车场仿真程序仿真原理:首先有两个定时器自动的随机产生请求入场的卡号和请求出场的卡号
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// FJView.cpp : implementation of the CFJView class
//

#include "stdafx.h"
#include "FJ.h"

#include "FJDoc.h"
#include "FJView.h"
#include <vector>
#include <stdlib.h>

#define W 20
#define L (2*W)
#define LOT_X 48 //栅栏横坐标, 预留来显示等待入场车辆的情况。
#define LOT_Y 70	 //车库纵坐标

#define WM_ELAPSE (WM_USER + 11)
#define WM_ELAPSE_INTERVAL 1000
#define WM_IN		(WM_USER + 12)			//本事件向进入队列填充员工卡号-包括无效卡号
#define WM_OUT		(WM_USER + 19)			//本事件随机的将车场内的卡加入请求出场队列,
#define WM_OUT_INTERVAL 12000
#define WM_IN_INTERVAL 10000		//
#define WM_DEFENCE1_UP (WM_USER + 13)
#define WM_DEFENCE1_DOWN (WM_USER + 14)
#define WM_DEFENCE1_UP_INTERVAL 2000
#define WM_DEFENCE1_DOWN_INTERVAL 1999
#define WM_DEFENCE2_UP (WM_USER + 15)
#define WM_DEFENCE2_DOWN (WM_USER + 16)
#define WM_ROLL_IN (WM_USER + 17)			//进车位事件
#define WM_ROLL_OUT (WM_USER + 18)			//出车位事件
#define WM_ROLL_INTERVAL 1999
#define WM_DEFENCE2_UP_INTERVAL 1999
#define WM_DEFENCE2_DOWN_INTERVAL 1999

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


//类Dedence的无参构造函数
Defence::Defence()
{
	//入口的状态
	m_intInDefenceState = 0;

	//出口的状态
	m_intOutDefenceState = 0;

	//入口杆正在运动
	m_intInMoveing = false;

	//出口杆正在运动
	m_intOutMoveing = false;
}

//本函数关闭入场杆
void Defence::closeIn()
{
	m_intInDefenceState = 0;
}

//本函数开启出场杆
void Defence::closeOut()
{
	m_intOutDefenceState = 0;
}

//判断入场杆是否已经打开
bool Defence::isInON()
{
	return 1 == m_intInDefenceState;
}

//判断出场杆是否已经打开
bool Defence::isOutON()
{
	return 1 == m_intOutDefenceState;
}

//开启入场杆
void Defence::openIn()
{
	m_intInDefenceState = 1;
}

//开启出场杆
void Defence::openOut()
{
	m_intOutDefenceState = 1;
}
/////////////////////////////////////////////////////////////////////////////
// CFJView

IMPLEMENT_DYNCREATE(CFJView, CView)

BEGIN_MESSAGE_MAP(CFJView, CView)
	//{{AFX_MSG_MAP(CFJView)
	ON_WM_CREATE()
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
	// Standard printing commands

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFJView construction/destruction

/*************************************************************************
 *
 * 函数名称:
 *   CFJView()
 *
 * 参数:
 *   
 * 返回值:
 *   
 *
 * 说明:
 * 类CFJView的无参构造函数,该函数完成一些基本变量的初始化
 * 
 * 
 ************************************************************************/
CFJView::CFJView() : m_park(theApp.m_intN , 2)
{
	//从0到N-1是空的。1则被占用。
	for(int i = 0; i <= theApp.m_intN + 2; i++)
	{
		m_vctLots.push_back(0);
	}
	::GetLocalTime(&m_systiStart);

	//设置卡的有效范围
	m_ccCards.setValidSize(theApp.m_intE);

	//车场过道没有人占用
	m_bLotLocked = false;

	//最近进场卡号
	m_intRecentIn = -1;

	//最近出唱卡号
	m_intRecentOut = -1;

	m_bHasStartRollIn = false;
	m_bHasStartRollOut = false;
	m_fTotalTime = 0.0f;
	m_ulTotalIn = 0;
	m_ulTotalOut = 0;

	//创建运行日志文件
	m_filOut.Open("停车场仿真.log", CFile::modeWrite | CFile::modeCreate);
}

/*************************************************************************
 *
 * 函数名称:
 *   CFJView()
 *
 * 参数:
 *   int x				- 单排车位数
 *	 int y				- 车位排数
 * 返回值:
 *   
 *
 * 说明:
 * 类CFJView的有参构造函数.本函数没有使用过
 * 
 *
 ************************************************************************/
CFJView::CFJView(int x, int y):m_park(x, y)
{
	//从0到theApp.m_intN-1个过道都是空的。1则被占用。
	for(int i = 0; i < theApp.m_intN + 2; i++)
	{
		m_vctLots.push_back(0);
	}
	m_bHasStartRollIn = false;
	m_bHasStartRollOut = false;
	m_bLotLocked = false;
	m_ccCards.setValidSize(theApp.m_intN);
	m_intRecentIn = -1;
	m_intRecentOut = -1;
	m_ulTotalIn = 0;
	m_fTotalTime = 0.0f;
	m_ulTotalOut = 0;
	m_filOut.Open("..\\m_filOut.txt", CFile::modeWrite | CFile::modeCreate);

}

/*************************************************************************
 *
 * 函数名称:
 *   ~CFJView()
 *
 * 参数:
 *   
 * 返回值:
 *   
 *
 * 说明:
 * 类CFJView的析构函数.销毁计时器
 * 
 * 
 ************************************************************************/
CFJView::~CFJView()
{	
	SYSTEMTIME sysTime;
	::GetLocalTime(&sysTime);

	KillTimer(WM_ELAPSE);
	KillTimer(WM_IN);
	KillTimer(WM_OUT);

	CFile file;
	CString name;
	name.Format("0%d%2d%2d_%2d%2d%2d_%2d%2d%2d.rpt",
			sysTime.wYear%2000,sysTime.wMonth,  sysTime.wDay,
			m_systiStart.wHour,	m_systiStart.wMinute, m_systiStart.wSecond,
			sysTime.wHour, sysTime.wMinute, sysTime.wSecond);

	file.Open(name, CFile::modeWrite | CFile::modeCreate);
	name.Format("本次仿真累计入场%d辆车,本次仿真累计出场%d辆车,本次仿真平均停车时间%d秒.",m_ulTotalIn, m_ulTotalOut,m_fTotalTime/(m_ulTotalIn==0?1:m_ulTotalIn));
	file.Write((LPSTR)(LPCTSTR)name, strlen((LPSTR)(LPCTSTR)name));
	file.Close();
}


BOOL CFJView::PreCreateWindow(CREATESTRUCT& cs)
{
	cs.cy = 100;
	cs.cx = 760;

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CFJView drawing

void CFJView::OnDraw(CDC* pDC)
{
	CFJDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	
	AfxGetApp()->m_pMainWnd->SetWindowText("停车场仿真 Ver1.0");
	
	CString stactics;

	pDC->SetTextColor(RGB(92, 32, 223));

	stactics.Format("则分别表示有多少辆车处于请求入场和出场状态.效果图仅是一个定性模拟,定量模拟数据以运行日志为准。");

	//说明界面文字
	pDC->TextOut(0,0, "说明:在下图中,红色的矩形表示空的车位,如果矩形边框变黑,则说明该车位已经停放车辆,框内的数值是停车者的员工卡号。");
	pDC->TextOut(0,15,"左右两道黑色的竖线分别表示处于关闭状态的进出场杆,如果消失则表示此刻杆是抬起的.左右竖线附近区域如果闪现出车形图案,");
	pDC->TextOut(0,30,stactics);

	stactics.Format("当前请求入场队列中有%d辆车在等待,出场队列中有%d辆,总计入场%d辆车,出场%d辆车,平均停车时间%d秒.",m_queIncomeCars.size(), m_queOutCars.size(),m_ulTotalIn, m_ulTotalOut,m_fTotalTime/(m_ulTotalIn==0?1:m_ulTotalIn) );
	pDC->TextOut(0,45,stactics);

	int n = -1;
	RECT c;
	c.top = LOT_Y;
	c.left = LOT_X;//
	c.right =  c.left + W; //
	c.bottom = c.top + L;
	CBrush cb(RGB(132, 32, 223));
	CBrush cbhave(RGB(0, 0, 0));
	
	/*画入口栅栏*/
	if(!m_defence.isInON())
	{
		pDC->MoveTo(LOT_X, L + LOT_Y);
		pDC->LineTo(LOT_X, L + LOT_Y + W);
	}

	//画第一排车库
	for(int i = 0; i < theApp.m_intN; i++)
	{
		c.left += W;
		c.right += W;

		CPoint p;
		p.x = i;
		p.y = 0;
		if( m_park.isOccupy(p))
		{
			pDC->FrameRect(&c, &cbhave);	//车位上有车
		}
		else
		{
			pDC->FrameRect(&c, &cb);
		}


		if((n=m_park.getCard(p)) != -1)
		{
			stactics.Format("%d", n );
			pDC->TextOut(c.left, c.top, stactics);
		}
	}

	//画出口
	if(!m_defence.isOutON())
	{
		pDC->MoveTo(c.right + W, L + LOT_Y);
		pDC->LineTo(c.right + W, L + LOT_Y + W);
	}

	/*这部分画第二排车库*/
	c.left = LOT_X;
	c.top = L + LOT_Y + W;
	c.right = LOT_X + W;
	c.bottom = c.top + L;
	for(i = 0; i < theApp.m_intN; i++ )
	{
		c.left += W;
		c.right += W;

		CPoint p;
		p.x = i;
		p.y = 1;

		if( m_park.isOccupy(p))
		{
			pDC->FrameRect(&c, &cbhave);	//车位上有车
		}
		else
		{
			pDC->FrameRect(&c, &cb);
		}

		if((n=m_park.getCard(p)) != -1)
		{
			stactics.Format("%d", n);
			pDC->TextOut(c.left, c.top, stactics);
		}
	}

	//用来显示图片
	CDIB dibCar;
	CDC * dc;
	dc = AfxGetApp()->m_pMainWnd->GetDC();

	//加载文件成功
	if(dibCar.LoadFromFile("car.bmp"))
	{
		//显示请求入场的所有汽车
		for( i = 0; i < m_queIncomeCars.size(); i++)
		{
			dibCar.ShowDIB(dc, 5, 2*L + 48 * i + LOT_Y, 48, 48);
		}

		//显示请求出场的所有汽车
		for(i = 0; i < m_queOutCars.size(); i++ )
		{
			if(m_ccCards.findCard(m_queOutCars.front()))
			dibCar.ShowDIB(dc, c.right + W, 2*L + 48 * i + LOT_Y, 48, 48);
		}

		//显示过道上的汽车
		if(isObstacle())
		{
			int n = getObstaclePosition();
			dibCar.ShowDIB(dc, LOT_X + n * W, L + LOT_Y, 2*W, W);
		}
	}

	//释放DC
	AfxGetApp()->m_pMainWnd->ReleaseDC(dc);

}

/////////////////////////////////////////////////////////////////////////////
// CFJView printing

BOOL CFJView::OnPreparePrinting(CPrintInfo* pInfo)
{
	return DoPreparePrinting(pInfo);
}

void CFJView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
}

void CFJView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
}

/////////////////////////////////////////////////////////////////////////////
// CFJView diagnostics

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

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

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

/////////////////////////////////////////////////////////////////////////////
// CFJView message handlers

int CFJView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	
		//启动时间流逝.
		SetTimer(WM_ELAPSE, WM_ELAPSE_INTERVAL, NULL);

		//启动产生入场请求事件。
		SetTimer(WM_IN, WM_IN_INTERVAL, NULL);

		//启动产生出场请求事件。
		SetTimer(WM_OUT, WM_OUT_INTERVAL, NULL);
	return 0;
}

/*************************************************************************
 *
 * 函数名称:
 *   OnTimer()
 *
 * 参数:
 *   UINT	nIDEvent			- 计时器编号
 * 返回值:
 *   void
 *
 * 说明:
 * 该函数用于处理各种已经发生的事件
 * 
 * 
 ************************************************************************/
void CFJView::OnTimer(UINT nIDEvent) 
{
	AfxGetApp()->m_pMainWnd->RedrawWindow();

	//开启入场杆
	if(nIDEvent == WM_DEFENCE1_UP)
	{
		m_defence.openIn();
		KillTimer(nIDEvent);
		m_defence.m_intInMoveing = false;
		m_bincome = true;
		setObstacle(0);

		LPSTR c = "开启入场杆完毕";
		write(c);
		Sleep(1010);
		CView::OnTimer(nIDEvent);
		return ;
	}

	//关闭入场杆
	else if(WM_DEFENCE1_DOWN == nIDEvent)
	{
		m_defence.closeIn();
		KillTimer(nIDEvent);
		m_defence.m_intInMoveing = false;

		LPSTR c = "关闭入场杆完毕";
		write(c);
		CView::OnTimer(nIDEvent);
		return ;
	}

	//开启出场杆
	else if(WM_DEFENCE2_UP == nIDEvent)
	{
		m_defence.openOut();
		KillTimer(nIDEvent);
		m_defence.m_intOutMoveing = false;

		LPSTR c = "开启出场杆完毕";
		write(c);
		CView::OnTimer(nIDEvent);
		return ;
	}

	//关闭出场杆
	else if(WM_DEFENCE2_DOWN == nIDEvent)
	{
		m_defence.closeOut();
		KillTimer(nIDEvent);
		m_defence.m_intOutMoveing = false;
		
		//送开过道使用权
		setEmpty();
		m_bLotLocked = false;

		LPSTR c = "关闭出场杆完毕";

⌨️ 快捷键说明

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