C4ValueArray *C4FindObject::FindMany(const C4ObjectList &Objs, const C4LSectors &Sct) { // Trivial case if (IsImpossible()) return new C4ValueArray(); C4Rect *pBounds = GetBounds(); if (!pBounds) return FindMany(Objs); // Prepare for array that may be generated C4ValueArray *pArray; int32_t iSize; // Check shape lists? if (UseShapes()) { // Get area C4LArea Area(&Game.Objects.Sectors, *pBounds); C4LSector *pSct; C4ObjectList *pLst = Area.FirstObjectShapes(&pSct); // Check if a single-sector check is enough if (!Area.Next(pSct)) return FindMany(pSct->ObjectShapes); // Set up array pArray = new C4ValueArray(32); iSize = 0; // Create marker, search all areas uint32_t iMarker = ::Game.Objects.GetNextMarker(); for (; pLst; pLst = Area.NextObjectShapes(pLst, &pSct)) for (C4ObjectLink *pLnk = pLst->First; pLnk; pLnk = pLnk->Next) if (pLnk->Obj->Status) if (pLnk->Obj->Marker != iMarker) { pLnk->Obj->Marker = iMarker; if (Check(pLnk->Obj)) { // Grow the array, if neccessary if (iSize >= pArray->GetSize()) pArray->SetSize(iSize * 2); // Add object (*pArray)[iSize++] = C4VObj(pLnk->Obj); } } } else { // Set up array pArray = new C4ValueArray(32); iSize = 0; // Search C4LArea Area(&Game.Objects.Sectors, *pBounds); C4LSector *pSct; for (C4ObjectList *pLst = Area.FirstObjects(&pSct); pLst; pLst = Area.NextObjects(pLst, &pSct)) for (C4ObjectLink *pLnk = pLst->First; pLnk; pLnk = pLnk->Next) if (pLnk->Obj->Status) if (Check(pLnk->Obj)) { // Grow the array, if neccessary if (iSize >= pArray->GetSize()) pArray->SetSize(iSize * 2); // Add object (*pArray)[iSize++] = C4VObj(pLnk->Obj); } } // Shrink array pArray->SetSize(iSize); // Recheck object status (may shrink array again) CheckObjectStatus(pArray); // Apply sorting if (pSort) pSort->SortObjects(pArray); return pArray; }
// return is to be freed by the caller C4ValueArray *C4FindObject::FindMany(const C4ObjectList &Objs) { // Trivial case if (IsImpossible()) return new C4ValueArray(); // Set up array C4ValueArray *pArray = new C4ValueArray(32); int32_t iSize = 0; // Search for (C4Object *obj : Objs) if (obj->Status) if (Check(obj)) { // Grow the array, if neccessary if (iSize >= pArray->GetSize()) pArray->SetSize(iSize * 2); // Add object (*pArray)[iSize++] = C4VObj(obj); } // Shrink array pArray->SetSize(iSize); // Recheck object status (may shrink array again) CheckObjectStatus(pArray); // Apply sorting if (pSort) pSort->SortObjects(pArray); return pArray; }
C4Object *C4FindObject::Find(const C4ObjectList &Objs, const C4LSectors &Sct) { // Trivial case if (IsImpossible()) return NULL; C4Object *pBestResult = NULL; // Check bounds C4Rect *pBounds = GetBounds(); if (!pBounds) return Find(Objs); // Traverse areas, return first matching object w/o sort or best with sort else if (UseShapes()) { C4LArea Area(&Game.Objects.Sectors, *pBounds); C4LSector *pSct; C4Object *pObj; for (C4ObjectList *pLst = Area.FirstObjectShapes(&pSct); pLst; pLst = Area.NextObjectShapes(pLst, &pSct)) if (pObj = Find(*pLst)) if (!pSort) return pObj; else if (!pBestResult || pSort->Compare(pObj, pBestResult) > 0) if (pObj->Status) pBestResult = pObj; } else { C4LArea Area(&Game.Objects.Sectors, *pBounds); C4LSector *pSct; C4Object *pObj; for (C4ObjectList *pLst = Area.FirstObjects(&pSct); pLst; pLst = Area.NextObjects(pLst, &pSct)) if (pObj = Find(*pLst)) if (!pSort) return pObj; else if (!pBestResult || pSort->Compare(pObj, pBestResult) > 0) if (pObj->Status) pBestResult = pObj; } return pBestResult; }
int IBFact::GetCost() const { if (IsImpossible()) return INT32_MAX; return (IsTrue() ? 0 : 1); }
int32_t C4FindObject::Count(const C4ObjectList &Objs) { // Trivial cases if (IsImpossible()) return 0; if (IsEnsured()) return Objs.ObjectCount(); // Count int32_t iCount = 0; for (C4ObjectLink *pLnk = Objs.First; pLnk; pLnk = pLnk->Next) if (pLnk->Obj->Status) if (Check(pLnk->Obj)) iCount++; return iCount; }
int32_t C4FindObject::Count(const C4ObjectList &Objs) { // Trivial cases if (IsImpossible()) return 0; if (IsEnsured()) return Objs.ObjectCount(); // Count int32_t iCount = 0; for (C4Object *obj : Objs) if (obj->Status && Check(obj)) iCount++; return iCount; }
C4Object *C4FindObject::Find(const C4ObjectList &Objs) { // Trivial case if (IsImpossible()) return NULL; // Search // Double-check object status, as object might be deleted after Check()! C4Object *pBestResult = NULL; for (C4ObjectLink *pLnk = Objs.First; pLnk; pLnk = pLnk->Next) if (pLnk->Obj->Status) if (Check(pLnk->Obj)) if (pLnk->Obj->Status) { // no sorting: Use first object found if (!pSort) return pLnk->Obj; // Sorting: Check if found object is better if (!pBestResult || pSort->Compare(pLnk->Obj, pBestResult) > 0) if (pLnk->Obj->Status) pBestResult = pLnk->Obj; } return pBestResult; }
int32_t C4FindObject::Count(const C4ObjectList &Objs, const C4LSectors &Sct) { // Trivial cases if (IsImpossible()) return 0; if (IsEnsured()) return Objs.ObjectCount(); // Check bounds C4Rect *pBounds = GetBounds(); if (!pBounds) return Count(Objs); else if (UseShapes()) { // Get area C4LArea Area(&::Objects.Sectors, *pBounds); C4LSector *pSct; C4ObjectList *pLst = Area.FirstObjectShapes(&pSct); // Check if a single-sector check is enough if (!Area.Next(pSct)) return Count(pSct->ObjectShapes); // Create marker, count over all areas uint32_t iMarker = ::Objects.GetNextMarker(); int32_t iCount = 0; for (; pLst; pLst=Area.NextObjectShapes(pLst, &pSct)) for (C4Object *obj : Objs) if (obj->Status) if (obj->Marker != iMarker) { obj->Marker = iMarker; if (Check(obj)) iCount++; } return iCount; } else { // Count objects per area C4LArea Area(&::Objects.Sectors, *pBounds); C4LSector *pSct; int32_t iCount = 0; for (C4ObjectList *pLst=Area.FirstObjects(&pSct); pLst; pLst=Area.NextObjects(pLst, &pSct)) iCount += Count(*pLst); return iCount; } }