Join 132,613 C++ Programmers for FREE! Get instant access to thousands of C++ experts, tutorials, code snippets, and more! There are 921 people online right now. Registration is fast and FREE... Join Now!
I have a linked list of objects (of multiple types), and I'd like to be able to perform a variety of actions depending upon what the object type is. It's a game I'm working on, and the different types of game "pieces" will follow a variety of rules depending upon the class type. I'll use chess as an example.
So I'll have a lot of different classes for each game piece type (king, queen, knight, pawn, etc.). Then I'll create a number of instances of each in order to fill the game board (black_knight_1, white_pawn_3, etc.). Now suppose the player chooses to move white_pawn_3. I would like to create some sort of conditional statement that checks the object type and handles the piece accordingly.
For instance (in pseudo-code):
if (white_pawn_3 is a king) then follow these rules... if (white_pawn_3 is a pawn) then follow these rules...
Seems simple enough, but I'm kind of new at this. Any help is appreciated.
Thanks.
This post has been edited by mjdamico: 10 Jul, 2008 - 10:14 AM
What i think you are talking about is checking if an object is of a certain class. If so, the easiest solution that I know of is to create bool values in each class (isKing, isQueen, etc.) and then in your constructor set the bool value to false of all the variables except for the piece (for instance, if it is a king, set isKing to true and isQueen to false). Then you would just check (if black_king_1.isKing, if black_king_1.isQueen, etc).
My only question, if you can detect which variable is used (for instance, you know they clicked on the black king), couldn't you have the user's input determine which if statement to use? If you have some more pseudocode about how the interface would work that would help. I'm just going after what i think you're getting at.
What i think you are talking about is checking if an object is of a certain class. If so, the easiest solution that I know of is to create bool values in each class (isKing, isQueen, etc.) and then in your constructor set the bool value to false of all the variables except for the piece (for instance, if it is a king, set isKing to true and isQueen to false). Then you would just check (if black_king_1.isKing, if black_king_1.isQueen, etc).
My only question, if you can detect which variable is used (for instance, you know they clicked on the black king), couldn't you have the user's input determine which if statement to use? If you have some more pseudocode about how the interface would work that would help. I'm just going after what i think you're getting at.
Thanks for the quick response. Your suggestion works. I tested it:
class pawn : public gamepiece { public: pawn():gamepiece() { isPawn = 1; isKnight = 0; isQueen = 0; } };
class knight : public gamepiece { public: knight():gamepiece() { isPawn = 0; isKnight = 1; isQueen = 0; } };
int main() { knight white_pawn_1; gamepiece* selected;
selected = &white_pawn_1;
if(selected->isPawn) cout << "That's a pawn."; if(selected->isKnight) cout << "That's a knight."; }
This will work, but it seems that things would get unwieldy if I wanted to add another class. Say I wanted to add a dragon piece. (Wouldn't chess be more exciting with dragons?) I'd have to go in and create a new bool value isDragon in the base class. Then I'd have to go into each derived class constructor and add the line isDragon = 0. If I ended up creating 50 different classes, I'd have a lot of mucking around. It would be a lot easier to be able to add one conditional statement to main. Something like
You could have a variable inside each class of type string, like this...
cpp
#include <iostream>
class gamepiece { public: string piecetype; };
class pawn : public gamepiece { public: pawn():gamepiece() { piecetype="Pawn"; } };
class knight : public gamepiece { public: knight():gamepiece() { piecetype="Knight"; } };
int main() { knight white_pawn_1; gamepiece* selected;
selected = &white_pawn_1;
if(selected->piecetype=="Pawn") cout << "That's a pawn."; if(selected->piecetype=="Knight") cout << "That's a knight."; }
That's a much better solution than the one i gave earlier.
Oh, and for your includes, if you are using a c++ library, drop the .h, since sometimes it can be a little ambiguous, especially with the string library (string is c++, string.h is c, cstring is also c).
1. Be sure to include the string library, <string>, for that. 2. Post the code in the snippets section once you're done (I'd love to see a chess snippet) 3. Shouldn't knight white_pawn_1 be pawn white_pawn_1?
This post has been edited by polymath: 10 Jul, 2008 - 01:55 PM
I wouldn't go crazy with a class for every conceivable thing. Your program may be easier to manage with just a Piece class and a Board class. Here's some code:
Now, where you may find a different class per piece is for things like legal moves. However, it's probably just as easy to make a legal moves list and stuff it in the game piece.
You can also do this using integers (which would be more efficient in time-critical portions of code). Here is an example (that does not require manual numbering):
cpp
#include <iostream>
class rtti_id_factory { public: typedef int id_type; static id_type get_id() { return cur_id_++; }
If a textual ID is desired as well as an integral one, that can be added to the preprocessor macros so that you can display the names when needed, but otherwise use simple integer comparisons when detecting object types.
Thanks for all of your tips. Unfortunately, it's been a week since I've had a chance to work on this code. I work full-time and go to grad school in the evening... seems I can only spare a couple hours a week to work on this game. Fortunately it's just a silly hobby. I don't expect it to show up on Xbox Live anytime soon.
Full disclosure: it's really a Roguelike RPG I'm trying to put together. I was just using the chess analogy as a bit of misdirection, being that it feels cliche for a beginning programmer to be making a Roguelike game.
I've got more design-related questions that I'll post in another thread...