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

📄 elevator.cpp

📁 电梯仿真系统的实现
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	return m_pltPassenger;
}
int CElevator::GetLocation()
{
	return m_iLocation;
}
long CElevator::GetTotalRun()
{
	//获取电梯运行时间.
	return m_lTotalRun;
}
long CElevator::GetTotalIdle()
{
	//获取电梯空闲时间.
	return m_lTotalIdle;
}
ESTATUS CElevator::GetStatus()
{
	return m_enStatus;
} 
EDIRECTION CElevator::GetDirection()
{
	return m_enDirection;
}
int CElevator::PassengerIn ()
{
  //## begin CElevator::PassengerIn%3BFB3ACB0050.body preserve=yes
// 处理乘客上电梯
	CPassengerList* pLst;
	CPassenger* tmp;
	CMessage* temp;
	CFloor* floor;
	floor = GetFloor(m_iLocation);
	pLst = floor->m_pltFPassengers;
//等待消息队列是否为空
	if(m_ltWaitMsg.empty()) return 3;
//电梯中的乘客是否超载
	if(m_pltPassenger->size() < m_iCapacity)
	{
		if(pLst->empty()) return 3; 
		// 取得等待消息队列中的第一个消息.
		temp = m_ltWaitMsg.front();
		//从楼层乘客链表中找到该乘客.
		tmp = pLst->GetPassengerByPID(temp->PID);
		//ASSERT(tmp);
		if(tmp!=NULL)
		{
			//找到一个乘客要上该电梯.
			//加入到电梯内部乘客链表中.
			m_pltPassenger->push_back(tmp);
			//从楼层中去掉
			pLst->remove(tmp);
			//结束该消息
			m_ltWaitMsg.pop_front();
			//改变该乘客状态
			tmp->SetStatus(INLIFT);
		}
		else m_ltWaitMsg.pop_front();
		if(m_ltWaitMsg.empty()) return 3;
		return 1;
	}
	return 2;//电梯满
  //## end CElevator::PassengerIn%3BFB3ACB0050.body
}
int CElevator::PassengerOut ()
{
  //## begin CElevator::PassengerOut%3BFB3C160226.body preserve=yes
// 处理乘客下电梯.
	CPassengerList::iterator it;
	CPassenger* tmp;
	CFloor* floor;
	floor = GetFloor(m_iLocation);
	for(it = m_pltPassenger->begin();it!=m_pltPassenger->end();it++)
	{
		tmp = *it;
		if(tmp->GetObjFloor() == m_iLocation)
		{
			//找到了一个要在该层下梯的乘客.
			//把它加入到该楼层乘客队列中.
			floor->m_pltFPassengers->push_back(tmp);
			//从乘客链表中去掉该乘客.
			m_pltPassenger->remove(tmp);
			//改变该乘客的当前楼层.
			tmp->SetFloor(m_iLocation);
			if(m_ltMessages.RemoveByPID(tmp->GetPID()))
			{
				//从消息队列中去掉该乘客后.
				//乘客执行自己的结束一次乘坐操作.
				tmp->FinishOneRide();
				return 1;
			}
			else
			{
				TRACE("该乘客P%d并没有在消息队列中!\n",tmp->GetPID());
				return 1; //暂时不作处理
			}
		}
	}
	return 0; //所有要下的乘客离开电梯

  //## end CElevator::PassengerOut%3BFB3C160226.body
}
void CElevator::ChangeDirection()
{
	//改变电梯当前运行方向.
	if(m_enDirection==UP) m_enDirection = DOWN;
	else
	{
		if(m_enDirection==DOWN) m_enDirection = UP;
	}
}
  //## end CElevator%3C1206FF0294.declarations

//## begin module%3C12090901FE.epilog preserve=yes
//## end module%3C12090901FE.epilog

void CElevator::SetStatus(ESTATUS status)
{
	//获取电梯状态.
	m_enStatus = status;

}
void CElevator::Overloaded()
{
//当电梯出现超载的情况,电梯作出的处理.	
	CPassenger* temp;
	CMessage* tmp;
	CFloor* floor;
	CPassengerList* pLst;
	floor = GetFloor(m_iLocation);
	pLst = floor->m_pltFPassengers;
	while(1)
	{
		//取出楼层中等待该电梯的第一个消息.
		tmp = m_ltWaitMsg.front();
		//在楼层乘客链表中找到该乘客.
		temp = pLst->GetPassengerByPID(tmp->PID);
		if(temp!=NULL)
		{
			//如果该乘客存在的话,改变他的状态为没有满足.
			temp->SetStatus(NOTSERVED);
			//从消息队列中去掉该消息.
			m_ltMessages.remove(tmp);
			//从等待消息队列中去掉该消息.
			m_ltWaitMsg.pop_front();
			//如果没有别的等待消息,退出.
			if(m_ltWaitMsg.empty()) break;
		}
		else
		{
			//如果不存在,直接去掉该消息.
			m_ltWaitMsg.pop_front();
			if(m_ltWaitMsg.empty()) break;
		}
	}
}

void CElevator::JudgeDirection()
{
//电梯在每次启动之前都要判断自己的方向.	
	CMessage * tmp;
	CMsgList::iterator it;
	CPassengerList::iterator pit;
	CPassenger * ptmp;
	CFloor* floor;
	CPassengerList* pLst;
	TRACE("Check direction!\n");
	switch(m_enDirection)
	{
	case UP:
		for(it = m_ltMessages.begin(); it!= m_ltMessages.end(); it++)
		{
			tmp = *it;
			if(tmp->OriFloor>m_iLocation)
			{
				//消息队列中还有乘客所在楼层比当前楼层高
				//电梯继续向上运行.
				SetDirection(UP);
				return;
			}
		}
		for(pit = m_pltPassenger->begin();pit!=m_pltPassenger->end();pit++)
		{
			ptmp = *pit;
			if(ptmp->GetObjFloor()>m_iLocation)
			{
				//电梯之中还有乘客要在当前楼层之上下梯.
				SetDirection(UP);
				return;
			}
		}
		SetDirection(DOWN); 
		return;	
	case DOWN:
		for(it = m_ltMessages.begin(); it!= m_ltMessages.end(); it++)
		{
			tmp = *it;
			if(tmp->OriFloor < m_iLocation)
			{
				//消息队列中还有乘客要上梯
				//电梯继续向下
				SetDirection(DOWN);
				return;
			}
		}
		for(pit = m_pltPassenger->begin();pit!=m_pltPassenger->end();pit++)
		{
			ptmp = *pit;
			if(ptmp->GetObjFloor() < m_iLocation)
			{
				//电梯之中中还有乘客要下梯.
				SetDirection(DOWN);
				return;
			}
		}
		SetDirection(UP); 
		return;
	case NONE:
		//如果电梯当前处于空闲状态,方向为NONE.
		//取出消息队列中的第一个消息,由它决定电梯的运行方向.
		tmp = m_ltMessages.front();
		if(tmp->OriFloor > m_iLocation ) SetDirection(UP);
		if(tmp->OriFloor < m_iLocation) SetDirection(DOWN);
		if(tmp->OriFloor==m_iLocation)
		{
			//如果电梯正在该层,检查改乘客是否已经在电梯中
			//分情况处理.
			floor = GetFloor(m_iLocation);
			pLst = floor->m_pltFPassengers;
			ptmp = pLst->GetPassengerByPID(tmp->PID);
			if(ptmp==NULL)
			{
				if(tmp->ObjFloor > m_iLocation ) SetDirection(UP);
				if(tmp->ObjFloor < m_iLocation)	 SetDirection(DOWN);
			}
			else SetStatus(WAIT);
		}
		return;
	default:
		break;
	}
}

void CElevator::SetDirection(EDIRECTION dir)
{
	m_enDirection = dir;
}

bool CElevator::IsQualifiedForRespondingCall(CMessage *msg)
{
// 该函数回答监视对象的询问: 能否对该请求提供服务;	
	if(!Reachable(msg->OriFloor) || !Reachable(msg->ObjFloor))
		return false;
	//if(IsOverloading()&&abs(m_iLocation-msg->OriFloor)<3) return false;
	if(IsIdle()) return true;
	if(m_enDirection==UP)
	{
		//同方向,当前楼层比请求者所在的楼层低
		if(msg->Direction==RUP && m_iLocation <= msg->OriFloor)
			return true;
		//不同方向,最高的目标楼层比请求者所在的楼层低
		//前提是当前层必须高于大于35层
		if(msg->Direction==RDOWN && GetHighestToGo()<msg->OriFloor)
			return true;
	}
	if(m_enDirection==DOWN)
	{
		//同方向, 当前楼层比请求者所在的楼层高
		if(msg->Direction==RDOWN && m_iLocation >= msg->OriFloor) 
			return true;
		//不同方向,最低层比请求者所在的楼层高
		//前提是已经有的请求小于5层
		if(msg->Direction==RUP && GetLowestToGo() > msg->OriFloor)
			return true;
	}
	return false;
}

bool CElevator::IsIdle()
{
	if(m_enStatus==IDLE) return true;
	else return false;
}
int CElevator::GetHighestToGo()
{
//获得电梯此时要到的最高层
	CMsgList::iterator it;
	CMessage* tmp;
	for(it=m_ltMessages.begin(); it!=m_ltMessages.end(); it++)
	{
		tmp = *it;
		if(tmp->OriFloor > 35 && tmp->OriFloor<=m_iLocation)
			return tmp->OriFloor;
		if(tmp->ObjFloor > 35 && tmp->OriFloor<=m_iLocation)
			return tmp->ObjFloor;
	}
	return m_iLocation;
}

int CElevator::GetLowestToGo()
{
// 获得电梯此时要到的最低层.
	CMsgList::iterator it;
	CMessage* tmp;
	for(it = m_ltMessages.begin();it!=m_ltMessages.end();it++)
	{
		tmp = *it;
		if(tmp->OriFloor < 5 )
			return tmp->OriFloor;
		if(tmp->ObjFloor < 5 )
			return tmp->ObjFloor;
	}
	return m_iLocation;
}
int CElevator::GetStopNums(CMessage *msg)
{
// 获得电梯若要到达消息指定的源楼层需要停留的时间
// 包括上下乘客的时间.
	CPassengerList::iterator it1;
	CMsgList::iterator it2;
	CPassenger* tmp1;
	CMessage* tmp2;
	int iCount=0;
//在乘客链表中找到在请求要上之前要下的乘客
	for(it1 = m_pltPassenger->begin();it1 != m_pltPassenger->end();it1++)
	{
		tmp1 = *it1;
		if(m_enDirection==UP) 
		{
			if(tmp1->GetObjFloor()>=m_iLocation && tmp1->GetObjFloor()<=msg->OriFloor)
			{
				iCount++;
			}
		}
		if(m_enDirection==DOWN) 
		{
			if(tmp1->GetObjFloor()<=m_iLocation && tmp1->GetObjFloor()>=msg->OriFloor)
			{
				iCount++;
			}
		}
	}
//在消息队列中找到在请求之前要下的乘客的个数
	for(it2 = m_ltMessages.begin();it2 != m_ltMessages.end();it2++)
	{
		tmp2 = *it2;
		if(m_enDirection==UP) 
		{
			if(tmp2->OriFloor>=m_iLocation && tmp2->OriFloor <= msg->OriFloor)
			{
				//该乘客在请求之前即下又上
				if(tmp2->ObjFloor<=msg->OriFloor) iCount= iCount+2;
				//上面已经计算过了
				else iCount++;
			}
		}
		if(m_enDirection==DOWN) 
		{
			if(tmp2->OriFloor <= m_iLocation && tmp2->OriFloor >= msg->OriFloor)
			{
				if(tmp2->ObjFloor>=msg->OriFloor) iCount = iCount+2;
				else iCount++;
			}
		}
	}
	return iCount;
}

⌨️ 快捷键说明

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