How can i use getters and setters with math?

Pages: 1234
Big hint: "preserve its invariants now", "keep preserving them in the face of future changes", "robust versioning", "the first stage of debugging – localization" etc. are not just meaningless verbiage.

Trust me, I understand. My point is that one should ask whether these things apply to one's specific problem. I've seem too many cases where a simple, one-off program has a class with all data members private and get/set members for each one of them. For cases like that, the getters & setters add a certain complication now for an uncertain benefit in future.

My point is just that they should not be used blindly in all cases.
Ok so there have been a lot of posts since my last post, and i read through them all, but like i said before it's hard for me to pay attention, also I have some family crisis stuff going on at the moment, but I still want to get this issue solved, So lets go step by step, what is my first step?

Here is my current class, I removed all te getters and setters:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Player
{
    public:
        Player(unsigned int PLAYERHEALTH, unsigned int PISTOLAMMO,
               unsigned int SHOTGUNAMMO, unsigned int RIFLEAMMO,
               unsigned int SCORE, unsigned int MONEY,
               unsigned int HEALTHPACKS, int TURNS, std::vector<int> ITEMS);

        unsigned int playerHealth;
        unsigned int pistolAmmo;
        unsigned int shotgunAmmo;
        unsigned int rifleAmmo;
        unsigned int score;
        unsigned int money;
        unsigned int healthPacks;
        unsigned int turns;
        std::vector<int> items;
};
My point is just that they should not be used blindly in all cases.
It should be used by default. Only if there is any compelling reason to not do so, you might make your clase a behaviorless aggregate.

what is my first step?

Step 1. Make anything what is not a function private.
Step 2. Think about behavior of class Player. What can be done to it. What its interface is.

Only you might know how this class will be used and what will be needed.
Example functions:
unsigned .health() returns current player health
.damage(unsigned int) Decreases player health. Calls proper handlers if hals <= 0 as rerults (handles death — preserves class invariants)
.useHealthPack(unsigned int n = 1) Uses Health Pack held by player. Will not increase health more than maximum health — preserves invariants.
unsigned .getHealthPack(unsigned) — Increases amount of health pack on player but no more than maximum. returns actual amount received.
unsigned .healthPacks() returns current amount of health packs.
bool .shoot(player&) — shoots another player with currently equipped weapon. Returns false if command is impossible to execute (no weapon, no ammo, target is far away, target is not visible, etc), true otherwise.
Avilius wrote:
Huh? All programs do is manipulate data. That's their job.


And the next sentence was ..

TheIdeasMan wrote:
For example CurrentWeapon->Reload rather than getting / setting Ammo Levels with functions.


I meant manipulating data with get / set functions as opposed to some Action type function CurrentWeapon->Reload which manipulates that member data.
Lol, and I look like an idiot like always for thinking about stuff too much...

Sorry about that I guess.

Ch1156 wrote:
but like i said before it's hard for me to pay attention
I don't see how conflicting answers are actually a bad thing...

If anything, they're a good thing. If you take each of them into consideration, then you can combine and modify the solutions to solve your problem in the best way.

Conflicting answers also help the people who are trying to help you. By reading others' reasons for picking the solution that they've chosen then it can only make you a better programmer.

Try not to follow people's advice too strictly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Player
{
    public:
        Player(unsigned int PLAYERHEALTH, unsigned int PISTOLAMMO,
               unsigned int SHOTGUNAMMO, unsigned int RIFLEAMMO,
               unsigned int SCORE, unsigned int MONEY,
               unsigned int HEALTHPACKS, int TURNS, std::vector<int> ITEMS);

        unsigned int playerHealth;
        unsigned int pistolAmmo;
        unsigned int shotgunAmmo;
        unsigned int rifleAmmo;
        unsigned int score;
        unsigned int money;
        unsigned int healthPacks;
        unsigned int turns;
        std::vector<int> items;
};


First off... if you're going to make everything in a class public, then it shouldn't be a class at all, but just a struct.

A lot of the information stored in this class seems fairly redundant... I can probably give better advice if I know what type of game you're making. Will there be other entities other than the player?
Last edited on
If anything, they're a good thing. If you take each of them into consideration, then you can combine and modify the solutions to solve your problem in the best way.

Conflicting answers also help the people who are trying to help you. By reading others' reasons for picking the solution that they've chosen then it can only make you a better programmer.


Hmm, I guess I never really thought of that before, i'll try to do that from now on.

First off... if you're going to make everything in a class public, then it shouldn't be a class at all, but just a struct.

A lot of the information stored in this class seems fairly redundant... I can probably give better advice if I know what type of game you're making. Will there be other entities other than the player?


I forgot to make the member variables private.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Player
{
    public:
        Player(unsigned int PLAYERHEALTH, unsigned int PISTOLAMMO,
               unsigned int SHOTGUNAMMO, unsigned int RIFLEAMMO,
               unsigned int SCORE, unsigned int MONEY,
               unsigned int HEALTHPACKS, int TURNS, std::vector<int> ITEMS);

    private:
        unsigned int playerHealth;
        unsigned int pistolAmmo;
        unsigned int shotgunAmmo;
        unsigned int rifleAmmo;
        unsigned int score;
        unsigned int money;
        unsigned int healthPacks;
        unsigned int turns;
        std::vector<int> items;
};


As for the type of game, it's called dinosaur arena, it's a turn based game, you play as a human against dinosaur opponents. I haven't implemented other dinosaurs yet, just a T-Rex.

If you would like to view all the source code, I put it on pastebin here: http://pastebin.com/6KqU0akU

There are three files in that one page, main.cpp, Player.h and Prototypes.h
Hi,

@Avilius

No worries. I am sure you are not the only one which that has happened to - I am in that list too .... :+)

I had a bit of a Plan in mind for Chay(The OP), showing a way to create classes with private member variables, and not needing getters / setters.

Starting out simple, then adding in extra stuff as we go along. A Player with a std::vector of resources. A Resources Base class, and some derived classes. Add a Resources into the Player's vector. Then some kind of Shop class, with transfer of objects from that to the player. The possibility of a Transaction class. Then perhaps a component model framework.

@Ch1156

So the thinking behind this so far, is we have a player and some resources, which the Player can just grab, without any cost or anything. Think of Tomb Raider, where Lara can arrive at a location and pick up whatever object is there.

I don't have a compiler at the moment, so this is just typed in - hopefully not any errors.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//CPlayer.hpp
class CPlayer
{
private:

    std::string m_Name; 

    std::vector<CResource *> pGear ; // Possessions, Equipment, stuff whatever
                                                    // Uses a smart pointer

public:

    CPlayer(std::string Name); // put the definition of this into a .cpp file using an initialiser list

    AcquireResource(CResource *pTheResource); // in the definition push_back the resource into the vector


};


Now the Resources Base class:

1
2
3
4
5
6
7
8
9
// CResource.hpp
class CResource
{

public:
     virtual void PrintDetails() = 0; // pure virtual function must be defined in derived classes


};


A derived Resource class:

1
2
3
4
5
6
7
8
9
10
11
12
// CBag.hpp
class CBag : public CResource // aka Rucksack, Back Pack etc
{
private:
    unsigned short      m_Capacity; // Volume in litres
    std::string            m_Material; // PVC, Canvas etc could use an enum 

public:
    CBag (unsigned short Capacity, std::string Material); // put defintion in cpp file with initialiser list
    void PrintDetails(); // std::cout each member variable

};



Now create another derived resource class that has some attributes to print out, don't for get to define a PrintDetails function which will do that.

Create a cpp file with main() in it. Create a Player Object (as unique smart pointer), and some instances of your derived Resource classes. Use the Player->AddResource function to add these resources into the player. The argument for this will be a smart pointer to the particular resource.

Next you can use the PrintDetails function to show information. Ideally this would be done from a new function in CPlayer that would use a range based for loop to iterate through the Gear vector, calling the PrintDetails function for each object in the vector.

I hope this enough to get you started, and we all look forward to seeing your code.
what is my first step?

Think about a player. What can a player do? Turn those things into methods.

Think about the data that a player has. What are the invariants? Make data private and methods public to enforce the invariants.

Sketch out the rest of the game. As you do this, you'll probably discover other data and methods that you want for the player class. From a practical standpoint, this really means developing the header files for the game.

Once you can't make more progress on the header files, start writing the code. As you go, you may find additional things that must be added to the interface. That's no big deal, as long as you don't find that you've really botched something up and need to make major changes.

What is vector<int> items? It seems to me that each item that the player carries will have many properties of its own.
Hi Chay,

Just wanted to explain a bit more about the code in my last post.

So we have generalised the Player's possessions by having a vector of resources. We have now generalised the PrintDetails function, in that the name is the same in all the resource derived classes. Essentially, from an OOP perspective there is one of them, just that they are specialised behind the scenes so to speak. EDIT: This is called abstraction. So that means that no matter how many resources, or what type they are - we can print out their details. So this is better than having a myriad of functions like PrintAssaultRifleDetails, PrintShotGunDetails, PrintPistolDetails, PrintAssaultAmmoDetails, etc, etc ........ As well as that, we can have a bunch of loosely related things in one container.

This means that the code is much easier to maintain. To add a new resource, just make a new derived resource class, with the appropriate functions. The other way means that you have to change code everywhere and add new functions with different names to make sure that everything works. If there are lots of different types of things, this soon gets out of control.

Now it is true that the PrintDetails function probably isn't a great deal of actual use, but it is a good and simple demonstration of how to think in a OOP way. The key to it, is that a function can declared to take an argument which is a pointer or reference to a base class, but when the function is called, one sends a pointer to a derived class. The compiler uses the derived class pointer, to call the derived class function. This is a very powerful thing, and saves writing lots of functions.

I haven't even looked at your existing code, I thought it better to explain what was good about my ideas instead, rather than criticise your code. Although, I noticed from the file names, that you have just one class in your existing code. Hopefully we can show how to easily use multiple classes in your application.

Hope all this helps :+)
Last edited on
Hello again,

At risk of overloading you with too much information, here is a really easy to read book about game patterns:

http://gameprogrammingpatterns.com/introduction.html


I really do hope that you are able to get the code I gave in my previous post working.
Ok so I made some classes, they are a little different from what you had but they are basically the same. here they are. Each class is in it's own .h file in my program:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class Player
{
    public:

    private:
        string playerName;
        int playerHealth;
        const int maxHealth;
        int playerMoney;
        const int maxMoney;
};


class Shop
{
    public:

    private:

};


class Backpack
{
    public:

    private:
        int currentItemAmount;
        const int itemLimit;

};


class Game
{
    public:


    private:

};


I made a new program so i could focus on this issue before moving on to working with a larger code base. Does everything look good so far?

I havent yet looked at the article, i will read it here in a bit, i havent had time lately.

"Think about a player. What can a player do? Turn those things into methods."

Ah I see, so I could add an attack method, a reload weapon method, a open backpack method etc correct?
Last edited on
Ah I see, so I could add an attack method, a reload weapon method, a open backpack method etc correct?

Yes, exactly! But think carefully about which class has the method. For example, "open backpack" would probably be an "open" method of the "backpack" class, rather than Player::openBackback(). Reload() might be a method of the weapon, or a method of the player, it depends on what it actually needs to do, but it probably involves both. In other words, it might be Weapon::reload(Player &p) or Player::reload(Weapon &w).
Hi chay

So some things to add to your code as per my previous post. you need a Resource base class and Backpack needs to derive from it. The Player class needs a std::vector of pointers to the Resource base class.

I wouldn't worry about the others classes yet, I was hoping to achieve the idea of a Player that can own things then add more things later. So add some more resources, and add the cpp code for each, as I described earlier. Don't forget the PrintDetails functions.

Cheers
Hi again,

I may have unintentionally complicated things by having a backpack as a resource, because really it should have a vector of resources of things inside the backpack.

I was just intending to have a list of simple things with attributes that a player owns, so that we could print a list of them all.

With the Weapons and other stuff, just be aware that we will run into using design patterns fairly soon. If you read the book whose link I posted earlier, you will see that patterns are going to be essential throughout the code for a game. Things like Player Health will become a class of their own, and there will be patterns to look after weapons etc.

Hope all is well :+)
Just another quick one:

I use a naming convention which is purely a personal preference thing.

I start class names with a C, member variables with a m_ , and pointers with a p .

Hope this helps
Hi, sorry for such a late response, had someone in the hospital for the past few weeks and they died a few days ago, been busy with that but should be free to work on this now.
Sorry for your loss. :(
Me too :+(
Thank you both :). I'll look over my code tomorrow and get back to you.
Hey sorry for the late response, I cant find my code, I think I deleted it, so i'll just start from scratch again. So from looking back, I need a player class, a backpack class, weapon class and a shop class correct?

EDIT: Nevermind I found it, it was in my videos folder for some reason. So this is my code so far:

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

#include "Resource_Class.h"
#include "BackpackClass.h"
#include "GameClass.h"
#include "PlayerClass.h"
#include "Prototypes.h"
#include "ShopClass.h"

using namespace std;

int main()
{

    return 0;
}



Resource_Class.h

1
2
3
4
5
6
7
8
9
10
11
#ifndef RESOURCE_CLASS_H_INCLUDED
#define RESOURCE_CLASS_H_INCLUDED

class Resource
{
    public:

    private:
};

#endif // RESOURCE_CLASS_H_INCLUDED 



BackpackClass.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef BACKPACKCLASS_H_INCLUDED
#define BACKPACKCLASS_H_INCLUDED

#include "Resource_Class.h"

class Backpack : public Resource
{
    public:
        Backpack(int CURRENTITEMAMOUNT, const int ITEMLIMIT);

    private:
        int currentItemAmount;
        const int itemLimit;
};

#endif // BACKPACKCLASS_H_INCLUDED 



BackpackConstructor.cpp

1
2
3
4
5
6
7
#include "BackpackClass.h"

Backpack::Backpack(int CURRENTITEMAMOUNT, const int ITEMLIMIT): currentItemAmount(0),
                                                                itemLimit(10)
{

}



GameClass.h

1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef GAMECLASS_H_INCLUDED
#define GAMECLASS_H_INCLUDED

class Game
{
    public:


    private:

};

#endif // GAMECLASS_H_INCLUDED 


PlayerClass.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef PLAYERCLASS_H_INCLUDED
#define PLAYERCLASS_H_INCLUDED

#include <vector>

class Player
{
    public:

    private:
        std::string playerName;
        int playerHealth;
        const int maxHealth;
        int playerMoney;
        const int maxMoney;
        std::vector<Resource *> p_Gear;
};

#endif // PLAYERCLASS_H_INCLUDED 



ShopClass.h

1
2
3
4
5
6
7
8
9
10
11
12
#ifndef SHOPCLASS_H_INCLUDED
#define SHOPCLASS_H_INCLUDED

class Shop
{
    public:

    private:

};

#endif // SHOPCLASS_H_INCLUDED 
Last edited on
Pages: 1234