Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 660 661 [662] 663 664 ... 796

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

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #9915 on: August 18, 2016, 08:27:23 pm »

You need to focus on data structures and how to work with them. Much of programming is having a toolkit of "solutions" (aka "patterns) to very simple problems, and being able to recognize when you can re-use one of those solutions to make whatever you need. And be able to refactor existing code in small steps. "knowing everything at the start" isn't how programming works. You break problems down into easier to understand components, and build up from the simplest system, in a consistent way.

e.g. the "Marines" example is a good test case. Say you want 10 marines, each marine is going to have stats and weapons. Start by just having an array of 10 ints, with each int holding "weapon type", with hard-coded weapons in code (e.g. "if (weaponType[ i ] == 2) cout << "power sword" etc). Try and make this, with just 2-3 weapon types.

So what's the logical next step here? Do only one thing. There are two choices. You could either improve the "marines" system, or you could improve the "weapons" system.

The weapon system obviously sucks since you have to edit the if statements whenever the weapon name gets printed out. So you can make an array of strings, which holds the weapon names. Hard-code this array, but use the marine's int to look up the value.

After you have the weapon look-up table working you can think of adding more data to the marines (each marine is just an int right now). The way to do this is refactoring. Make a struct which only holds a single int, then replace the int in the array with your struct. Re-wire all the references to the array to access the int.

Now, the above changes don't actually change what the program does, but they are the sort of framework-improving code that's critical to making the program better. Putting the weapon types into a table means it's much quicker to add new weapon types, and turning the marines into a struct allows you to add new variables for each marine more easily.
« Last Edit: August 18, 2016, 08:38:28 pm by Reelya »
Logged

Spehss _

  • Bay Watcher
  • full of stars
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #9916 on: August 20, 2016, 01:51:38 pm »

What's some methods of organizing data for something like a roguelike dungeon? I'm fiddling around with writing a dungeon generation algorithm. Maps consists of Tile objects which contain all the data pertaining to a single space of a dungeon. I was using a two dimensional array to hold all the Tile objects. It works but I'm starting to wonder if there's alternative and/or better ways. It feels clunky to have to specify the size of the 2nd dimension in the array every time I write a new function that takes that array as an argument.

One thing that comes to mind is a single dimensional array and each Tile in the array contains two ints for the x and y coordinate of that Tile.
Logged
Steam ID: Spehss Cat
Turns out you can seriously not notice how deep into this shit you went until you get out.

EnigmaticHat

  • Bay Watcher
  • I vibrate, I die, I vibrate again
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #9917 on: August 20, 2016, 07:19:50 pm »

That's how I do it.  There's a simple formula you can use to turn the position in the array into the coordinates, assuming tiles were entered into the array in ascending order of x values first and then y values, and you know the width and height of your dungeon.

Where n = position in the array, x and y are the coordinates in integers:

y = n / width
x = n % width

You can also invert it with:

n = y * width + x
Logged
"T-take this non-euclidean geometry, h-humanity-baka. I m-made it, but not because I l-li-l-like you or anything! I just felt s-sorry for you, b-baka."
You misspelled seance.  Are possessing Draignean?  Are you actually a ghost in the shell? You have to tell us if you are, that's the rule

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #9918 on: August 20, 2016, 08:44:36 pm »

What's some methods of organizing data for something like a roguelike dungeon? I'm fiddling around with writing a dungeon generation algorithm. Maps consists of Tile objects which contain all the data pertaining to a single space of a dungeon. I was using a two dimensional array to hold all the Tile objects. It works but I'm starting to wonder if there's alternative and/or better ways. It feels clunky to have to specify the size of the 2nd dimension in the array every time I write a new function that takes that array as an argument.

One thing that comes to mind is a single dimensional array and each Tile in the array contains two ints for the x and y coordinate of that Tile.

That method would have too much memory and speed overhead. Though it's useful to have separate data for creatures and objects that stores its own location.

The real solution is to not pass raw arrays around. Make a level object and pass a pointer/reference to that. The level object contains an array and x/y size information, plus any other level-specific stuff. Additionally, you set it up so that the array can by dynamically sized.

That's where EnigmaHat's idea comes in. Making a dynamic actual 2D array in C++ is a pain in the ass:
http://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new
When you make a static 2D array, it's tightly packed in memory and unpacks using the x/y values to look up the location. When you make a dynamic 2D array, it's done in a bullshit way with a for loop and a pointers-to-pointers, which means it needs to deference TWO pointers each time you access a map tile.

So what's better? make a 1D pointer, then wrap that inside your own custom container, which treats it like a 2D array. The only caveat is that you reference tiles by tile(x,y) rather than tile[ x ][ y ]

Spoiler (click to show/hide)

There you have a nice basic dynamic-sizable "2D" array class, and you only need to pass 1 parameter around, which is faster.
« Last Edit: August 20, 2016, 09:24:53 pm by Reelya »
Logged

ancistrus

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #9919 on: August 21, 2016, 11:20:49 am »

There is this program that generates sql queries (oracle).
It seems most of them end with - where rownum<=0

Is there EVER a good reason for that? Its so weird I am not even sure anymore.
Logged

miauw62

  • Bay Watcher
  • Every time you get ahead / it's just another hit
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #9920 on: August 21, 2016, 01:14:53 pm »

What's some methods of organizing data for something like a roguelike dungeon? I'm fiddling around with writing a dungeon generation algorithm. Maps consists of Tile objects which contain all the data pertaining to a single space of a dungeon. I was using a two dimensional array to hold all the Tile objects. It works but I'm starting to wonder if there's alternative and/or better ways. It feels clunky to have to specify the size of the 2nd dimension in the array every time I write a new function that takes that array as an argument.

One thing that comes to mind is a single dimensional array and each Tile in the array contains two ints for the x and y coordinate of that Tile.

That method would have too much memory and speed overhead. Though it's useful to have separate data for creatures and objects that stores its own location.

The real solution is to not pass raw arrays around. Make a level object and pass a pointer/reference to that. The level object contains an array and x/y size information, plus any other level-specific stuff. Additionally, you set it up so that the array can by dynamically sized.

That's where EnigmaHat's idea comes in. Making a dynamic actual 2D array in C++ is a pain in the ass:
http://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new
When you make a static 2D array, it's tightly packed in memory and unpacks using the x/y values to look up the location. When you make a dynamic 2D array, it's done in a bullshit way with a for loop and a pointers-to-pointers, which means it needs to deference TWO pointers each time you access a map tile.

So what's better? make a 1D pointer, then wrap that inside your own custom container, which treats it like a 2D array. The only caveat is that you reference tiles by tile(x,y) rather than tile[ x ][ y ]

Spoiler (click to show/hide)

There you have a nice basic dynamic-sizable "2D" array class, and you only need to pass 1 parameter around, which is faster.
Shouldn't it be possible to overload operators so you can do Tile tile = level[x][y]?
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.

cerapa

  • Bay Watcher
  • It wont bite....unless you are the sun.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #9921 on: August 21, 2016, 02:26:43 pm »

It is, but you need a secondary class for that. The overloaded [] would need to return an object that has an overloaded [] that returns the final value.

It's simpler to just make a get(int x, int y) method.
Logged

Tick, tick, tick the time goes by,
tick, tick, tick the clock blows up.

LoSboccacc

  • Bay Watcher
  • Σὺν Ἀθηνᾷ καὶ χεῖρα κίνει
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #9922 on: August 21, 2016, 02:36:30 pm »

it is indeed possible to overload [] and it's listed under 'madness', for example if you try to use the overloaded [] on a pointer instead of a reference it'll fail because is gonna index pointer type, while for arrays it is expected to be equivalent

http://www.learncpp.com/cpp-tutorial/98-overloading-the-subscript-operator/

just use a class with a deferred array and create method on top of it to access the array.
Logged

miauw62

  • Bay Watcher
  • Every time you get ahead / it's just another hit
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #9923 on: August 21, 2016, 02:40:48 pm »

huh, didn't know it was that hard to overload [] in C++. I thought it was easy, but I may have been thinking of C#
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.

Ghills

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #9924 on: August 21, 2016, 04:05:04 pm »

There is this program that generates sql queries (oracle).
It seems most of them end with - where rownum<=0

Is there EVER a good reason for that? Its so weird I am not even sure anymore.

Possibilities:

The coder didn't want to generate queries that could be run by someone too inexperienced to understand them.

There was an actual column 'rownum' which had some meaning,

Other han that, I've got nothing.
Logged
I AM POINTY DEATH INCARNATE
Ye know, being an usurper overseer gone mad with power isn't too bad. It's honestly not that different from being a normal overseer.
To summarize:
They do an epic face. If that fails, they beat said object to death with their beard.

TheDarkStar

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #9925 on: August 21, 2016, 06:10:38 pm »

It is, but you need a secondary class for that. The overloaded [] would need to return an object that has an overloaded [] that returns the final value.

It's simpler to just make a get(int x, int y) method.

No, you can do it with one class, but iirc you have your [] overload return a pointer to something rather than an actual value. (it's been a while since I've needed it and I don't think I have the code lying around anymore, sorry)
Logged
Don't die; it's bad for your health!

it happened it happened it happen im so hyped to actually get attacked now

LoSboccacc

  • Bay Watcher
  • Σὺν Ἀθηνᾷ καὶ χεῖρα κίνει
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #9926 on: August 22, 2016, 01:54:26 am »

It is, but you need a secondary class for that. The overloaded [] would need to return an object that has an overloaded [] that returns the final value.

It's simpler to just make a get(int x, int y) method.

No, you can do it with one class, but iirc you have your [] overload return a pointer to something rather than an actual value. (it's been a while since I've needed it and I don't think I have the code lying around anymore, sorry)


but if you return pointer you cannot call overloaded [] on it, you have to cast it out first, making it a clunky syntax mess where you overloaded to simplify a one line method call (!)
Logged

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #9927 on: August 22, 2016, 02:03:29 am »

besides, map.get(x,y) isn't all that complex compared to
Code: [Select]
map[x][y].
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

lethosor

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #9928 on: August 22, 2016, 08:51:32 pm »


but if you return pointer you cannot call overloaded [] on it, you have to cast it out first, making it a clunky syntax mess where you overloaded to simplify a one line method call (!)

If you're storing everything in a flat internal buffer (which appears to have been suggested above), operator[] could return a pointer to the middle of the buffer:

Code: [Select]
Thing *buffer;
Thing *operator[](int x) {
  return &buffer[x * height];  // or "buffer + (x * height)"
}

Then map[x][y] would effectively be the same as "buffer[(x * height) + y]".

I believe that's the idea TheDarkStar was getting at. Of course, it doesn't do any checking for invalid values of y, which could return items in other columns, but that's the same situation as the example for get() mentioned above. (It also relies on the data being grouped by column internally, but there may be a way to group it by row if you want, although it's an implementation detail that really shouldn't make a difference.)
« Last Edit: August 22, 2016, 08:55:08 pm by lethosor »
Logged
DFHack - Dwarf Manipulator (Lua) - DF Wiki talk

There was a typo in the siegers' campfire code. When the fires went out, so did the game.

LoSboccacc

  • Bay Watcher
  • Σὺν Ἀθηνᾷ καὶ χεῖρα κίνει
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #9929 on: August 23, 2016, 01:44:44 am »



Then map[x][y] would effectively be the same as "buffer[(x * height) + y]".


I understand that part about pointers, but I was specifically mentioning his previous idea of overloading subscripts, in which case the second [] call will be standard pointer offset and not the expected overloaded subscript unless, magic.
Logged
Pages: 1 ... 660 661 [662] 663 664 ... 796