2011-12-01 4 views
0

이 하나가 저를 곤혹스럽게합니다. 나는 세 가지 클래스를 가지고 있는데, 이라는 큰 클래스는 Plant 인스턴스에 대한 포인터의 다차원 벡터와 Mob 인스턴스에 대한 포인터의 다차원 벡터를 포함합니다. 두 벡터는 위치에 따라 몹과 식물을 분류하기위한 것이므로, 가장 근접한 위치를 찾기 위해 기존의 모든 식물/몹을 순환하지 않고 각각의 벡터를 대략적인 위치로 검색 할 수 있습니다. 주어진 지점.고스트 인스턴스가 벡터로 표시됩니다.

벡터는 다음과 같습니다. 가장 작은 std :: vectors는 각면에 128 픽셀의 사각형 영역을 나타냅니다. 마피아와 식물은 X 및 Y 좌표를 128로 나눈 다음 적절한 섹터에 추가하여 분류됩니다 (결과 값이 정수가되도록주의해야합니다).

폭도 때로는 식물을 찾을 필요가

std::vector< std::vector< std::vector<Mob*> > >* m_AnimalSectors

std::vector< std::vector< std::vector<Plant*> > >* m_PlantSectors. 문제가 발생하는 곳은 다음과 같습니다. mob가 다차원 벡터를 쿼리하여 대략적인 영역에서 식물을 검색 할 때 (mob의 coords/128이 [1,2] m_PlantSectors [2] [1]을 검색하는 경우) 때로는 존재하지 않는 식물을 찾습니다.

뿐만 아니라 이러한 식물은 1.9777e + 33 또는 3.75853e-39 (예를 들어) 정도의 위치에 불가능합니다. 내가 선택한 식물의 색을 시각적으로 찾기 위해 빨간색으로 변경하려고하면 화면에있는 식물 (유일한 식물은 내가 손으로 직접 만든 식물 임) 중 색이 변하지 않은 것으로 나타났습니다.

모든 식물에 정수 ID를 표시했습니다. 1-36의 ID를 가진 36 개의 식물이 있지만, 내 mobs가 발견 한 식물은 63이나 429와 같은 ID를 가지고 있습니다. 식물이 그렇게 생성되지 않았기 때문에 존재할 수없는 것입니다. 지속적으로 얼마나 많은 식물이 존재 하는지를보고하므로 어떤 식물도 우연히 만들어지지 않습니다. 폭도들은 상상의 식물 다음으로 화면의 왼쪽 위 부분으로 흘러 나오고 굶어 죽는다.

어쨌든 나는 유령 식물을 창조합니다. 지금까지 Mob 인스턴스가 Plant 인스턴스를 찾을 수 있도록 두 가지 방법을 시도했습니다. 첫 번째는 다음과 같습니다

float TargetDist = 256 * 256; 
    Plant* Candidate = 0; 
    Plant* ForageTarget = 0; 
    int xSect = m_X/128; 
    int ySect = m_Y/128; 
    std::vector<Plant*> ThisSect = pLevel->CheckPSector(xSect, ySect); 
    for (int i = 0; i < ThisSect.size(); ++i) 
    { 
     cout << "Searching in Sector (" << ySect << ", " << xSect << ")\n"; 
     Candidate = ThisSect[i]; 
     cout << "Candidate at: " << Candidate->GetX() << ", " << Candidate->GetY() << "\n"; 
     Candidate->Mark(); 
     //Calculate distance 
     float xDist = Candidate->GetX() - m_X; 
     float yDist = Candidate->GetY() - m_Y; 
     float tDist = sqrt(xDist * xDist + yDist * yDist); 
     if (tDist <= TargetDist) 
     { 
      ForageTarget = Candidate; 
      TargetDist = tDist; 
     } 
    } 

CheckPSector()이 보이는 경우 :

std::vector<Plant*> Level::CheckPSector(int x, int y) 
{ 
    return m_PlantSectors[y][x]; 
} 

내가 시도 두 번째 일이 있었다 :

std::vector< std::vector< std::vector<Plant*> > >* Level::AccessPlantSectors() 
{ 
    return &m_PlantSectors; 
} 
이 사용

 float TargetDist = 256 * 256; 
     Plant* Candidate = 0; 
     Plant* ForageTarget = 0; 
     int xSect = m_X/128; 
     int ySect = m_Y/128; 
     std::vector< std::vector< std::vector<Plant*> > >* Sectors = pLevel->AccessPlantSectors(); 
     for (int i = 0; i < (*Sectors)[ySect][xSect].size(); ++i) 
     { 
      cout << "Searching in Sector (" << ySect << ", " << xSect << ")\n"; 
      Candidate = (*Sectors)[ySect][xSect][i]; 
      cout << "Candidate at: " << Candidate->GetX() << ", " << Candidate->GetY() << "\n"; 
      Candidate->Mark(); 
      //Calculate distance 
      float xDist = Candidate->GetX() - m_X; 
      float yDist = Candidate->GetY() - m_Y; 
      float tDist = sqrt(xDist * xDist + yDist * yDist); 
      if (tDist <= TargetDist) 
      { 
       ForageTarget = Candidate; 
       TargetDist = tDist; 
      } 
     } 

그러나이 두 가지 모두 상상의 식물을 발견하고 공허로 달아나는 동물을 학대합니다.

잠재적으로 큰 다차원 벡터를 Mob 인스턴스에 정기적으로 복사하지 않으려합니다. 한 번에 그러한 인스턴스가 많아지기 때문에 프로그램을 다소 원활하게 실행하고 싶습니다. 그럼에도 불구하고, 방금 관련성이있는 벡터 대신 전체 벡터를 복사하여 전체 작업을 수행하려고 시도했습니다. 동일한 결과를 얻었습니다 : 상상의 식물.

저는 전에 이런 문제가 없었습니다. 여기서 무슨 일이있을 수 있니?

EDIT : 내가 선택한 식물을 자신의 위치와 ID를 스스로보고하도록하는 것은 똑같이 실패하고, 어리석은 결과를 보이기 때문에 아마도 개인 회원에 액세스하는 데 사용되는 Plant의 기능이 아닙니다. 한편, 기존의 모든 식물을 쿼리해도 유령 식물이 자체보고하는 정보는 공개되지 않습니다. 이미 포인터를 가지고 있기 때문에

std::vector< std::vector< std::vector<Plant*> > >* m_PlantSectors 

그런 다음 Level::AccessPlantSectors()m_PlantSectors하지 &m_PlantSectors을 반환해야합니다 :로

+4

귀하의 질문은 꽤 길고 따라하기가 어렵습니다. 코드 및 시나리오를 단순화하고 자체 포함 된 테스트 케이스를 만들 수 있습니까? (http://sscce.org 참조) –

+0

네가 맞다고 생각해. 내가 좀 더 간단한 요리를 할 수 있는지 보겠다. 아마도 그렇게 할 때 내 자신의 질문에 답을 줄 것이다. – GarrickW

+1

왜 다차원 배열의 포인터를 사용하고 있는지 궁금합니다. 초기화되지 않은 메모리에서 나를 읽는 것과 같은 냄새가 난다. – LiMuBei

답변

2

m_PlantSectors하는 경우가 정의됩니다.

마찬가지로 Level::CheckPSector(int x, int y)[] 연산자를 호출하기 전에 포인터를 비준해야하기 때문에 (*m_PlantSectors)[y][x]을 반환해야합니다.

작성한대로 Level::CheckPSector(int x, int y)은 임의의 메모리를 반환하며 나는 Level::AccessPlantSectors()이 컴파일된다는 사실에 놀랐습니다.

+0

+1 다음을 위해 –

+0

죄송합니다. 나는이 사실을 너무 늦게 보았습니다. - 설명해 주셔서 감사합니다! 결국 코드를 ​​정리하고 식물을 힙의 위치에 대한 포인터로 저장함으로써 결국 문제를 극복 할 수있었습니다. – GarrickW