#include "T2CrossEquipArray.h" #include "T2FloorInfo.h" #include "T2FloorPtrList.h" #include "T2Mover.h" #include "T2MoverRoutingTable.h" #include "T2Request.h" #include "T2RoutingTable.h" #include "T2Tenant.h" T2MoverRoutingTable::T2MoverRoutingTable(T2FloorInfo* inFloorInfo, T2FloorPtrList* inFloorPtrList, T2Mover* inMover) : LArray(sizeof(T2RoutingTableElem)) { mMover = inMover; mFloorPtrList = inFloorPtrList; mFloorInfo = inFloorInfo; RECT rect; inMover->GetEquipArea(rect); mMoverHPos = (rect.left + rect.right) / 2; AddItems(mFloorPtrList->GetCount()); } /*virtual*/ T2MoverRoutingTable::~T2MoverRoutingTable() { } void T2MoverRoutingTable::AddItems(int inCount) { T2RoutingTableElem elem; InsertItemsAt(inCount, mItemCount + 1, &elem); } void T2MoverRoutingTable::RemoveItem(int inIndex) { RemoveItemsAt(1, inIndex); } void T2MoverRoutingTable::ClearData() { T2RoutingTableElem elem; AssignItemsAt(GetCount(), 1, &elem); } BOOL T2MoverRoutingTable::GetItem(int inIndex, T2RoutingTableElem& outItem) { return FetchItemAt(inIndex, &outItem); } BOOL T2MoverRoutingTable::IsStopFloor(int inIndex) { BOOL res = false; T2RoutingTableElem item; if (FetchItemAt(inIndex, &item)) res = item.IsStopFloor(); return res; } void T2MoverRoutingTable::SetStopFloor() { LArrayIterator iterator(*mMover->GetCEArray()); unsigned int id; while (iterator.Next(&id)) { int index = mFloorPtrList->GetIndex(id); T2RoutingTableElem item; item.SetTable(id, mMoverHPos); AssignItemsAt(1, index, &item); } } BOOL T2MoverRoutingTable::Update(T2MoverRoutingTable* inTable) { BOOL set = false; unsigned int numOfFloor = mFloorPtrList->GetCount(); for (unsigned int prevFloor = 1; prevFloor <= numOfFloor; prevFloor++) { if (!IsStopFloor(prevFloor) && inTable->IsStopFloor(prevFloor)) { for (unsigned int nextFloor = 1; nextFloor <= numOfFloor; nextFloor++) { if (nextFloor != prevFloor && inTable->IsStopFloor(nextFloor)) { T2RoutingTableElem elem; GetItem(nextFloor, elem); if (elem.HasRoute()) set |= IsUpdate(inTable, nextFloor, prevFloor, elem); } } } } return set; } BOOL T2MoverRoutingTable::IsUpdate(const T2MoverRoutingTable* inTable, unsigned int inNextFloorID, unsigned int inPrevFloorID, T2RoutingTableElem& inElem) { BOOL set = false; unsigned int hScore = CalcHScore(inTable->GetMoverHPos() - inElem.GetFinalHPos()); if (hScore < 120) { T2Mover *theMover = inTable->GetMover(); unsigned int vScore = theMover->CalcScore(mFloorPtrList->CalcDistance(inNextFloorID, inPrevFloorID)); unsigned int totalScore = hScore + vScore + inElem.GetScore(); if (theMover->IsElevator()) totalScore += 120; if (totalScore <= 1000) set = IsSetTable(inPrevFloorID, inElem.GetNextFloorID(), totalScore, 0, inTable->GetMoverHPos()); } return set; } BOOL T2MoverRoutingTable::IsSetTable(unsigned int inPrevFloorID, unsigned int inNextFloorID, unsigned int inScore, int inTime, int inFinalHPos) { BOOL set = false; T2RoutingTableElem item; if (FetchItemAt(inPrevFloorID, &item)) { if (item.IsSetTable(inNextFloorID, inScore, inTime, inFinalHPos)) { AssignItemsAt(1, inPrevFloorID, &item); set = true; } } return set; } int T2MoverRoutingTable::CalcHScore(int inDistance) { if (inDistance < 0) inDistance *= -1; return inDistance; } BOOL T2MoverRoutingTable::IsConnectRoute(int inFloorID) { BOOL result = false; T2RoutingTableElem item; if (FetchItemAt(inFloorID, &item)) result = item.HasRoute(); return result; } BOOL T2MoverRoutingTable::GetNextRoute(POINT inPt, unsigned int inFloorID, POINT& ioPt, unsigned int inFloorID2, unsigned int& outScore) { BOOL ok = false; T2RoutingTableElem item; FetchItemAt(inFloorID2, &item); if (item.HasNextRoute(inFloorID)) { outScore = CalcScore(inPt, ioPt, &item); ok = true; } return ok; } unsigned int T2MoverRoutingTable::CalcScore(POINT inPt, POINT& ioPt, T2RoutingTableElem* inElem) { #pragma var_order(theNextFloor, nextFloorArea, score, moverArea, theRequest, lobby, pt, isDown) T2Tenant *theNextFloor = mFloorInfo->GetTenant(inElem->GetNextFloorID()); #line 377 _ASSERT(theNextFloor != NULL); RECT nextFloorArea; theNextFloor->GetEquipArea(nextFloorArea); POINT pt; pt.y = nextFloorArea.bottom - 1; BOOL isDown = (pt.y - inPt.y) > 0; RECT moverArea; mMover->GetEquipArea(moverArea); if (isDown) pt.x = moverArea.right + 2; else pt.x = moverArea.left - 4; unsigned int score = inElem->GetScore() + mMover->CalcScore(pt.y - inPt.y); int lobby = mFloorInfo->GetGroundLine() - 1; if (inPt.y != lobby) score += CalcHScore(pt.x - inPt.x); if (ioPt.y != lobby) score += CalcHScore(ioPt.x - inElem->GetFinalHPos()); if (mMover->IsElevator()) score += 120; T2Request *theRequest = mMover->GetRequest(mFloorInfo, mMover->UnitToPosition(inPt.y), isDown); if (theRequest) score += theRequest->GetNumOfContent() * 10; ioPt = pt; return score; } T2Tenant* T2MoverRoutingTable::SelectNearFloor(POINT inPt, int& outFinalHPos, unsigned int& ioScore) { T2Tenant *result = NULL; ioScore -= CalcHScore(mMoverHPos - inPt.x); if (ioScore > 0) { LArrayIterator iterator(*this); T2RoutingTableElem item; int numOfFloor = 0; while (iterator.Next(&item)) { if (item.HasRoute() && ioScore > item.GetScore()) { int scoreThreshold = ioScore - item.GetScore(); T2Tenant *theNextFloor = mFloorInfo->GetTenant(item.GetNextFloorID()); if (theNextFloor) { RECT area; theNextFloor->GetEquipArea(area); int v = area.bottom - 1; if (scoreThreshold > mMover->CalcScore(v - inPt.y)) numOfFloor++; } } } if (numOfFloor > 0) { int randFloor = rand() % numOfFloor; int index = 0; iterator.ResetTo(0); while (!result && iterator.Next(&item)) { if (item.HasRoute() && ioScore > item.GetScore()) { int scoreThreshold = ioScore - item.GetScore(); T2Tenant *theNextFloor = mFloorInfo->GetTenant(item.GetNextFloorID()); if (theNextFloor) { RECT area; theNextFloor->GetEquipArea(area); int v = area.bottom - 1; if (scoreThreshold > mMover->CalcScore(v - inPt.y)) { if (index == randFloor) { result = theNextFloor; outFinalHPos = item.GetFinalHPos(); ioScore = scoreThreshold; } else { index++; } } } } } } } return result; }