• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

[Question] c++ classes question

180
Posts
12
Years
  • Age 36
  • Seen Aug 12, 2023
I asked a question regarding tips on a pokemon engine about a year ago, and I've taken a pretty long vacation from learning c++ programming. I've since reread the topic and can now understand every suggestion given to me, but... Since I'm just getting back into it, and consider myself a n00b programmer, I was hoping you guys could help me clear up a few concepts. I've barely started coding, rather just practicing each object oriented method I can think of that will go into the application before I actually start the programming for the real thing.

1. Is there a way where one class can just read another class's object without invoking the outside class's constructor?

Here's some of the code so far to show what I've done.

Spoiler:

I'm pretty sure there's some ugliness in that code, but yeah.

2. I remember a while ago that someone said making a subclass for each pokemon is not a great idea. So instead, each pokemon will be an instance of the pokemon class (and makes more sense now that I think about it). The pokemon class constructor will initialize the base stats and name of the pokemon. ( Pokemon Bulbasaur("Bulbasaur", 45, 49, 49, 45, 65, 65) ). Is this the correct way of going about it?
 

th3shark

Develops in AS3/C++
79
Posts
10
Years
Semi-experienced C++ coder here! Nice to see another person up to the task of creating a battle engine from scratch.

1. Is there a way where one class can just read another class's object without invoking the outside class's constructor?

Not quite sure what you're asking here. Do you want code in the constructor to be skipped when the object is created? A constructor has to be called for a class instance to be created. I guess you can have two different constructors with different code in each.

2. I remember a while ago that someone said making a subclass for each pokemon is not a great idea. So instead, each pokemon will be an instance of the pokemon class (and makes more sense now that I think about it). The pokemon class constructor will initialize the base stats and name of the pokemon. ( Pokemon Bulbasaur("Bulbasaur", 45, 49, 49, 45, 65, 65) ). Is this the correct way of going about it?

No. A pokemon is much more than just its name and base stats. Here's data I have stored which is constant for a species of pokemon (written in AS3, but same concept):
Spoiler:
You are not going to want to initialize all that in the pokemon's constructor. If you don't want each pokemon to be a separate class, then each pokemon should be a separate file with data on it that is parsed during the game.

And some advantages of each pokemon being a separate class:
  • No need to write a file parser, and no need to have separate files for each pokemon.
  • You can take advantage of constants and enumerations when using classes.
  • Classes can have functions that can be overridden. For example, I found it easier to represent how a pokemon evolves with a function instead of a variable.

Classes may not be the most conventional way to handle pokemon, but that's how I do it, and it has caused me no problems so far. Feel free to ask me any questions!
 

zingzags

PokemonGDX creator
536
Posts
15
Years
You are able to pass through an object in c++. For example the same way you would use a regular variable, but what do you mean was the object already pre-made (with the constructors being used, or not). There is something called method/function overloading, which lets you create the same method/function/constructor with the same name, but different parameters.
 
180
Posts
12
Years
  • Age 36
  • Seen Aug 12, 2023
Thanks for the replies, guys. Well, like I said before my code that I posted in the spoiler is just practice stuff.

Zingzags: I didn't know you could overload a class' constructor.

th3shark: I know that Pokemon have a LOT more data members than just name and base stats. This is what I can think of off the time of my head.

Name
Nickname
Level
Base Stats: HP / Attack / Defense / Speed / Special Attack / Special Defense
Calculated Stats: Current HP / Max HP / Attack / Defense / Speed / Special Attack / Special Defense
Nature
EVs and IVs
Abilities
Item slot
Attack List
Status inflictions: 1st being the main ones.. poison, paralysis, freeze, burn, sleep... confusion also, but since confusion can coincide with other inflictions I feel it should have its own dedicated member (right word?)
Sprite pointer, but I'm not doing graphics so I don't plan on including that.
Pokedex entry: Species, number (national), height, weight, and description.

My battle class will be the one to keep track of everything in a battle (well duh). It's gonna have its own members for pokemon stats that will be modified based on whatever stat modifying moves there are. I'm thinking the flow for it will be...

Create battle object
Copy pokemon objects into battle class from player, and NPC (or player 2...) party slots into battle pokemon party vector.
Send pokemon in first party slot of players out to battle, check abilities
Wait for move
Check move priority first, if same priority, pokemon with higher speed goes first
Do battle move stuff... (attack, or set weather condition if Pokemon changes weather, or if player switches out pokemon, move chosen pokemon to first party slot)
Check held item ability
If Pokemon's HP <= 0, it has fainted. If HP is below 0, set HP to 0.
Wait for player to choose another Pokemon to send out, once pokemon is chosen, move chosen to first party slot.

...Something like that. I'm gonna need to research a lot more on move priorities, abilities and secondary effects (such as absorb and the likes), but I think I pretty much got the gist of it.
 

th3shark

Develops in AS3/C++
79
Posts
10
Years
Yes, but keep in mind some of these members (such as name, base stats) are unique to a specific pokemon species.

Also, level and calculated stats are not stored. These are calculated from exp, base stats, EVs, IVs, nature, etc.

Sprite pointer, but I'm not doing graphics so I don't plan on including that.
You probably should lol

Your plan for the battle flow looks fine to me. Good luck!
 
180
Posts
12
Years
  • Age 36
  • Seen Aug 12, 2023
Yes, but keep in mind some of these members (such as name, base stats) are unique to a specific pokemon species.

Also, level and calculated stats are not stored. These are calculated from exp, base stats, EVs, IVs, nature, etc.

Well, since my program will just be mainly a battle engine, I don't know if I'll even include methods for leveling. I figure I'll just let the user choose a Pokemon, and choose its level, nickname, and EVs. From there, the class will choose IVs at random, and calculate the final stats. Why can't I store calculated stats within the class object and have a method to change them later?

You probably should lol

Honestly this battle engine wll sort of be my own final project for basic c++ programming. If I'm successful in it, and it all works out.. then I'll move to GUI programming, and programming stuff like graphics and sound (with SDL). If it all works out, I could release it to the public, make it open sourced, and people could modify it for graphics on their own. I do plan on making my battle engine somewhat modular, easily readable, and well documented in any case.

Your plan for the battle flow looks fine to me. Good luck!

Cool, thanks!

Edit: BTW, I know almost nothing when it comes to programming for graphics. I've taken a look at it before, (mainly Direct3D) and quite frankly, it's a little intimidating to me, lol.
 
Last edited:

th3shark

Develops in AS3/C++
79
Posts
10
Years
Why can't I store calculated stats within the class object and have a method to change them later?
You can, but it would be a lot easier to have one getter function calculate stats from EVs etc. than to change the the calculated stats every time a variable changes.

this battle engine wll sort of be my own final project for basic c++ programming
Out of curiosity, are you learning C++ on your own or taking a class?

BTW, I know almost nothing when it comes to programming for graphics. I've taken a look at it before, (mainly Direct3D) and quite frankly, it's a little intimidating to me, lol.
I've used SFML with C++ for 2d games before. It's a relatively simple library to use. I'd recommend trying it out if you haven't started learning something else already.
 
180
Posts
12
Years
  • Age 36
  • Seen Aug 12, 2023
You can, but it would be a lot easier to have one getter function calculate stats from EVs etc. than to change the the calculated stats every time a variable changes.

That's what I was trying to say :P. A getter function being called based on a condition of some sort: if (level up = true) { CalculateStats(); }<-- something along those lines

Out of curiosity, are you learning C++ on your own or taking a class?

Self-taught.

I've used SFML with C++ for 2d games before. It's a relatively simple library to use. I'd recommend trying it out if you haven't started learning something else already.

I'll be sure to check it out, thanks.
 

Maruno

Lead Dev of Pokémon Essentials
5,285
Posts
16
Years
That's what I was trying to say :P. A getter function being called based on a condition of some sort: if (level up = true) { CalculateStats(); }<-- something along those lines
That's sort of how Essentials works. The stats are stored as separate variables, and upon changing something that would affect them (e.g. levelling up, changing form, using certain items on the Pokémon) the stats are recalculated and resaved.

I believe the latest games have the stats recalculated immediately, rather than waiting until level-up to dump any new EVs into them (as the older games did it).
 
180
Posts
12
Years
  • Age 36
  • Seen Aug 12, 2023
That's sort of how Essentials works. The stats are stored as separate variables, and upon changing something that would affect them (e.g. levelling up, changing form, using certain items on the Pokémon) the stats are recalculated and resaved.

I believe the latest games have the stats recalculated immediately, rather than waiting until level-up to dump any new EVs into them (as the older games did it).

I was hoping you'd reply some time, lol. You were a big help in my previous c++ question thread.

So, instead of on some condition, it just recalculates the stats after an EV is given in new games? This is a bit off topic I know, but does it recalculate during battle after every time one Pokemon KOs the other, or after the battle is over with no level up?

Back on-topic: Is it correct form if I included a getter function be called in a class constructor?
 

th3shark

Develops in AS3/C++
79
Posts
10
Years
Well to each there own for calculated stats, I suppose.

Is it correct form if I included a getter function be called in a class constructor?
Is it okay to call a getter function from a class constructor? I don't see why not. Constructors are usually for setting and initializing data though, so why would you need to do this?
 

Maruno

Lead Dev of Pokémon Essentials
5,285
Posts
16
Years
I was hoping you'd reply some time, lol. You were a big help in my previous c++ question thread.

So, instead of on some condition, it just recalculates the stats after an EV is given in new games? This is a bit off topic I know, but does it recalculate during battle after every time one Pokemon KOs the other, or after the battle is over with no level up?
Essentials is a little haphazard about when it recalculates stats, because I haven't specifically looked at that. Stats are recalculated upon level-up (obviously), and if a Pokémon's form changes, or an EV-altering item is used on it, or it Transforms, or if it evolves. Currently a Pokémon will not recalculate its stats due to gaining EVs from battle, and those EVs will go unused until one of the aforementioned events.

That's just how Essentials works at the moment. It sounds nearly correct, so far as I know, except it should also recalculate upon gaining EVs from battle.

Thinking about it, if stats are now supposed to always take all EVs into account all the time, it's redundant to save the stat values separately. They can indeed be calculated when required (from the base stat/EVs/IVs/nature).
 

th3shark

Develops in AS3/C++
79
Posts
10
Years
Thinking about it, if stats are now supposed to always take all EVs into account all the time, it's redundant to save the stat values separately. They can indeed be calculated when required (from the base stat/EVs/IVs/nature).
Yeah, there's that too.

Here's a C++ equivalent to how it works in Evoas:
Code:
#include <math.h>

int getLevel(){
    double l = pow(_exp*_levelUpSpeed,1.0/3);
    if (ceil(l) - l < .0000001){ //rounding errors
        l = ceil(l);
    }
    return int(l);
}
int getAtk(){
    //original formula, replace with the official formula using EVs, IVs, etc.
    return statAtkCalculate(_baseAtk, getLevel(), _gender, _trainAtk);
}
 
180
Posts
12
Years
  • Age 36
  • Seen Aug 12, 2023
I actually look at it a slightly different way I think. Just call the function method that calculates stats for pokemon after certain stat altering events: EV-altering items, on level up, on Pokemon KO, evolution, form changing, etc. For EV specific events, all you really need to do is call the same calculate stats method after EV altering items, and after your Pokemon KOs another one.


Code:
Player 1 and NPC sends out pokemon.

// ... battley stuff

Player 1 Pokemon KOs NPC's pokemon
If ( !Max_EV(); )
{
     Get info of opponent's pokemon EV reward
     Add opponent's pokemon EV reward to player 1's first pokemon EV values
     If other player's pokemon were brought in during battle
          Add opponent's KO'd pokemon EV reward to player's other Pokemon
}
Where Max_EV() would return a bool value '1' if your pokemon's max EVs of 510 have been reached, and 0 otherwise. Of course I didn't take into account if the other pokemon brought out during battle has max EVs, nor did I take into account individual max EV values of 255. Too much pseudocode to write here. :P You get my idea. I'm still a n00b programmer like I said, and I'm pretty sure there's a cleaner, more efficient way to implement this, but yeah.

I do have an STL question. Is there an STL container where you can switch element spots? Like, say switch around what [0] and [4] point to without destroying anything? the 1st element now is set to the 5th element, and 5th now set to 1st. Something like that?
 
Last edited:

Maruno

Lead Dev of Pokémon Essentials
5,285
Posts
16
Years
I actually look at it a slightly different way I think. Just call the function method that calculates stats for pokemon after certain stat altering events: EV-altering items, on level up, on Pokemon KO, evolution, form changing, etc. For EV specific events, all you really need to do is call the same calculate stats method after EV altering items, and after your Pokemon KOs another one.
You could do that, and that's what Essentials currently does (with one missing call). However, if there is no situation where the latest EVs are not counted, then functionally there's no difference between this and calculating the stats on the fly when needed. And at least with the on-the-fly calculations, you don't have to throw calls to the calcStats method all over the place, nor do you use an additional 6 variables to store the stat values which are redundant.
 
180
Posts
12
Years
  • Age 36
  • Seen Aug 12, 2023
I'm not too familiar with on-the-fly calculations done in programming. My thinking whenever there was a change, you'd have to be specific on that change. What am I not understanding here?
 

Maruno

Lead Dev of Pokémon Essentials
5,285
Posts
16
Years
What I mean is that, when asking a Pokémon object what its Attack stat is (for example), instead of returning a saved variable which is updated each time an EV changes, a value for the Attack stat is calculated there and then and returned (but isn't saved anywhere).

Even if the Attack stat doesn't change between two instances of asking the Pokémon object what it is, it'll still be calculated both times.

I don't know if the correct term is getter or accessor or whatever. I just mean that you do the calculation on the spot when you need the stat, rather than preparing the stat value in advance (i.e. each time an EV changes) and keeping it around until you need it.
 

th3shark

Develops in AS3/C++
79
Posts
10
Years
I do have an STL question. Is there an STL container where you can switch element spots? Like, say switch around what [0] and [4] point to without destroying anything? the 1st element now is set to the 5th element, and 5th now set to 1st. Something like that?
I dunno. Just do this:
Code:
Pokemon* temp = team[0];
team[0] = team[5];
team[5] = temp;

@Mods we need an Audino smiley
 
180
Posts
12
Years
  • Age 36
  • Seen Aug 12, 2023
What I mean is that, when asking a Pokémon object what its Attack stat is (for example), instead of returning a saved variable which is updated each time an EV changes, a value for the Attack stat is calculated there and then and returned (but isn't saved anywhere).

Even if the Attack stat doesn't change between two instances of asking the Pokémon object what it is, it'll still be calculated both times.

I don't know if the correct term is getter or accessor or whatever. I just mean that you do the calculation on the spot when you need the stat, rather than preparing the stat value in advance (i.e. each time an EV changes) and keeping it around until you need it.

Ahh, well I wasn't thinking along the lines of returning the variable. I was thinking more along the lines of assignment. CalculateStats(); just reads information of your pokemon object's EVs, IVs, nature, and base stats and assigns the final value based on the stat formulas.

So, I could make all my stat variables private within the class and can only be changed by CalculateStats() since it's code within the class, and when dealing with adding or subtracting EVs, I could send a pokemon's reward EVs by const_reference through a function method defined in the class that takes the reference variables' values and adds the numbers to the object's current EVs; checking if max EVs first, of course. Since EVs are only given, and not taken in battle, you only need to add.

Now that I'm thinking about it, why not a method that does what I said above in addition to having that method call the CalculateStats() function after giving the reward EVs?
Edit: An item class can also have its own reward EV method doing what I said above, with the addition of subtracting EVs for certain berries. Warn me if I'm way off track here....... seriously. I'm just thinking up stuff of what I could do. I'm kind of just mind vomiting if you will... Seriously, stop me!! Lmao

As far as getters or setters. I found this page to be informative. http://www.zeuscmd.com/tutorials/cplusplus/50-gettersandsetters.php So, for example, my CalculateStats() function would be a setter. Some kind of function method to read the stats, like outputting a pokemon stats, would be a getter -> GetStats()
 
Last edited:

Maruno

Lead Dev of Pokémon Essentials
5,285
Posts
16
Years
It looks like you're still fixed on having a pokemon.attack variable, using CalculateStats() to give it a particular value, and then looking at that value when you want to know the Pokémon's attack stat. I'm saying that you don't need to do this.

pokemon.attack() is a public getter which solely contains the code: return CalculateStat(Stats::Attack). The actual value of the attack stat isn't saved anywhere in the Pokémon class, because it doesn't need to be. That's all you need. The CalculateStat(stat) method will take into account the current EVs, and returns the calculated value for the stat given as the argument. All you need to worry about is changing the Pokémon's EVs.

The main benefit is that you don't use as many variables, and you don't need to make sure you put a call to pokemon.CalculateStats() everywhere. It's all automatic.
 
Back
Top