Pokemon game

I am trying to make a game similar to pokemon but i have a problem.. i want to let the player choose his own pokemon but I have no idea how to set the pokemon as his own as there is more than one choice.
I am using voids for the pokemon but I am open to any suggestions. Ill post my code though it might be a bit messy and I know it is wrong. I will only post one of the pokemons code. In my code for example i dont know what myP (my Pokemon) should be.
Thank you very much.

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
  #include <iostream>

using namespace std;
#include <string>
#include <sstream>
#include <time.h>
#include <cstdio>
#include <fstream>
#include <limits>
string pokemonName;
string myGender;
string myName;
int attack;
int spAttack;
int defence;
int spDefence;
int speed;
int hp;
int level;
int type;
string a;
string myChoice;
void charmander()
{
	pokemonName = "charmander";
	attack = 10;
	spAttack = 15;
	spDefence = 5;
	defence = 6;
	speed = 6;
	hp = 22;

}

int main()

{
  cout<<"Why hello there! Have you been waiting for a long time?"<<endl;
  cout<<"Im sorry I dont have my glasses and therefore cant see you very well."<<endl;
  cout<<"Are you a boy or a girl?"<<endl;
  cin>>myGender;
  cout<<"Ah ok so youre a "<<myGender<<". And what is your name?"<<endl;
  cin>>myName;
  cout<<"Ok, "<<myName<<", and are you prepared to receive your first pokemon?"<<endl;
  cin>> a;
  for(int i=0; i<500; i++)
  {
	  cout<<"......................"<<endl;
  }
 cout<<"Well of course you are! If you werent you wouldnt have come here! Silly me.."<<endl;
 cout<<"OK here we go..I have four different pokemon for you to choose from.."<<endl;
 int r=rand()%60;
 if (r>=10)
 {
	 cout<<"Youre options are: charmander, mareep, magikarp, treecko and pinsir."<<endl;
 }

 if (r<10 && r>=20)
 {
	 cout<<"Youre options are: pidgey, eevee, porygon, tyrogue and larvitar."<<endl;
 }
  
  if (r<20 && r>=30)
 {
	 cout<<"Youre options are: charmander,eevee, magikarp, tyrogue and pinsir."<<endl;
 }
  
  if (r<30 && r>=40)
 {
	 cout<<"Youre options are: pidgey, mareep, porygon, treecko and larvitar."<<endl;
 }
  
    if (r<40 && r>=50)
 {
	 cout<<"Youre options are: charmander, mareep, magikarp, tyrogue and larvitar."<<endl;
 }
  
    if (r<50 && r>=60)
 {
	 cout<<"Youre options are: pidgey, mareep, porygon, treecko and pinsir."<<endl;
 }
  
  cout<<"Which pokemon do you want?"<<endl;
  cin>>myChoice;
  if ( myChoice == "charmander")
  {
	   myP == charmander;
  }
  if ( myChoice == "mareep")
  {
	   myP == mareep;
  }
  if ( myChoice == "magikarp")
  {
	   myP == magikarp;
  }
  if ( myChoice == "treecko")
  {
	   myP == treecko;
  }
  if ( myChoice == "pinsir")
  {
	   myP == pinsir;
  }
  if ( myChoice == "pidgey")
  {
	   myP ==pidgey;
  }
  if ( myChoice == "eevee")
  {
	   myP == eevee;
  }
  if ( myChoice == "porygon")
  {
	   myP == porygon;
  }
  if ( myChoice == "tyrogue")
  {
	   myP == tyrogue;
  }
  if ( myChoice == "larvitar")
  {
	   myP == larvitar;
  }


  cout<<"Ok, now you are ready to start your adventure!"<<endl;
  cout<<"But before you leave, I would like to battle you."<<endl;
  cout<<"Prepare for your defeat! :)"<<endl;
std::cin.get();
 
   std::cout << "Press ENTER to continue...";
  std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );

  return 0;

}
You should make it where the person can only pick a pokemon from the list they were provided, you have it where they can pick any pokemon. Also, fix the grammar for parts of it. In the if statements listing the pokemon, you have you're where you should have your.
Hey what you should be doing actually is assigning numerical values (enumeration) to all of your different types of Pokemon. That way you're checking against an integer rather than a string. For example you could do this.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
	int myPokemonType;
	int attack;

	enum PokemonType
	{
		somepokemon1,
		somepokemon2
		//etc...
	};

	enum PokemonAttack
	{
		somepokemonattack1,
		somepokemonattack2
		//etc...

	};

	myPokemonType = somepokemon1;
	attack = somepokemonattack2;


Now that's an improvement and all but we can do one better. We can use Classes to hold the data about our pokemon, player, attacks, etc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Creates a class of type Player that you can create instances of.
class Player
{
private:
	std::string name; // Player name.
	Pokemon *activePokemon;  // Points to an object of type Pokemon.
	std::vector<Pokemon>allPokemon; // Vector that stores all of your Pokemon objects(different pokemon)

};

// Creates a class of type Pokemon that you can create instances of.
class Pokemon
{
private:
	enum pokemonType // enum of different pokemon types.
	{
		somePokemon1,
		somePokemon2
		//..etc...
	};

	int hp; // Pokemon health;

};


Using a Class you can have a Player Object that holds a Pokemon Object and all of the other data that it needs. This makes it so much easier to make calculations and whatnot. Lets say you have more than one pokemon. How is the program going to know which pokemon is active? Using your original code you'd have to make an std::string variable that held the name of the pokemon and then for EVERYTHING you did, you'd have to type if(currentPokemon == "pokemon name goes here" That's pretty inefficient. What you can do with using classes is this:
1
2
3
4
5
	Player player;

	player.activePokemon->attack;
	player.activePokemon->dismiss;
	player.activePokemon->doWhatever;

And it will always attack/do something with your active pokemon.

I hope i helped!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
string pokemonName;
string myGender;
string myName;
int attack;
int spAttack;
int defence;
int spDefence;
int speed;
int hp;
int level;
int type;
string a;
string myChoice;
void charmander()
{
	pokemonName = "charmander";
	attack = 10;
	spAttack = 15;
	spDefence = 5;
	defence = 6;
	speed = 6;
	hp = 22;

}

This code is shouting really loud to you, wanting you to wrap it inside a class.
I'm not going to get into many details, but one of the ways for making such game would be making a class "Pokemon". It's even easier then making monsters in games - monsters can be different, all pokemons follow one simple scheme.
After you have Pokemon class, you can make "Player" class, that will have inventory, badges, name, time spent in game, pokemons, and all other save/game data you may want.
Right now I'm talking about clone of Nintendo's Pokemon games for GameBoy/Nintendo DS/others. However, if I were to make such game, this would be my starting point.

Also, your code has few flaws, and one of which is the very design of pokemon - you have global variables for all pokemons, meaning that if two pokemons fight each other, you will either have to constantly use firstpokemon() and anotherpokemon(), or you will use only stats from one pokemon.

Cheers!

Edit: from brief view, Renthalkx97 provided short overview with example code of what I am talking about.
Last edited on
Another possibility is to use something like a std::map, along with classes. For example, using a struct as an aggregation of the types, and storing the base stats of a pokemon (to facilitate leveling up):
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
42
43
44
#include <unordered_map>
#include <string>
#include <iostream>

struct PokemonData {
    int hp;
    int atk;
    int def;
    int spatk;
    int spdef;
    int speed;
};

const std::unordered_map<std::string, PokemonData> pokemon {
    {"charmander", {39, 52, 43, 60, 50, 65}},
    {"squirtle", {44, 48, 65, 50, 64, 43}},
    {"pidgey", {40, 45, 40, 35, 35, 56}},
    {"ekans", {35, 60, 44, 40, 54, 55}},
     // so on    
};

int main() {
    std::cout << "Choose a Pokemon. Your choices are: \n";

    // output all the valid pokemon names
    for (auto x : pokemon)
        std::cout << "  -  " << x.first << "\n";

    std::string choice;
    std::cin >> choice;

    // while an invalid choice is given
    while (!pokemon.count(choice)) {
         std::cout << "Invalid choice! Please enter a valid Pokemon: ";
         std::cin >> choice;
    }

    PokemonData myPokeData = pokemon[choice];

    std::cout << "Your Pokemon's base HP is " << myPokeData.hp << "!\n";

    // process battles, do things, etc.
    return 0;
}


Of course, you should use a player class too for managing your pokemon, but this approach would be a bit easier than storing an enum, as with the enum you still have to if/else all the time to get the stats for the pokemon, and why use an enum here if you have to display strings of the pokemon's name anyway?
Last edited on

Of course, you should use a player class too for managing your pokemon, but this approach would be a bit easier than storing an enum, as with the enum you still have to if/else all the time to get the stats for the pokemon, and why use an enum here if you have to display strings of the pokemon's name anyway?


You'd use an enum simply to make it easier on the programmer. That's all they're there for. What I'm saying is if you have say int pokemonType; You could still do what you did but instead of just having raw numbers you'd have the enums which make it more readable. For example:
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
class Pokemon
{
public:
	int pokemonType;

	enum pokemonType
	{
		Fire,
		Water,
		//etc...
	};
};

int main()
{
	Pokemon Poke;

	Poke.pokemonType = Poke.Fire;

	switch(Poke.pokemonType)
	{
		case Poke.Fire:
			// takes inreased damage versus Water type pokemons
			break;
		//etc
	}

        return 0;
}


That is how I would use the enums.
Last edited on
Yes, I agree with that. I was referring to using the enums for the actual names of the Pokemon, which would be counter effective, as you obviously want to be displaying the name of the Pokemon too. In a case where you don't need to use switch statements, using enums can make the code base harder to maintain as well. However, I fully agree with using enums for the type system. Also, it generally makes more sense for the variable containing the current enum to be one of the enum, like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Pokemon {
    public:
        enum class Type : unsigned int {
            Fire,
            Water,
            // etc...
        };

        Type getType() const { return _type; }
        void setType(Type type) { _type = type; }

    private:
        Type _type;
};


And then you do the switch statements like this:
1
2
3
4
5
6
7
8
9
10
11
switch (Poke.getType()) {
    case Pokemon::Type::Fire: {
        // takes increased damage versus Water type attacks
    } break;

    case Pokemon::Type::Water: {
        // takes increased damage versus Grass type attacks
    } break;

    // etc.
}


This just makes it easier on the developer and maintainers to see what falls as part of what, and if you have multiple enums it prevents clashes between their values. It also prevents you from doing stupid things (for example, Poke.setType(6)) which make no sense to someone looking on at your code.
Ahhh I misunderstood you what you posted. My bad.
Thats all right, I should probably have explained more clearly... :)
thank you very much to all, helped me very much. If you have any more tips please post them, im open to ideas
Will you please post the final code, I would like to see it.
i got one question though, I make the pokemon types, but then how do i assign the pokemon itself into the type? like imagine a squirtle, it is a water type, do i make a class for squirtle or what should i do? im lost please help me.
and also i cant seem to get the unordered map working, i get a expected a declaration message.
thank you
Last edited on
Could you post the exact message for your error? Anyway, for the types, simply add a type field to your data structure. Here is an example:
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
#include <iostream>
#include <string>
#include <unordered_map>

// either an enum
enum class Types {
    NOTYPE,  // placeholder for if a second type doesn't exist
    Water,
    Fire,
    Grass,
    // ...
};
// or a set

struct PokemonData {
    int hp;
    int attack;
    int defense;
    int spatk;
    int spdef;
    int speed;
    Types type1;
    Types type2;
};

const std::unordered_map<std::string, PokemonData> Pokemon = {
    {"charmander", {39, 52, 43, 60, 50, 65, Types::Fire, Types::NOTYPE}},
    {"squirtle", {44, 48, 65, 50, 64, 43, Types::Water, Types::NOTYPE}},
    {"pidgey", {40, 45, 40, 35, 35, 56, Types::Normal, Types::Flying}},
    {"ekans", {35, 60, 44, 40, 54, 55, Types::Poison, Types::NOTYPE}},
     // so on    
};

int main() {
    // ...
}


Of course, really you should be using a class to store your pokemon as well, but I can't be bothered to do everything for you.
Topic archived. No new replies allowed.