Does anyone here have a sample of code they used for data in thier game which uses Vectors?
Yes, me and my Eglish teacher did not see eye to eye.
There's some really nice Vector code in Openlayer. You can download it here .
I mean like, I use Structs to contain all of my Race data for each Castle in my game. Is it possiable to use Vector to store several ints?
I'm really tired (waiting for a backup process to complete) so I'm not going to test it, but if I made no mistakes it should output:
[1,12,23,34,45,56] [1,12,23,34,45,56]
Your code is readable and I appreciate it. I guess what I'm asking for is, would it be possiable to use a vector like a struct..
like...
struct Character { int Hitpoints; int Magicpoints; int Strength; }GoodGuys[10]; GoodGuys[0].Hitpoints=50; GoodGuys[0].Magicpoints=10;
and so on...
It would be nice to use a vector or something like it that could enable me to easily kill of GoodGuys[5] and still keep the data for GoodGuys[4] with GoodGuys[6] data replacing GoodGuys[5].
I have ways to code around it, but is there an easier way with STL?
The real difference is that when you're adding items to a vector, you use push_back(), like bamccaig showed. (Note to bamccaig: Line 35 )
Once you've pushed all of the numbers onto the array that you want, you can index them with the normal "[]" brackets like you do with a normal array:
std::vector<int> array; array.push_back(10); array.push_back(-13); // ... array.push_back(6); int current_value = array[0]; // 0th element, value of "10" int next_value = array[1]; // 1st element, value of "-13" // ...
EDIT:
I guess what I'm asking for is, would it be possiable to use a vector like a struct..
Yes, absolutely you can do something like this. That's what the std::vector was made for. You define the "type" of vector using the "<" and ">" brackets:
So then with my GoodGuys code, I'd have to make a seperate Vector for every Struct element? Like
std::vector<int> GoodGuyHitpoints; std::vector<int> GoodGuyMagicpoints; GoodGuyHitpoints.push_back(10); GoodGuyHitpoints.push_back(8); GoodGuyMagicpoints.push_back(5);
And so on...
Is there a way to group certain Vectors together like a struct, and give it a common name like I did for my struct Char?
[EDIT]
Oh my Gosh, you just changed my world... I never knew you could vector an entire struct...
I'm absolutely shocked!
and so on...
It would be nice to use a vector or something like it that could enable me to easily kill of GoodGuys[5] and still keep the data for GoodGuys[4] with GoodGuys[6] data replacing GoodGuys[5].
I have ways to code around it, but is there an easier way with STL?
No, no, no. Unless a single GoodGuy has multiple Hitpoints, which I don't think you want.
You want to have multiple Characters. Each Character will have its own "Hitpoints", "Magicpoints", etc. as defined in the struct that you provided earlier.
If you have "GoodGuys" defined as the vector, it's the same as having:
Character GoodGuys[3]; GoodGuys[0].Name="Bob"; GoodGuys[0].Hitpoints=50; GoodGuys[0].Magicpoints=10; GoodGuys[1].Name="Fredrick"; GoodGuys[1].Hitpoints=75; GoodGuys[1].MagicPoints=5;
... and so on.
"Bob" will only have a single set of Hitpoints, value 50. "Fredrick" will have 75 Hitpoints. "Jimmy" will have his own.
What you were asking is the equivalent of "Bob" having 10 Hitpoints, as well as 8 Hitpoints, etc.
Yeah I saw the error of my ways after the last two responses were given...
In regards to LennyLen post, if I delete GoodGuys[5], would GoodGuys[6]'s data take it's place an so on until the entire Vector was one shorter in length?
GoodGuys.erase(GoodGuys.begin() + 4); // erases GoodGuys[5]
[EDIT]
Vector reminds me of the push pop in Assembly Language.
In regards to LennyLen post, if I delete GoodGuys[5], would GoodGuys[6]'s data take it's place an so on until the entire Vector was one shorter in length?
GoodGuys.erase(GoodGuys.begin() + 4); // erases GoodGuys[5]
Yes.
Therefore, if you think that you'll be deleting a lot of stuff in the middle, you may want to look into linked lists: std::list
It follows the same format as std::vector: std::list<Character>
The difference is that if you're iterating through linked lists, it takes a lot longer (because it has to start at "node 0" and iterate through each one before coming to "node 17"). With vectors, you can point right to it by simply saying "GoodGuys[17]". However, if you delete from the middle of a linked list, it unhooks the previous Node and the next Node, attaches them together, and gets rid of the one that you specified to remove.
You can get around this by a simple trick (if order doesn't matter): take the LAST element in the vector, stick it where the current element is, and then delete from the end of the vector. Then you don't have to shift all 1,000 other "Character" elements "up one".
But if order does matter, you'll just have to settle for the "shift up one" when you remove that element. ::shrug::
EDIT: Explained more. Long-winded. Yup, yup.
Your pretty smart for a Cop...Wolf...
I'm looking at erasing a vector each time a troop dies. So it would be about 1 every 2 mins or so. And my vector Struct will contain 8 kingdoms worth of 20-50 troops.
Vector sounds like the way to go...but I'll read about the List you are talking about.
protip:
Goalie:
Explain that for me; I'm not used to c++0x.
Nakhash: Since you're not going to be removing them every second, std::vector sounds about right for you. The only two things you'll want to consider when doing this is:
1) If you have a LOT of elements in the array, and you remove Troops from (or near) the front of that vector, you'll have a lot of shifting to do.
2) If the order of the troops don't matter much in the overall design of the game, swapping the last element with the to-be-removed element should be considered.
I don't know how much you've worked with pointers, but I've actually found it worthwhile for me to store a vector of points to the structs/classes that I've created. Then, if you do something like "array[current_index] = array[another_index];", it won't COPY the object using the object's assignment operator ( Troop& operator= (const Troop& rhs); ). It will just copy the pointer address and you're done.
The only real overhead you have with this is that you must call new() and delete() yourself. Passing by reference, instead of passing by pointer, does all of this for you (even calling the destroyed object's destructor when appropriate), though you incur the "deep" or "shallow" copy I just mentioned.
OnlineCop:
1) If you have a LOT of elements in the array, and you remove Troops from (or near) the front of that vector, you'll have a lot of shifting to do.
2) If the order of the troops don't matter much in the overall design of the game, swapping the last element with the to-be-removed element should be considered.
Nakhash Reply:
I shouldn't have a lot of elements. It should be about 5 Vector structs total with the biggest one being 100 or so...
I use a lot of Structs referencing other structs which references another struct. It's like a long line of code that equals 5 or something. It enables me to not reference or make duplicates of data.
An example would be for my current game.
[EDIT]
Yes I've used pointers before, but I think I'll stick to the Vecter approach that was given to me. Currently I only use pointers for char that I want used in another function without declaring a global char.
OnlineCop:
1) If you have a LOT of elements in the array, and you remove Troops from (or near) the front of that vector, you'll have a lot of shifting to do.
2) If the order of the troops don't matter much in the overall design of the game, swapping the last element with the to-be-removed element should be considered.
Nakhash Reply:
You can use <quote>...</quote> tags if it helps.
Okay...
Since your
and your
contain two of the same variables, why not use inheritance?
struct ClassDef { int Strength; int Defense; };struct UnitsDef : public ClassDef{ int ClassID; int Level; // UnitsDef now contains Strength and Defense, as inherited from ClassDef };
I shouldn't have a lot of elements.
Now, if I've broken this down correctly, you have:
20 "Class" objects, each with two ints (4 bytes apiece)
8*50 == 400 "Units" objects with four ints (4 bytes apiece)
25 "PlayerTroops" objects with four ints (4 bytes apiece)
That's (20 * 8) * (400 * 16) * (25 * 16) bytes, or 409,600,000 bytes of data you're storing in memory, whether all of them are filled or not with actual data.
Yes, I'd definitely go with the vector approach, and only allocate them as needed.
Shouldn't that be
(20 * 8) + (400 * 16) + (25 * 16) = 6960 bytes?
I don't think inheritance will work for me since I haven't fully repersented my variables in each struct. I've been going off memory to show how I'm using the data.
So in other words ClassDef has variables that UnitDef doesn't have and the Class Strength should also be a different number then the Units Strength.
I've been using ClassDef as an intro set of stats for my troops, and it also contains graphical X,Y cordance data for my sprite bitmaps that correspond to the correct Class(Job..Ex..Archer..Wizard)/Race
I do appreciate all of your guys help.
Note to bamccaig: Line 35
Yes I've used pointers before, but I think I'll stick to the Vecter approach that was given to me. Currently I only use pointers for char that I want used in another function without declaring a global char.
You'd still use a std::vector, but instead of storing objects in the std::vector by value, you'd store them by pointer. It makes certain operations much faster (though complicates matters slightly by forcing you to manage memory yourself).
$ g++ -c main.cpp $ g++ -o chrvct main.o $ ./chrvct { HP : 100, MP : 100, STR : 23 } { HP : 87, MP : 121, STR : 15 } { HP : 53, MP : 534, STR : 22 } { HP : 234, MP : 32, STR : 51 } $
The advantage to using pointers is that container operations won't cause copies of entire objects. Only their memory addresses need to be copied. Even better, if you don't mind installing Boost, would be using boost::shared_ptr<Character> (or if you've got a C++0x compatible compiler, std::shared_ptr<Character>) because it acts just like a pointer and is efficient like a pointer, but cleanup is automatic[1].
Goalie:
Explain that for me; I'm not used to c++0x.
Okay I will.. someone please bookmark/remind me to make a wiki if this ends up being referred to in other posts.
//use case: -(vec1 + vec2) //modifies and returns the unnamed vector //created from (vec1 + vec2) //requires c++0x Vec2D&& operator-( Vec2D&& vec ) { vec.x = -vec.x; vec.y = -vec.y; return std::move(vec); }
So, in C++ there are r-values and l-values. An r-value is a value without an explicit name.. these are temporary objects that can only be accessed in one way.
Vec2D a(1,2); Vec2D b(-1,2); Vec2D c = (a + b) - b;
In this example a,b,c are named variables. That means that any line of code in that scope can use the label (ie: name) to access that object.
(a+b) is a function of named variables a and b and returns a variable. What is this variable called? It is unnamed therefore nowhere else in the code can touch that result. This means that we can make an optimization here! Let us re-use the result from (a+b) by storing the result of (a+b)-b into the temporary created by (a+b).
Vec2D&& operator-(Vec2D&& ab, const Vec2D& b) { ab.x -= b.x; ab.y -= b.y; return std::move(ab); }
So && is the C++0x notation for r-value. Once we give an r-value a name it becomes an l-value. So ab is an l-value. But we want to return an r-value here so we use std::move which simply casts an l-value to an r-value. Notice how we re-use the temporary ab rather than making a new-copy!
Except why would that be any optimization here if there's nothing to be gained from moving?
With the following the version with rvalue references appears to be slower.
Except why would that be any optimization here if there's nothing to be gained from moving?
std::move does nothing but cast from Var& to Var&&. Where is the code that runs the actual test?
Say for example you had a string..
string&& operator+( string&& a, const string& b ) { //some magic } //write out other permutations of arguments... string& operator+( const string& a, const string& b) { //some different magic }
Then you would see a great performance increase from something like this
string c = a + b + "hello world " + d + e + f + g + "something else ";
In many programming languages they say avoid doing this because it constructs a new string for every addition and then throws it away. A lot of language tell you to use a.join etc. With r-values you can mimic that join behavior with a naive syntax.
String's a different thing indeed. But with something as simple as a Vec2D, everything goes on on the stack, and the compiler, I assume, can optimize away the temporaries via return value optimizations and inlining.
I have feeling there isn't much point to bother exploding the number of overloads you need for simple things like that.