#ifndef _3D_ARRAY_CHECKER_H_ #define _3D_ARRAY_CHECKER_H_ #include class C3DArrayChecker { public: C3DArrayChecker(TakeType::TakeSource eTakeSource) : m_eTakeSource(eTakeSource) { } virtual void Set(Item::ItemPos itemPos, int nXSize, int nYSize) = 0; virtual bool Test(Item::ItemPos itemPos, int nXSize, int nYSize) = 0; virtual bool FindEmptyPos(Item::ItemPos& foundPos, int nXSize, int nYSize) = 0; protected: TakeType::TakeSource m_eTakeSource; }; template class C3DItemArrayChecker : public C3DArrayChecker { public: C3DItemArrayChecker(TakeType::TakeSource eTakeSource) : C3DArrayChecker(eTakeSource) { memset(m_Set, 0, sizeof(char) * tX * tY * tZ); } virtual void Set(Item::ItemPos itemPos, int nXSize, int nYSize) { int nZ = itemPos.GetZIndex(); if(nZ < tZ) { int nY = itemPos.GetYIndex(); int nX = itemPos.GetXIndex(); int nMaxY = std::min(nY + nYSize, tY); int nMaxX = std::min(nX + nXSize, tX); for(nY = itemPos.GetYIndex(); nY < nMaxY; ++nY) { for(nX = itemPos.GetXIndex(); nX < nMaxX; ++nX) { m_Set[nX][nY][nZ] = 1; } } } } virtual bool Test(Item::ItemPos itemPos, int nXSize, int nYSize) { int nZ = itemPos.GetZIndex(); int nY = itemPos.GetYIndex(); int nX = itemPos.GetXIndex(); int nMaxY = std::min(nY + nYSize, tY); int nMaxX = std::min(nX + nXSize, tX); if(tZ <= nZ || tY <= nMaxY || tX < nMaxX) { return false; } for(nY = itemPos.GetYIndex(); nY < nMaxY; ++nY) { for(nX = itemPos.GetXIndex(); nX < nMaxX; ++nX) { if(0 != m_Set[nX][nY][nZ]) { return false; } } } return true; } virtual bool FindEmptyPos(Item::ItemPos& foundPos, int nXSize, int nYSize) { for(int nZ = 0; nZ < tZ; ++nZ) { for(int nY = 0; nY < tY; ++nY) { for(int nX = 0; nX < tX; ++nX) { foundPos.SetPos(nX, nY, nZ); if(Test(foundPos, nXSize, nYSize)) { foundPos.m_cPos = static_cast(m_eTakeSource); return true; } } } } return false; } private: char m_Set[tX][tY][tZ]; }; #endif