check object type?

chess game example

Page 1 of 1

12 Replies - 11227 Views - Last Post: 17 July 2008 - 05:33 PM Rate Topic: -----

#1 mjdamico  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 9
  • Joined: 15-May 08

check object type?

Posted 10 July 2008 - 11:13 AM

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 July 2008 - 11:14 AM


Is This A Good Question/Topic? 0
  • +

Replies To: check object type?

#2 polymath  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 52
  • View blog
  • Posts: 670
  • Joined: 04-April 08

Re: check object type?

Posted 10 July 2008 - 11:21 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.
Was This Post Helpful? 0
  • +
  • -

#3 C++ Programmer  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 20
  • View blog
  • Posts: 548
  • Joined: 12-June 08

Re: check object type?

Posted 10 July 2008 - 11:24 AM

I'm kinda new to, but it sounds like a pretty fun game once finished
Was This Post Helpful? 0
  • +
  • -

#4 mjdamico  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 9
  • Joined: 15-May 08

Re: check object type?

Posted 10 July 2008 - 11:55 AM

View Postpolymath, on 10 Jul, 2008 - 11:21 AM, said:

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:

#include <iostream.h>

class gamepiece
	{
	public:
		bool isPawn;
		bool isKnight;
		bool isQueen;
		//etc...
	};
	
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
if( selected is a dragon) then 



Know what I mean? Any ideas?
Was This Post Helpful? 0
  • +
  • -

#5 polymath  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 52
  • View blog
  • Posts: 670
  • Joined: 04-April 08

Re: check object type?

Posted 10 July 2008 - 12:02 PM

You could have a variable inside each class of type string, like this...

#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).
Was This Post Helpful? 0
  • +
  • -

#6 mjdamico  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 9
  • Joined: 15-May 08

Re: check object type?

Posted 10 July 2008 - 12:41 PM

Yeah, now we're talking. That should work just fine. Thanks!
Was This Post Helpful? 0
  • +
  • -

#7 polymath  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 52
  • View blog
  • Posts: 670
  • Joined: 04-April 08

Re: check object type?

Posted 10 July 2008 - 02:54 PM

Three things:

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 July 2008 - 02:55 PM

Was This Post Helpful? 0
  • +
  • -

#8 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 5763
  • View blog
  • Posts: 12,580
  • Joined: 16-October 07

Re: check object type?

Posted 10 July 2008 - 03:26 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:

enum PieceType { PT_PAWN, PT_KNIGHT, PT_BISHOP };

class GamePiece  {
private:
	 PieceType type;
public:  
	 GamePiece(PieceType type) {
		  this->type = type;
	 }
	 PieceType getType() const { return this->type; }
	 string getName() const { 
		  switch (this->type) {
				case PT_PAWN: return "Pawn";
				case PT_KNIGHT: return "Knight";
				case PT_BISHOP: return "Bishop";
				default: return "Oops";
		  }
	 }
};



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.
Was This Post Helpful? 0
  • +
  • -

#9 Cerolobo  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 53
  • View blog
  • Posts: 450
  • Joined: 05-April 08

Re: check object type?

Posted 10 July 2008 - 04:28 PM

Actually, you might want to implement virtual functions. They make things like this a lot easier to work with.

#include <string>
#include <iostream>

class gamepiece
	{
	public:
		virtual std::string GetType(void) const{return "";}
	};

class pawn : public gamepiece
	{
	public:
		std::string GetType(void) const{return "Pawn";}
	};

class knight : public gamepiece
	{
	public:
		std::string GetType(void) const{return "Knight";}
	};

int main(void)
{
  pawn p;
  knight k;
  gamepiece *g;

  g = &k;
  std::cout << "Game piece is a " << g->GetType() << std::endl;

  g = &p;
  std::cout << "Game piece is a " << g->GetType() << std::endl;

  return 0;
}


This way, you can easily add new game piece types, without modifying the original gamepiece class.

Plus, since you wanted to preform some action based on the piece type, you could easily add addition virtual functions to actually do those checks.
Was This Post Helpful? 0
  • +
  • -

#10 perfectly.insane  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 70
  • View blog
  • Posts: 644
  • Joined: 22-March 08

Re: check object type?

Posted 10 July 2008 - 07:44 PM

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):

#include <iostream>

class rtti_id_factory
{
    public:
       typedef int id_type;
       static id_type get_id() 
       {
           return cur_id_++;
       }

    private:
       static id_type cur_id_;
};

rtti_id_factory::id_type rtti_id_factory::cur_id_ = 1000;

#define USE_RTTI()                                                         \
    public: virtual rtti_id_factory::id_type type() { return my_type_; }           \
            static rtti_id_factory::id_type type_id() { return my_type_; } \
    private: static rtti_id_factory::id_type my_type_; 

#define IMPLEMENT_RTTI(klass)                                              \
    rtti_id_factory::id_type klass::my_type_ = rtti_id_factory::get_id();

class my_class_1
{
    USE_RTTI();

    public:
        my_class_1() { }
        ~my_class_1() { }
};

IMPLEMENT_RTTI(my_class_1);

class my_class_2
{
    USE_RTTI();

    public:
        my_class_2() { }
        ~my_class_2() { }
};

IMPLEMENT_RTTI(my_class_2);

int main()
{
   my_class_1 mc1;
   my_class_2 mc2;
   if(mc1.type() == my_class_1::type_id()) {
       std::cout << "mc1: my_class_1" << std::endl;
   }
   if(mc1.type() == my_class_2::type_id()) {
       std::cout << "mc1: my_class_2" << std::endl;
   }

   return 0;
}




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.
Was This Post Helpful? 0
  • +
  • -

#11 mjdamico  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 9
  • Joined: 15-May 08

Re: check object type?

Posted 17 July 2008 - 07:03 AM

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...
Was This Post Helpful? 0
  • +
  • -

#12 polymath  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 52
  • View blog
  • Posts: 670
  • Joined: 04-April 08

Re: check object type?

Posted 17 July 2008 - 10:18 AM

I felt so smart until all the experts came in...
Was This Post Helpful? 0
  • +
  • -

#13 skaoth  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 91
  • View blog
  • Posts: 601
  • Joined: 07-November 07

Re: check object type?

Posted 17 July 2008 - 05:33 PM

One other option similar to that of virtual functions is to use the concept of an interface
An interface being simply a pure abstract class. Then derive each piece that you need from
this interface.

Here is an example
class IRule 
 {
 public:
	  virtual boolean CheckRule() = 0;
 };

class Piece1 : IRule
 {
 public:
	//
	// IRule interface implementation
	//
	 virtual boolean CheckRule() {
		// Your piece specific logic
		std::cout << "Piece1 checking its rules" << std::endl;
		return true;
	 }
 };

 class Piece2 : IRule
 {
 public:
	 //
	 // IRule interface implementation
	 //
	virtual boolean CheckRule()
	{
		// Your piece specific logic
		std::cout << "Piece2 checking its rules" << std::endl;
		return true;
	}
 };

void main(void)
{
	   vector<IRule*> rulesVector;
	rulesVector.push_back((IRule*)new Piece1());
	rulesVector.push_back((IRule*)new Piece2());

	for(std::vector<IRule*>::iterator itr = rulesVector.begin(); itr != rulesVector.end(); itr++)
	{
		IRule *p = (IRule*) *itr;
		p->CheckRule();
	}
}



In this sample I have 2 pieces that implement the interface IRule. This allow you to treat all the pieces uniformly. In affect what you are saying is that
for me to check the "rules" of any given piece you MUST implement this interface. At the same time this gives each piece the flexibility of defining their
own rules.

This post has been edited by skaoth: 17 July 2008 - 05:33 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1