Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 470 471 [472] 473 474 ... 796

Author Topic: if self.isCoder(): post() #Programming Thread  (Read 909509 times)

XXXXYYYY

  • Bay Watcher
  • Been a long time.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7065 on: March 29, 2015, 05:50:08 pm »

ptw 3x combo
Logged
Oooooooo. I know. ClF3. That should be a fun surprise.

HavingPhun

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7066 on: March 29, 2015, 06:16:10 pm »

So, I have tried to learn c++ multiple times over the years with limited success, but each time I get a little better at it. Currently I am at the beggining of the development of a roguelike type thing and am working on world generation right now. I am having trouble figuring out how to do this.

First, I'll just discuss my main problem, then I'll get into the rest. I have a class called Tile, which will basically be used to store the information on each of the world tiles, and my idea for storing the main world map was to just make a multidimensional array and store many Tile class objects in it. The declaration for it went like this:

Code: [Select]
Tile WorldTileArray[123][123];

But, if I have this in my code, my program crashes. If I comment it out, it does not crash. So, am I allowed to just create an array like this and fill it with all of those empty Tile objects, or should I do something like this instead?

Code: [Select]
std::map <int, Tile*> WorldTileMap(15376);

I could make the 2nd example work, but would rather use the multidimensional array since it would be easier to determine which tiles are adjacent to each other.

The above problem is more important, but I also have another question. For my first version of the world generation, I am just going to apply simplex noise to each world tile to determine the height, by looping through the array of all the tiles and applying the noise to each. Then, based on the height, determine if it is a mountain, flatland, or ocean. Would this approach actually create coherent terrain and landmasses, or would it just be some huge mess? Would I need to somehow apply the noise to the entire map at once?

Anyways, thank you ahead of time for any help, and let me know if you need more information, or if I need to explain what I am saying more.
« Last Edit: March 29, 2015, 06:18:44 pm by HavingPhun »
Logged

Moghjubar

  • Bay Watcher
  • Science gets you to space.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7067 on: March 29, 2015, 09:27:02 pm »

Looks like stack overflow to me.

http://www.programmerinterview.com/index.php/data-structures/difference-between-stack-and-heap/

Also... you can use a single dimension tile array and still determine adjacencies easily... via math.

Code: [Select]
struct mapcoords
{
    int mapx;
    int mapy;
};

int x = 3;
int y = 4;
mapcoords tilemap[x*y];  //3*4, or [3][4]
for (int y_iter = 0; y_iter < y; y_iter++)
{
   for (int x_iter = 0; x_iter < x; x_iter++)
   {
       tilemap[x_iter+(y_iter*x)].mapx = x_iter;
       tilemap[x_iter+(y_iter*x)].mapy = y_iter;
       std::cout << tilemap[x_iter+(y_iter*x)].mapx << " , " << tilemap[x_iter+(y_iter*x)].mapy << "  |  ";
   }
   std::cout << std::endl;
}

system("pause");

Output:
Code: [Select]
0 , 0  |  1 , 0  |  2 , 0  |
0 , 1  |  1 , 1  |  2 , 1  |
0 , 2  |  1 , 2  |  2 , 2  |
0 , 3  |  1 , 3  |  2 , 3  |
Press any key to continue . . .
Logged
Steam ID
Making things in Unity
Current Project: Demon Legend
Made This too (publisher abandoned ) Farworld Pioneers
Mastodon

Spehss _

  • Bay Watcher
  • full of stars
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7068 on: March 29, 2015, 09:46:57 pm »

Can you not read spaces with fstream in c++? Trying to read in a message from a text file that says "this is a test" and put each char into an array slot to be printed out character by character. It prints out "thisisatest" with no spaces.
Logged
Steam ID: Spehss Cat
Turns out you can seriously not notice how deep into this shit you went until you get out.

XXXXYYYY

  • Bay Watcher
  • Been a long time.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7069 on: March 29, 2015, 10:24:40 pm »

Can you not read spaces with fstream in c++? Trying to read in a message from a text file that says "this is a test" and put each char into an array slot to be printed out character by character. It prints out "thisisatest" with no spaces.
Are you using .get ? The basic >> operator doesn't read in spaces/other whitespace, same as with cin.
« Last Edit: March 29, 2015, 10:27:11 pm by XXXXYYYY »
Logged
Oooooooo. I know. ClF3. That should be a fun surprise.

Spehss _

  • Bay Watcher
  • full of stars
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7070 on: March 29, 2015, 10:31:14 pm »

Can you not read spaces with fstream in c++? Trying to read in a message from a text file that says "this is a test" and put each char into an array slot to be printed out character by character. It prints out "thisisatest" with no spaces.
Are you using .get ? The basic >> operator doesn't read in spaces/other whitespace, same as cin.
Well that fixed it. Thanks.
Logged
Steam ID: Spehss Cat
Turns out you can seriously not notice how deep into this shit you went until you get out.

HavingPhun

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7071 on: March 30, 2015, 08:58:36 am »

snip.
Alright, thank you, I will try this out. Some things in programming, even simple things, are just incomprehensible to me.
Logged

HavingPhun

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7072 on: March 30, 2015, 10:40:55 am »

I am going to base my first version of world generation roughly on this: http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/

The problem is that my knowledge of mathematics doesn't seem to be up to par with this, and is probably the reason why I have been trouble understanding all of the things I have been reading about world generation. I am going to look up the things mentioned in the article, such as Voronoi polygons, Delaunay triangulation, and Lloyd relaxation (whatever those are).

But, my question is, what sort of mathematics should I study in order to have an understanding of the things mentioned in the article and things like simplex noise? My current knowledge is at the level of basic trigonometry, and geometry.
Logged

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7073 on: March 30, 2015, 10:45:14 am »

It would be a lot easier to start with tiles and perlin noise, than to start with the stuff in that article. Look up 2D perlin noise for terrain generation / heightmaps.

~~~

Yeah, I'm not a huge fan of Moghjubar's implementation because it introduces redundancy / takes much more memory: since every tile both has an index and contains it's own coords. You can get that information just from the index.

The issue with stack vs heap is when you create arrays locally inside a function. Then, they are basically created in "temporary" memory which has strict limits. Try creating the array smaller to start with and see if this is the reason.

Another possibility is that there's something wrong with the class you've created "Tile". Maybe it has a constructor that is broken? Are there any pointers used inside the class? Perhaps something is being accessed before it is set. Without seeing the "Tile" class it's impossible to rule this out: if an array of custom objects is causing a crash, it is vital to know what the custom objects actually are.

If you really need a large array defined locally inside a function, remember that it will get deleted when the function leaves. If you still want this, use new/delete to create and destroy it manually when you leave the function. Better still, make the whole thing into an object itself, and have it handle it's own new and delete inside itself:

Code: [Select]
class Tilemap
{
    Tile *data; // the data
    int x, y; // the dimensions

public:
    int sizeX() { return x; }
    int sizeY() { return y; }
   
    Tilemap(int _x, int y) : x(_x), y(_y) // set the dimensions
    {
        data = new Tile[x * y];
    }

    ~Tilemap() // called when the class is destroyed
    {
        delete [] data; // delete must always match new. the constructor and destructor are sensible places for these.
    }

    Tile &operator[](int x1, int y1) // defines [] operator for this class, taking x and y inputs
    {
        return data[x1 + y1 * x]; // converts x and y to 1-dimensional array index, returns reference to the entry
    }
};


The above class can actually be accessed like an array, but it's smart enough to free up memory if the entire object leaves scope.

//create the thing and set the dimensions
Tilemap tilemap(123,123);

//set tile which has x = 0, y = 13
tilemap[0, 13] = //stuff

if(tilemap[0, 13] == // whatever)
   // do things

You can also query the size by asking for tilemap.sizeX() and tilemap.sizeY()
« Last Edit: March 30, 2015, 10:56:53 am by Reelya »
Logged

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #7074 on: March 30, 2015, 11:15:09 am »

Or if you're going to use classes anyways, go one step further and use std::vector instead of an array!
Logged

bay12 lower boards IRC:irc.darkmyst.org @ #bay12lb
"Oh, they never lie. They dissemble, evade, prevaricate, confoud, confuse, distract, obscure, subtly misrepresent and willfully misunderstand with what often appears to be a positively gleeful relish ... but they never lie" -- Look To Windward

Moghjubar

  • Bay Watcher
  • Science gets you to space.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7075 on: March 30, 2015, 11:19:57 am »


Yeah, I'm not a huge fan of Moghjubar's implementation because it introduces redundancy / takes much more memory: since every tile both has an index and contains it's own coords. You can get that information just from the index.


Indeed, it was meant to be a teaching example that shows they are the same thing.
Logged
Steam ID
Making things in Unity
Current Project: Demon Legend
Made This too (publisher abandoned ) Farworld Pioneers
Mastodon

HavingPhun

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7076 on: March 30, 2015, 11:42:40 am »

It would be a lot easier to start with tiles and perlin noise, than to start with the stuff in that article. Look up 2D perlin noise for terrain generation / heightmaps.

I know what you mean, start simple then expand from there. But, I have this idea that I might as well just do it completely and fully how I want to the first time, and I don't really understand perlin that well either. What sort of mathematics should I study to understand both noise, and the link I posted?

It would be a lot easier to start with tiles and perlin noise, than to start with the stuff in that article. Look up 2D perlin noise for terrain generation / heightmaps.

~~~

Yeah, I'm not a huge fan of Moghjubar's implementation because it introduces redundancy / takes much more memory: since every tile both has an index and contains it's own coords. You can get that information just from the index.

The issue with stack vs heap is when you create arrays locally inside a function. Then, they are basically created in "temporary" memory which has strict limits. Try creating the array smaller to start with and see if this is the reason.

Another possibility is that there's something wrong with the class you've created "Tile". Maybe it has a constructor that is broken? Are there any pointers used inside the class? Perhaps something is being accessed before it is set. Without seeing the "Tile" class it's impossible to rule this out: if an array of custom objects is causing a crash, it is vital to know what the custom objects actually are.

If you really need a large array defined locally inside a function, remember that it will get deleted when the function leaves. If you still want this, use new/delete to create and destroy it manually when you leave the function. Better still, make the whole thing into an object itself, and have it handle it's own new and delete inside itself:

Code: [Select]
class Tilemap
{
    Tile *data; // the data
    int x, y; // the dimensions

public:
    int sizeX() { return x; }
    int sizeY() { return y; }
   
    Tilemap(int _x, int y) : x(_x), y(_y) // set the dimensions
    {
        data = new Tile[x * y];
    }

    ~Tilemap() // called when the class is destroyed
    {
        delete [] data; // delete must always match new. the constructor and destructor are sensible places for these.
    }

    Tile &operator[](int x1, int y1) // defines [] operator for this class, taking x and y inputs
    {
        return data[x1 + y1 * x]; // converts x and y to 1-dimensional array index, returns reference to the entry
    }
};


The above class can actually be accessed like an array, but it's smart enough to free up memory if the entire object leaves scope.

//create the thing and set the dimensions
Tilemap tilemap(123,123);

//set tile which has x = 0, y = 13
tilemap[0, 13] = //stuff

if(tilemap[0, 13] == // whatever)
   // do things

You can also query the size by asking for tilemap.sizeX() and tilemap.sizeY()
If the dimensions are constant, there is no real reason to use an std::vector. At least, if you do, use reserve() to reserve the expected space. Otherwise, you're just misusing vectors.
Or if you're going to use classes anyways, go one step further and use std::vector instead of an array!

So, this line would create a new array of Tile objects of the size specified the constructors arguments, and set the pointer data to point to it?

Code: [Select]
data = new Tile[x * y];

To be honest, the only reason that I had wanted to use a multidimensional array is because I was being a bit lazy, and figured that it would be easier to determine which cells are adjacent to each other, which it turns out it would be just as easy with a vector, map, or even a single-dimensional array.

So, thank you all for your help, and sorry if I ask questions that seem rather simple, or seem oblivious to certain things. Programming hasn't really clicked with me yet.
« Last Edit: March 30, 2015, 11:44:49 am by HavingPhun »
Logged

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #7077 on: March 30, 2015, 11:48:30 am »

If the dimensions are constant, there is no real reason to use an std::vector. At least, if you do, use reserve() to reserve the expected space. Otherwise, you're just misusing vectors.
well, a dynamically allocated array is almost always worse than a vector. The cases where it's better are probably pretty fringe. And yes, reserve() is good if you're doing push_back (), otherwise allocate the entire thing at once with the proper constructor. :D
Logged

bay12 lower boards IRC:irc.darkmyst.org @ #bay12lb
"Oh, they never lie. They dissemble, evade, prevaricate, confoud, confuse, distract, obscure, subtly misrepresent and willfully misunderstand with what often appears to be a positively gleeful relish ... but they never lie" -- Look To Windward

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7078 on: March 30, 2015, 12:05:54 pm »

It would be a lot easier to start with tiles and perlin noise, than to start with the stuff in that article. Look up 2D perlin noise for terrain generation / heightmaps.

I know what you mean, start simple then expand from there. But, I have this idea that I might as well just do it completely and fully how I want to the first time, and I don't really understand perlin that well either. What sort of mathematics should I study to understand both noise, and the link I posted?

No, that's not the right way to look at it. If you try to build some super-dooper magical system all at once, you will fail. This is not hype. You will just fail and give up.

Do the simple stuff first. Everything is incremental and builds on top of the knowledge you gain. The all-or-nothing approach to programming isn't a good idea.

With perlin noise you can build everything up to 3D spinning planets with jagged terrain. And it's needed to roughen-up the polygon-based stuff later. Those types of things build on top of each other so you should implement them in stages. Plus the data structures for those voronoi based things are much less straightforward than working with grids. That's they type of thing you want to add to a terrain generator once you have the noise and heightmaps already working: there are many ways to implement continents and other macro-features, and if you build them from the ground-up then it will be very hard to adapt your algoritm later, compared to creating a heightmap generator system, then adding code for continents afterwards.
« Last Edit: March 30, 2015, 12:11:26 pm by Reelya »
Logged

miauw62

  • Bay Watcher
  • Every time you get ahead / it's just another hit
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7079 on: March 30, 2015, 12:50:48 pm »

Multi-dimensional arrays are a PITA, especially if you ever want to pass them as an argument. I also recommend using vector<vector<>>, even if that means slightly worse performance/slightly more required memory (which you won't notice. At all. Seriously. Modern computers are REALLY FUCKING FAST).

Reelya's class seems like a better solution than a nested vector, though.

Anyway, I'll just say this again: Don't micro-optimize. For something like a roguelike you won't notice anything about the performance unless you start doing really dumb stuff. Keep the code neat and readable. Modern computers are fast.
Logged

Quote from: NW_Kohaku
they wouldn't be able to tell the difference between the raving confessions of a mass murdering cannibal from a recipe to bake a pie.
Knowing Belgium, everyone will vote for themselves out of mistrust for anyone else, and some kind of weird direct democracy coalition will need to be formed from 11 million or so individuals.
Pages: 1 ... 470 471 [472] 473 474 ... 796