2

所以,我正在努力发明自己的瓦片地图创建,但我遇到了大小问题。最大尺寸(我没有设置)是 <700x700,任何更高的尺寸都会使其崩溃。首先,我认为这是我在制作“演示版本”时出错了不知道为什么。由于代码不是那么大,我将在这里展示它。如果你有一些建议,我不介意接受。

#include <iostream>
#include <string.h>
#include <fstream>
#include <ctime>
#include <cstdlib>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#define _WIN32_WINNT 0x0501
#include <windows.h>
using namespace std;

int main()
{

  sf::Vector2i Size;
  int Points,rands,PointsCheck=1,x,y,RandX,RandY,CurrentNumber=1;
  srand(time(0));
  bool Done=false,Expanded,Border;
  ofstream Out("txt.txt");
  /***/
  cout << "Size X-Y = "; cin >> Size.x >> Size.y;cout << endl;
  cout << "MAX Points - " << (Size.x*Size.y)/10 << endl;
  cout << "Number of POINTS = ";cin >> Points ;cout << endl;
  /***/
  int PixelMap[Size.x+1][Size.y+1];
  /***/
  for (x=1;x<=Size.x;x++) for (y=1;y<=Size.y;y++) PixelMap[x][y]=0;
  /***/
  while(PointsCheck<=Points)
    {
     rands=1+(rand()%10);
     RandX=1+(rand()%(Size.x));RandY=1+(rand()%(Size.y));
     if (rands==1 && PointsCheck<=Points && PixelMap[RandX][RandY]==0)
     {PixelMap[RandX][RandY]=CurrentNumber;CurrentNumber+=2;PointsCheck++;}
    }
  /***/
  while(Done==false)
   {
    Done=true;
    for(x=1;x<=Size.x;x++)
     for(y=1;y<=Size.y;y++)
      if(PixelMap[x][y]%2!=0 && PixelMap[x][y]!=-1)
       {
        if (PixelMap[x+1][y]==0) PixelMap[x+1][y]=PixelMap[x][y]+1;
        if (PixelMap[x-1][y]==0) PixelMap[x-1][y]=PixelMap[x][y]+1;
        if (PixelMap[x][y+1]==0) PixelMap[x][y+1]=PixelMap[x][y]+1;
        if (PixelMap[x][y-1]==0) PixelMap[x][y-1]=PixelMap[x][y]+1;
       }
    for(x=1;x<=Size.x;x++)
     for(y=1;y<=Size.y;y++)
      if(PixelMap[x][y]!=0 && PixelMap[x][y]%2==0) {PixelMap[x][y]--;Done=false;}
   }
   for(x=1;x<=Size.x;x++){
    for(y=1;y<=Size.y;y++)
     {Out << PixelMap[x][y] <<  " ";}Out << endl;}

   //ShowWindow (GetConsoleWindow(), SW_HIDE);
}
4

3 回答 3

0

不确定这是否与您的崩溃有关(我会添加评论,但我没有声誉),但这是我注意到的一个问题:

您的数组索引方案不一致。由于您使用索引 1 来指示第一个元素,因此您的边界检查应该如下所示......

if (y!=1 && y!=Size.y && x!=1 && x!=Size.x && ...

...而不是这个...

if (y!=0 && y!=Size.y && x!=0 && x!=Size.x && ...

[编辑]

我刚试过这个:

...
cout << "asdf" << endl;
int PixelMap[Size.x+1][Size.y+1];
cout << "asdf" << endl;
...

并验证这是一个堆栈溢出问题。所以,正如上面提到的其他人,在堆上分配你的像素图应该没问题。

顺便说一句,这段代码...

int PixelMap[Size.x+1][Size.y+1];

不是标准的 C++。这是一些编译器提供的扩展,称为“可变长度数组”。查看更多信息 ->为什么可变长度数组不是 C++ 标准的一部分?

[/编辑]

于 2013-08-15T05:15:05.183 回答
0

您在这里所拥有的是这个网站得名的概念。你有一个堆栈溢出:

int PixelMap[Size.x+1][Size.y+1];

如果要分配大量内存,则需要动态(在堆上)进行。

您可以通过多种方式做到这一点。由于您使用的是 C++,我建议使用std::vector. 唯一的技巧是使数组二维。通常,这与您在堆栈上分配的方式相同,只是您没有获得语言语法来帮助您:

vector<int> PixelMap( (Size.x+1) * (Size.y+1) );

上面,您需要从行/列计算线性索引。就像是:

int someval = PixelMap[ row * (size.y+1) + column ];

如果你真的想使用[row][column]索引语法,你可以制作一个向量的向量(不推荐),或者你可以索引你的行:

vector<int> PixelMapData( (Size.x+1) * (Size.y+1) );
vector<int*> PixelMap( Size.x+1 );
PixelMap[0] = &PixelMapData[0];

for( int i = 0; i < Size.x+1; i++ ) {
    PixelMap[i+1] = PixelMap[i] + Size.y + 1;
}

现在您可以在 2D 中建立索引:

int someval = PixelMap[row][col];
于 2013-08-15T01:59:47.693 回答
0

您的代码有几个问题:

首先:

int PixelMap[Size.x+1][Size.y+1];

 for (x=1;x<=Size.x;x++)
    for (y=1;y<=Size.y;y++)
         PixelMap[x][y]=0;

在上面的片段中,您永远不会设置 PixelMap[0][0] 或 PixelMap 0等的值。基本上这些值将是未定义的。C++ 中的数组索引为 0,因此您需要确保解决这些问题。另外,为什么要使用 Size.x+1 和 Size.y+1?对此感觉有些不对劲。

更好的循环是:

int PixelMap[Size.x][Size.y];
     for (x=0;x<Size.x;x++)
        for (y=0;y<Size.y;y++)
             PixelMap[x][y]=0;

其次,下一段代码难以辨认:

while(PointsCheck<=Points)
{
     rands=1+(rand()%10);
     RandX=1+(rand()%(Size.x));
     RandY=1+(rand()%(Size.y));
     if (rands==1 && PointsCheck<=Points && PixelMap[RandX][RandY]==0)
     {
       PixelMap[RandX][RandY]=CurrentNumber;
       CurrentNumber+=2;
       PointsCheck++;
     }
}

你只是增加 PointsCheck 如果

PointsCheck <= 点数

为什么?您在 while 条件下测试这是否为真。在此测试之前,PointsCheck 不会在任何地方增加。

rands顺便说一句,永远不能保证等于 1,因此您的循环可以永远持续下去(尽管不太可能)。

下一个循环遇到与上述类似的问题:

while(Done==false)
   {
    Done=true;

这是什么原因?你永远不会跳出 while 循环,也永远不会将 Done 设置为 false,因此下一个代码块只会执行一次。删除这个位。

for-loops的跟随应该从 0 开始并继续while < Size(Size.x 和 Size.y)

for(x=0;x<Size.x;x++)
     for(y=0;y<Size.y;y++)

先解决这些问题,如果你还有问题,我们可以继续。为了我们的缘故,请使用方括号{}来确定您的 for 循环和 if 语句的范围,以便我们可以遵循。此外,将命令分开到单独的行中。每行跟踪一个以上的分号对我们来说是很多工作。

编辑

由于您似乎不愿意首先解决这些问题:这可能是堆栈上为您的程序分配的内存量的问题。如果您尝试创建一个 800x800 整数数组,那么您将使用 800*800*4 字节 = 2.4 MB 的数据。我知道这高于 Visual Studio 的默认限制 1 MB,但由于 700x700 数组使用 1.8 MB,因此您使用的任何程序都有更高的默认值(或者您将 Visual Studio 设置得更高,但不够高)。

看看您是否可以将限制设置为至少 3 MB。不过,越多越好。如果这不能将您的缩放问题解决到 800,那么您还有其他问题。

编辑2

我刚刚注意到这一点:

 sf::Vector2i Size;
  //unimportant stuff
  cin >> Size.x >> Size.y;
  int PixelMap[Size.x+1][Size.y+1];

Vector2i 可能有 x 和 y 的默认值。如果你想动态分配比那些更多的东西,你不能静态地说

像素图[大小.x][大小.y]

您需要动态分配数组。我强烈建议为此使用 std::vector > 之类的东西

例如(未经测试的代码):

  sf::Vector2i Size;
  //unimportant stuff
  cin >> Size.x >> Size.y;
  std::vector<vector<int> > PixelMap;
  //Initialize values to 0
  for(size_t i=0; i < Size.x; ++i){
     vector<int> nextVec;
     for(size_t j=0; j < Size.y; ++j){
        nextVec.push_back(0);
      }
      PixelMap.push_back(nextVec);
  }
于 2013-08-15T02:35:58.913 回答