Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 493 494 [495] 496 497 ... 796

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

Spehss _

  • Bay Watcher
  • full of stars
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7410 on: May 16, 2015, 11:05:45 pm »

An array/vector of size "n" is always counted from 0 to n-1. This is because "myArray" is a pointer to the first allocated element, and the index is actually how many places beyond the start to access. if you count down, it must be from n-1 to zero. if you read/write past the end of an array, the results are undefined and may or may not crash unexpectedly.
Oooh. Thought vectors were different enough from arrays to not follow that rule of starting at zero.

Wasn't part of the appeal of vectors the fact that you didn't have to specify the size "limit" of the vector when initializing it like you would arrays and could just add to the vector as necessary? I have yet to find an example of this online. Is it done with the push_back modifier?

Spoiler: like this for example? (click to show/hide)

So vector stuff would contain {10, 20, 30}. Would it have a size of 3 and push_back adds a slot to the size or is the size just undefined and push_back adds data to th enext slot that doesn't have data?
Logged
Steam ID: Spehss Cat
Turns out you can seriously not notice how deep into this shit you went until you get out.

Skyrunner

  • Bay Watcher
  • ?!?!
    • View Profile
    • Portfolio
Re: if self.isCoder(): post() #Programming Thread
« Reply #7411 on: May 16, 2015, 11:07:03 pm »

it has a defined size. The first one is correct. push_back and one other function changes the actual size of the vector.
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 #7412 on: May 16, 2015, 11:12:46 pm »

Resizing vectors is expensive though. They're stored in a normal linear array, and when you resize that it copies the entire thing to an area of memory with more free space. So resizing is cool when they're small, but has a linear time cost based on the current length of the array. Keeping them linear in memory is required for fast access based on indexes, and the index operator [] doesn't check for resizing, since that would slow down every single vector operation with extra checking whenever you read or write a value.

This is the thing about fast low-level languages vs slow high-level ones. high-level scripting languages only give you "play knives" because it would be bad if you cut yourself with them, and they do extra checking every single CPU tick to make sure you're not cutting yourself with the play knife. Whereas C++ gives you direct memory-access arrays and vectors (which are a thin wrapper on direct-to-memory arrays), which are like professional super-sharp chef's knives. And they leave you in the kitchen by yourself and expect you to know how to cut everything up without losing a finger :)
« Last Edit: May 16, 2015, 11:25:25 pm by Reelya »
Logged

i2amroy

  • Bay Watcher
  • Cats, ruling the world one dwarf at a time
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7413 on: May 16, 2015, 11:31:29 pm »

Resizing vectors is expensive though.
Note: On average in C++ they are going to be constant time, because the vector automatically reserves extra whenever it runs out of space and only fills in the extra reserved amount when it needs to do so (so you only need an array resize every once in a while). That said if for some reason you had to add a very large number of objects to an array or you had a bit of code you needed to be very efficient (and you knew how many objects were being added) you might consider doing a vector.reserve(number of objects) first, then adding them. In general what the vector does automatically is going to be good enough for most uses, though.
Logged
Quote from: PTTG
It would be brutally difficult and probably won't work. In other words, it's absolutely dwarven!
Cataclysm: Dark Days Ahead - A fun zombie survival rougelike that I'm dev-ing for.

DJ

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7414 on: May 18, 2015, 07:40:35 am »

So I want to place a camera on a line so that the edges of it's field of view run through two arbitrary points on one side of the line. Here's a scheme I drew:
Spoiler (click to show/hide)
I was thinking that I need angles to A and B to be equal, therefore tangents of those angles must be equal, ie d1/(x - x1) = d2/(x2 - x).
Going through the steps:
Spoiler (click to show/hide)
However, placing the camera at x doesn't work out perfectly. Is there a flaw in my math, or is my issue with the variables I'm feeding it?
Logged
Urist, President has immigrated to your fortress!
Urist, President mandates the Dwarven Bill of Rights.

Cue magma.
Ah, the Magma Carta...

MagmaMcFry

  • Bay Watcher
  • [EXISTS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7415 on: May 18, 2015, 08:15:26 am »

If the camera points orthogonally away from x1x2, then your math is correct, and the images of the points should have equal distance from the center of the camera image. If you adjust the camera's FOV correctly (as a function of alpha), then both A and B should appear exactly at the edges of the screen.

What exactly doesn't work out perfectly?
Logged

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7416 on: May 18, 2015, 08:25:23 am »

So what are templates good for? From what I've seen of examples of it online I guess it's good for being able to process a range of variables without needing to be specified, like it can take ints or doubles or chars instead of having to define several functions for each variable type that all do the same thing.
...

Also Reelya, all I can find of "c++ grid class" is webpages for the Stanford cslib package. So I guess if I wanted to use grid I'd need to download the cslib package and #include the header file? Or am I completely misunderstanding your example with the template and grid?

There is nothing to download because the full functionality for a 2D array is right there. "grid" is just the name I called my array class. call it array2D or anything you like. it's meant to be a complete set of working code, but I had one typo. Doublechecking what's allowed, and it's not allowed to have two parameters when overloading the [] operator. So that was my bad, and an error (fixable by changing the operator[] to operator(), which does allow multiple parameters).

You can either use ( x,y ) or [ x ][ y ] to access the array.  Here's a working program illustrating using the (fixed) template class. I included both possible ways of indexing, but i recommend picking one style and deleting the unused operator. I have a feeling that the ( x , y ) version is slightly faster than the [ x ][ y ] version, since the [][] version casts the array address to a pointer, returns that to the calling code, then it gets dereferenced back to an actual variable.

Spoiler (click to show/hide)

There are several advantage of templates. For the "grid" object, since they're objects, you can pass them into functions as parameters and they remember their size. And when the object is destroyed, they remember to delete the data.

For templates in general some advantages of using them are:

  • reuse template classes in new projects without needing changes
  • improve your templates over multiple projects, so any problem with the template adds to your library
  • turn project-specific code into a template class, then you can more easily extract general functionality
  • template classes don't need to #include the header file of class that they are using. which reduces chains of header file dependencies and speeds up recompiles.
  • since templates don't know anything about the objects they're manipulating, it's harder to break them by changing the objects
  • templates are resolved at compile time, meaning more errors picked up before runtime
  • templates provide static polymorphism instead of dynamic polymorphism, which could be faster.
  • templates can pre-calculate any value since c++'s template system is turing-complete. as long your values are known at compile time, you can do arbitrarily complex caculations in zero runtime.

One thing I really like about templates is the possibility to provide polymorphism but without the different objects needing to be part of an inheritance tree. So no worry about virtual functions etc, just add in the single needed method in any class you pass into the template. The compile will tell you if you're missing the needed method.

Here's an example using a template function instead of a class:

Code: [Select]
#include <iostream>
using namespace std;

template <class T> void draw(T thing)
{
thing.draw();
};

class drawableThing
{
public:
void draw() { cout << "I'm being drawn!\n"; };
};

class differentDrawableThing
{
public:
void draw() { cout << "Put me on the screen!\n"; };
};

int main()
{
drawableThing thing;
draw(thing);

differentDrawableThing otherThing;
draw(otherThing);

while(1==1);
return 0;
}

This is an example of compile-time polymorphism, which generally runs faster and doesn't require you to have inheritance trees.
« Last Edit: May 18, 2015, 09:54:50 am by Reelya »
Logged

DJ

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7417 on: May 18, 2015, 08:43:20 am »

If the camera points orthogonally away from x1x2, then your math is correct, and the images of the points should have equal distance from the center of the camera image. If you adjust the camera's FOV correctly (as a function of alpha), then both A and B should appear exactly at the edges of the screen.

What exactly doesn't work out perfectly?
I was adjusting FoV, and the left object seemed to leave the camera frustum before the right one. So I turned off FoV adjustment and tried pausing the game and manually turning FoV up and down, and it did indeed appear closer to the edge than the right object, though it was inconsistent by how much. I also have a bit of camera jerkiness when it switches the object it's tracking (there's a group of objects moving to the right at variable speeds and the camera tries to track the rightmost and the leftmost from it's perspective to keep them all in view). That shouldn't be happening because the angle between camera and the old and camera and the new object that's being tracked should transition smoothly. I do assign the left and right object at the end of a frame, and they move in the next frame before I update camera position and FoV, but this movement over one frame @ 100+ FPS should be negligible. I'm not calling the camera adjustment function before everything is done either, because objects move in Update and cameras move in LateUpdate (I'm using Unity). I'm really at a loss as to what I'm doing wrong here. I'm glad to have confirmation that the math is good, though, so I don't waste time coming up with different formulas and focus on examining my variables.
Logged
Urist, President has immigrated to your fortress!
Urist, President mandates the Dwarven Bill of Rights.

Cue magma.
Ah, the Magma Carta...

AlleeCat

  • Bay Watcher
  • Black, the beast, descends from shadows...
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7418 on: May 18, 2015, 10:44:29 am »

So, anyone here know anything about Inform? It's really annoying that it doesn't really function like a normal programming language, but I'm trying to learn it all the same because I can't find a better IF engine.

Basically, in what I'm working on now, the main character is a robot. I want the character to be able to have programs in a separate "Installed" inventory, but I can't replace the inventory because I want them to be able to pick up and carry and wear things, as well. The documentation is very unhelpful about this, as it only distinguishes between a "carried" and "worn" inventory, which the engine already has infrastructure for.

Reelya

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7419 on: May 18, 2015, 03:20:51 pm »

Maybe if you treat the memory as a type of container. Then, it should be possible to make the memory also a worn object that can't be removed, and limit rules about the type of thing that can be put in the memory. There are Inform examples about how containers with liquids are modeled from first principles, so that would probably be a good starting point.

See example 266 from this document:

http://inform7.com/learn/man/plain-text-RB.txt
« Last Edit: May 18, 2015, 03:24:41 pm by Reelya »
Logged

bahihs

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7420 on: May 18, 2015, 06:57:58 pm »

I'm trying to generate wilderness maps for my ASCII game using libtcod.

I don't quite understand how to do this using libtcod's noise and height map generator, and then how to transpose this into an actual map with ASCII tiles. Can anyone help?

For the latter part, I think I can create the heightmap then iterate over all tiles and get the height value, then use that to draw characters on the a map. Its making the heightmap pesudo random using the noise generator that I'm confused over. The documentation is sparse on python examples, sadly.

« Last Edit: May 18, 2015, 06:59:50 pm by bahihs »
Logged

Spehss _

  • Bay Watcher
  • full of stars
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7421 on: May 18, 2015, 07:04:32 pm »

There's a python+libtcod based tutorial in roguebasin. I found it quite helpful for understanding how someone could go about generating random dungeon levels. Obviously the level of helpfulness depends on what language you're using for your own game, but I'd think the examples of the implementation of libtcod would be helpful.
Logged
Steam ID: Spehss Cat
Turns out you can seriously not notice how deep into this shit you went until you get out.

bahihs

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7422 on: May 18, 2015, 10:34:50 pm »

I know of that tutorial and I'm using python but the dungeon gen code does not use noise or a height map
Logged

breadman

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7423 on: May 19, 2015, 01:49:39 pm »

I don't quite understand how to do this using libtcod's noise and height map generator, and then how to transpose this into an actual map with ASCII tiles. Can anyone help?

It looks like the main interface you need is heightmap_add_fbm.  That requires a noise generator initialized with two dimensions, and has a slightly ridiculous number of options for scaling in various directions.  At its simplest:

Code: [Select]
h = 20
w = 50
noise = libtcod.noise_new(2)
heights = libtcod.heightmap_new(h, w)
libtcod.heightmap_add_fbm(heights, noise, 1, 1, 0, 0, 1, 0, 1)
libtcod.noise_delete(noise)

At this point, to determine which ASCII tile you want for a particular height, you'll need to translate the floating point values into integers, and iterate over them.  I'm going to normalize the values to make that easier:

Code: [Select]
tiles = "123456789"
libtcod.heightmap_normalize(heights, 0, len(tiles))
for y in range(h):
    for x in range(w):
        n = int(libtcod.heightmap_get_value(heights, x, y))
        sys.stdout.write(tiles[n])
    sys.stdout.write("\n")

(Fair warning: The code above is completely untested, and not particularly optimized.  I've used libtcod before, but not recently, and never the heightmap or noise generator.  Feel free to play with the fbm octaves in particular.)
Logged
Quote from: Kevin Wayne, in r.g.r.n
Is a "diety" the being pictured by one of those extremely skinny aboriginal statues?

bahihs

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #7424 on: May 19, 2015, 03:04:35 pm »

Thanks alot @breadman. That is really quite helpful. It looks like the heightmap_add_fbm function was indeed the missing link. I'll have to play with the noise generator a bit (to generate various types of maps) but I think I get it now.

A quick question though, given the function to add noise, what is the point of the add_hill and dig_hill functions and could those be used in conjunction with noise?

Thanks again.
Logged
Pages: 1 ... 493 494 [495] 496 497 ... 796