Jump to content
  • Advertisement
Sign in to follow this  
Gary the Llama

What's the best way to connect my two classes?

This topic is 4834 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

Alright, I'm making a simple dice game. I have a Dice class and a Player class. The Dice class has 3 die members, for the 3 die that the player can roll and re-roll when it's their turn. I need to keep track of whose turn it is and what they've rolled, so how do I do this? Do I pass a pointer to an object of the player into my Dice::Roll function? What's the best way - or at least, a hint in the right direction? int Dice::Roll(Player* p, Die d); How is this normally handled in OOP?

Share this post


Link to post
Share on other sites
Advertisement
If you need to keep track of what each player rolls, maybe you could add a member to your player class that stores their current roll.

For the dice roll function, I'd just create a function that returns an integer value.


int Dice::Roll(void);



This isn't the only way to do it, and might not be the best way to handle it. I hope it helps you out though.

Share this post


Link to post
Share on other sites
"Dice::Roll(Player* p, Die d)" is kind of weird. Why is it in the Dice object? Why does the Dice object need to know anything about the Player object?

Depending on what Roll exactly does (which I'm not sure), what I would probably do is have a GameLogic object, and the GameLogic calls Dice.Roll and Player.whatever.

Or I could see it working where the Player object has game logic on it, and the Player object might use a Dice object (like if there was a CreateNewPlayer function on player, and it had to use dice to randomize stats)

But giving the Dice object responsiblitity over updating the Player is kind of backwards I think.

Share this post


Link to post
Share on other sites
You could discuss what is 'the right way' to do it until the cows come home so don't worry about that too much. I'd probably ensure that the Dice class simply has a function that, when called, will roll a random number and return it immediately. The Player class will keep a record of what they rolled previuosly and multiple rolls will simply be done by calling it multiple times (there's no need for the code to actually roll three seperate dice).

Anyway, like I say don't worry too much about the right way but that would make sense to me - the player takes care of remembering their previous rolls and the dice simply generates a random number on request.

Share this post


Link to post
Share on other sites
Quote:
Original post by ghosted
You could discuss what is 'the right way' to do it until the cows come home so don't worry about that too much. I'd probably ensure that the Dice class simply has a function that, when called, will roll a random number and return it immediately. The Player class will keep a record of what they rolled previuosly and multiple rolls will simply be done by calling it multiple times (there's no need for the code to actually roll three seperate dice).

Anyway, like I say don't worry too much about the right way but that would make sense to me - the player takes care of remembering their previous rolls and the dice simply generates a random number on request.


This makes perfect sense to me. And yeah, my Dice::Roll() call does just return a random number. I'll just have my Player class remember it. Thanks!

One more (related) question. Where does game logic go? Do I make a Rules class that checks for win victories? (That's what I've been thinking about.)

Share this post


Link to post
Share on other sites
Put game logic in a Game class. Generally your classes will either reflect entities (eg. dice, players), systems (game, graphics), or the interface (keyboard, network). This is just a vague categorisation though: object orientation is there to serve you, not the other way around. I tend to do whatever works first, and clean it up later. With experience, your first attempts will get more and more like your final attempts, but don't worry too much to begin with.

Share this post


Link to post
Share on other sites
Modelling the actual dice is probably a bad idea. Modelling the set of three individual Die-s as its own Dice object is especially unlikely to do anything useful for you. However, if you really wanted to do it that way (and it seems like a reasonable enough exercise for getting the hang of OO - although it's also important to practice "using the right tool for the job"), it might look something like:


class Die {
// all the necessary stuff here. I assume a Die "remembers" its last roll:
int currentValue;
public:
int roll(); // randomize and then return currentValue
int face(); // return currentValue;
}

class ThreeDice {
Die[3] dice;
public:
int roll(); // call roll() on each die, and then return sum of results
int face(); // call face() on each die, and return the sum of results
}

class Player {
ThreeDice mydice;
public:
// a bunch of other stuff
// When needed, call mydice.roll() or mydice.face()
// Now you can "remember" a previous die roll for later.
// Maybe it will be necessary for a player to have several sets!
}



Modelling things often is a matter of common sense and thinking about how it would work in the real world. When you play a tabletop RPG, you don't tell the dice who you are and then have them set your stats etc. - instead, you just roll the dice, observe the result, and do the rest yourself. Thus a Player parameter for a Dice function makes no sense. Similarly, a set of Dice always contains the same dice, so it doesn't need to be "told which to use".

In any event, "keeping track of whose turn it is" is best done externally, e.g. in the main game loop. You might have some Player* within main, and update it each time a player ends his turn, or something. One option is to have Player functions return a Player* (or Player&) representing who goes next. (If the current player's turn is not done, you would return the current player.) Of course, this all depends on the rest of your game logic, and requires some serious thought; solutions cannot be applied blindly.

Share this post


Link to post
Share on other sites
Heirarchies are a good way to organize stuff. The files on your computer are organized into folders for example. Do the files need to know what folder they are in? Not really. The folder needs to know what files are in it, so that when it is opened it can display them all.

I like to do the same with the various parts of my program. I try to make some classes (well actually I use structs, because I prefer default access being public) sort of standalone (or reuseable to use a buzzword). These parts are the foundation of my program. Then I have classes that depend on them. The foundation parts don't need to know about the higher levels. Dice don't need to know about Players.

Also not everything goes in a class. Some things should be global. Think of it this way: nothing is truely global because it is still part of something, your game for example. So to have a subpart of your game named Game makes no sense. A good guideline is that every program has roughly the same number of global variables. If a program is ten times bigger than another program and it has ten times as many globals then you have made a very big mistake and don't know what I mean about using globals. Just because something is not global doesn't mean that it should be in a class either. Namespaces are great, I use them extensively. They are also more STL and hmmm... been a while what is the word? Start up initialization friendly.

So, in your case I would just make a function along these lines:
int RollThreeDice();

"Do I make a Rules class that checks for win victories?"
Not if you know your win conditions at compile time, which you almost certainly do. Chances are a player can only win at certain parts of the game, such as after a player takes an action. That's when you call something like:
CheckForVictory(current_player);
Or if there are different ways to win during different phases of the game that is when you pull out the:
VictoryConditions::CheckConditionOne();

Every feature of your language is a useful tool. Every language feature and design philosophy appealed to someone at some time. Figure out why and how you can use it to apply your tools better.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!