Sign in to follow this  

Leveraging OOP

This topic is 4401 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Given the following classes and inheritance that is in place, how can I assign the appropriate icons to each KIND of Robot (as you can see I am doing with the MasterRobot) without having to duplicate the same code in the constructor for each class?
public class Object
{
	public Image icon;
}

public class Robot : Object
{
	public string owner;
	public bool is_enemy;
}

public class MasterRobot : Robot
{
	public MasterRobot()
	{
		if(!is_enemy)
		{
			icon = Image.FromFile("images\\mr_friendly.bmp");
		}
		else
		{
			icon = Image.FromFile("images\\mr_enemy.bmp");
		}
	}
}

public class Medic : Robot
{
}

public class Engineer : Robot
{
}

public class Destroyer : Robot
{
}

public class Wall : Object
{
}

Share this post


Link to post
Share on other sites
I suggest that you create a base class constructor that receives the 'enemy' and 'friend' filenames, and pass them to this constructor from the constructor of the derived classes.

Share this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
I suggest that you create a base class constructor that receives the 'enemy' and 'friend' filenames, and pass them to this constructor from the constructor of the derived classes.


Can you give me a source code example? I don't quite see how this helps.

Share this post


Link to post
Share on other sites
You will need to write at least two things: the names of the files and a short command to explain what to do with them. You will not be able to make things any shorter. My suggestion is to use:



class BaseClass {

protected BaseClass( string friend, string enemy ) {

if( friendly ) { /* load friend */ }
else { /* load enemy */ }
}

public BaseClass( ) : this( "BaseFriend.tga", "BaseEnemy.jpg" ) {

}
}

class Derived : public BaseClass {

public Derived( ) : base( "DerivedFriend.tiff", "DerivedEnemy.gif" ) {

}
}






This reduces the amount of additional characters to be typed to :base(,) for each derived class.

Share this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
You will need to write at least two things: the names of the files and a short command to explain what to do with them. You will not be able to make things any shorter. My suggestion is to use:

*** Source Snippet Removed ***

This reduces the amount of additional characters to be typed to :base(,) for each derived class.





So like this?


public class Object
{
public Image icon;
}

public class Robot : Object
{
public string owner;
public bool is_enemy;
public Robot()
{

}

protected Robot(string friendly_image, string enemy_image)
{
if(!is_enemy)
{
icon = Image.FromFile(friendly_image);
}
else
{
icon = Image.FromFile(enemy_image);
}
}

}

public class MasterRobot : Robot
{
public MasterRobot( ) : base( "images\\mr_friendly.bmp", "images\\mr_enemy.bmp" )
{
}
}

public class Medic : Robot
{
public Medic( ) : base( "images\\med_friendly.bmp", "images\\med_enemy.bmp" )
{
}
}

public class Engineer : Robot
{
public Engineer( ) : base( "images\\eng_friendly.bmp", "images\\eng_enemy.bmp" )
{
}
}

public class Destroyer : Robot
{
public Destroyer( ) : base( "images\\dest_friendly.bmp", "images\\dest_enemy.bmp" )
{
}
}

public class Wall : Object
{
public Wall()
{
icon = Image.FromFile("images\\wall.bmp");
}
}


Share this post


Link to post
Share on other sites

class Robot:public Object {
*insert base robot code here*
public:
Rect rect;
};

class ImageView: public View {
Image image;
Object& object;
public:
ImageView(std::string filename, Object& object_):image(filename), object(object_) {}

void render(Surface& screen) {
screen.draw(image, object.rect);
}
};

...

Robot* robots = {new MasterRobot(), new Medic()};
ImageView robot_views = {ImageView("master_robot.png"), ImageView("medic.png")};

Share this post


Link to post
Share on other sites
bytecoder: the OP wants to specify the graphics per-class, not per-instance. (and is using C#, not C++)

Share this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
bytecoder: the OP wants to specify the graphics per-class, not per-instance. (and is using C#, not C++)


Correct on both counts. I think I have my answer now....I tested and it seems to be working just fine.


I had another question:



//Instead of doing this:

public class Destroyer : Robot
{
public Destroyer( ) : base( "images\\dest_friendly.bmp", "images\\dest_enemy.bmp" )
{
}
}


//Can I somehow do THIS:


public class Destroyer : Robot
{
public Destroyer( ) : base( iType.DestroyerFriendly, iType.DestroyerEnemy)
{
}
}


iType.DestroyerFriendly = "images\\dest_friendly.bmp"
iType.DestroyerEnemy = "images\\dest_enemy.bmp"






What is a nice way to do this...make things a little cleaner?

Share this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
bytecoder: the OP wants to specify the graphics per-class, not per-instance. (and is using C#, not C++)

That's what mine does (it's actually even more flexible). Look into Model-View-Controllers.

Share this post


Link to post
Share on other sites
OP: yes, you can, and it's even quite recommended. You could also use a static hashtable member of Robot to store the strings (indexed by derived class type) and query that table upon creation of a Robot.

bytecoder: in that case I'm afraid I didn't understand your code. Would the following code work as is? And if yes, please explain how the constructor for Medic( ) becomes aware of the name of the file from which to load the graphic.



Robot medic = new Medic( );

assert( medic.icon == Image.FromFile( "medic.png" ) );




Share this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
OP: yes, you can, and it's even quite recommended. You could also use a static hashtable member of Robot to store the strings (indexed by derived class type) and query that table upon creation of a Robot.

bytecoder: in that case I'm afraid I didn't understand your code. Would the following code work as is? And if yes, please explain how the constructor for Medic( ) becomes aware of the name of the file from which to load the graphic.

*** Source Snippet Removed ***

No, it wouldn't. The Robot class (the model) has absolutely no knowledge of anything other than abstract robot tasks. The ImageView class is what does the rendering based on 1) the robot's position and 2) the image you gave it. To get input from the user or ai, you would have a RobotController class that controls the robot. If you did for some reason want to create more work for yourself, you could create specific RobotXViews that sets the image in the constructor, but my way is shorter and more flexible.

Share this post


Link to post
Share on other sites
The topic of this thread is on ways to bind a resource (eg. a pair of filenames) to a class in a concise way, based on an existing code framework. Your proposed solution:


  1. Does not bind a resource to a class in any way. You first asserted that I was wrong and that your code did perform this per-class binding. Then, you contradicted that initial statement and said that per-class binding would require the creation of an additional class for each class for which you want to perform the binding — which falls short of the request for a concise solution, as per the original post.

  2. Does not use the existing code framework provided in the original post, and instead proposes a heavy reworking. Your code is also written in another language which the original poster might not understand, and which does not compile (check the number of required arguments for the ImageView constructor). It uses a basic design that is different from that of the original post: Model-View-Controller, a design with which I happen to be familiar, having used it often in the past.


As a consequence, it seems clear enough to me that your proposal is not an acceptable answer to the question and problem described in the original post of this thread. Your implying that I do not know enough to judge your post — directing me to look up the Model-View-Controller pattern — is something I would consider downright insulting if not for the irony of your contradictions in your third post.

Your initial post does offer some good insight by giving an example of Model-View-Controller, which I agree is a very good thing to use. However, you never stated that your purpose of showcasing an alternative design, which was quite different from the meaning of answering the original question that the format of your post (a blob of code with no accompannying explanations) implied. Moreover, you insisted that your post did answer the original question of the thread, which it does not as you seemed to agree later on. Why not simply begin your post with "This does not answer your question, but a better design would be: ...", maybe followed by a short argumentation of why that design is better.

You don't appear to have read the original question (or deliberately chose to ignore it), you do not answer the original question, and instead make an unsupported, unexplained post that, after thorough reading, seems to scornfully throw away the entire work of the original poster and unilaterally replace it with a half-described and crippled design that has no logical relationship whatsoever to the question, but which you appear to put forward as if it was the best thing that happened to man since the AZERTY keyboard; only to follow up by implying that I am a know-nothing idiot who does not see in which way your post helps solving a problem that it (fact) does not solve.
Your participation is not an answer to the problem, only a suggestion for a better design that is completely orthogonal to the problem, so accept that it is only that, and nothing more.

EDIT: one final remark about your allusive statement in your last post.

Quote:
If you did for some reason want to create more work for yourself, you could create specific RobotXViews that sets the image in the constructor, but my way is shorter and more flexible.


There are two errors in the above comment.


  1. Consider the following line of code:
    int main( ) { return 0; }

    Neither this line nor your proposal are acceptable solutions to the problem. My proposal is shorter. Therefore, I suggest we do not create too much work for ourselves, so we keep my solution and throw yours away.

    Before saying that your solution is shorter, you should begin by providing an actual solution.

  2. The you could create specific RobotXViews that set the image in the constructor part of your answer has the quite ironic property of being, word for word, what the original poster wants to know how to do. Is this what you call a solution? Commenting on the general design of the code, giving a design of your own that you insist on being superior without supporting your claims, while leaving the original question unanswered?


Great, cool, you won. Your method is the best, shortest, most easily maintained and most easy to write. Here's your medal. Now, stop interfering with the actual answering of the question.

Share this post


Link to post
Share on other sites
Quote:

# Does not bind a resource to a class in any way. You first asserted that I was wrong and that your code did perform this per-class binding. Then, you contradicted that initial statement and said that per-class binding would require the creation of an additional class for each class for which you want to perform the binding — which falls short of the request for a concise solution, as per the original post.

Per-class binding can easily be done informally using per-instance binding. By creating a separate class you get strict class binding, but you also get more work and less flexibility.

Quote:

Does not use the existing code framework provided in the original post, and instead proposes a heavy reworking.

I didn't force him to use it. I merely presented the method that I would use. If it doesn't fit in with his overall design, he's free to chose a different method.

Quote:

Your code is also written in another language which the original poster might not understand, and which does not compile (check the number of required arguments for the ImageView constructor).

Didn't notice that he wasn't using C++; guess I filtered out the 'public' keywords before the classes. In any event, the code I posted was more of a demonstration than anything. It didn't have to be production quality to get the point across.

Quote:

As a consequence, it seems clear enough to me that your proposal is not an acceptable answer to the question and problem described in the original post of this thread.

That's something only the OP needs to decide. Arguing about what is "acceptable" and what isn't doesn't seem very productive, in my opinion.

Quote:

Your implying that I do not know enough to judge your post — directing me to look up the Model-View-Controller pattern — is something I would consider downright insulting if not for the irony of your contradictions in your third post.

Your direct attack on the "acceptableness" of my post is something I would consider downright insulting, if not for the irony that your post is completely unrelated to the (already solved) question at hand.

Quote:

Great, cool, you won. Your method is the best, shortest, most easily maintained and most easy to write. Here's your medal. Now, stop interfering with the actual answering of the question.

I fail to see how my solution to the problem, even if it might not be completely appropriate for the OP's situation, interferes any more than your post. If you feel that my post was completely off topic and wouldn't help the OP at all, then rate me down; that is, after all, what the rating system is for. Otherwise, I recommend you leave it to the OP to decide what is appropriate and what is not.

Share this post


Link to post
Share on other sites

This topic is 4401 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this