How can I make it so that I can use the appropriate constructor for a type of...

Started by
12 comments, last by SSJCORY 20 years, 5 months ago
player and still be able to use methods. I have a CPlayer class and a Barbarian class and a Necromancer class. I want the person to be able to choose which type they want to be. I tried to use...

void main(){
    int chartype;
    cout<<"1 barbarian , 2 necromancer";
    cout<<"Pick a type:";
    cin>>chartype;
    if(chartype == 1){
         Barbarian player;
    }
    else{
         Necromancer player;
    }
But then when i want to use a method it gives me errors... Is there a way to make it so I can do this... Here''s the full source code.

//Copyright 2003 Cory Fisher

#include<iostream>								//For cin,cout

#include<string>								//For string use

#include<stdio.h>								//For standard io

using namespace std;							//Dont know why just everyone says you should

string nameSet();								//Forward declaration of nameSet()

class CMonster;
class CPlayer;
class Barbarian;
class Necromancer;
class CPlayer{									//Base Player Class

private:
	int playerHealth;							//Begin of self explanatory section

	int playerMaxHealth;						
	int playerMana;								
	int playerMaxMana;							
	int playerLevel;							
	int playerStrength;			
	int playerSpeed;
	int playerDefense;
	int playerSkill;
	string playerName;
	string playerClass;							//End of self explanatory section

public:
	string skill[10];
	CPlayer():									
		playerHealth(0),						
		playerMaxHealth(0),
		playerMana(0),
		playerMaxMana(0),
		playerLevel(1),
		playerStrength(0),
		playerSpeed(0),
		playerDefense(0),
		playerSkill(1),
		playerName(""),
		playerClass("")
	{
	}
	int getHealth(){							//Begin Self Explanatory

		return playerHealth;
	}
	int getMaxHealth(){
		return playerMaxHealth;
	}
	int getMana(){
		return playerMana;
	}
	int getMaxMana(){
		return playerMaxMana;
	}
	int getLevel(){
		return playerLevel;
	}
	int getStrength(){
		return playerStrength;
	}
	int getSpeed(){
		return playerSpeed;
	}
	int getDefense(){
		return playerDefense;
	}
	int getSkill(){
		return playerSkill;
	}
	string getName(){
		return playerName;
	}
	string getClass(){
		return playerClass;
	}
	void setHealth(int newhealth){
		playerHealth = newhealth;
	}
	void setMaxHealth(int newmaxhealth){
		playerMaxHealth = newmaxhealth;
	}
	void setMana(int newmana){
		playerMana = newmana;
	}
	void setMaxMana(int newmaxmana){
		playerMaxMana = newmaxmana;
	}
	void setLevel(int newlevel){
		playerLevel = newlevel;
	}
	void setStrength(int newstrength){
		playerStrength = newstrength;
	}
	void setSpeed(int newspeed){
		playerSpeed = newspeed;
	}
	void setDefense(int newdefense){
		playerDefense = newdefense;
	}
	void setSkill(int newskill){
		playerSkill = newskill;
	}
	void setName(string newname){
		playerName = newname;
	}
	void setClass(string newclass){
		playerClass = newclass;
	}												//End of Self Explanatory

	void printBaseInfo(){							//Prints the things that are common to all characters

		cout<<"Name: "<<playerName<<endl;
		cout<<"	Level: "<<playerLevel<<endl;
	}
	void printSkills(){								//Prints all skills known

		cout<<"Skills Learned: ";
		for(int i = 1; i < 11; i++){
			if(playerSkill < i){
				break;
			}
			if(playerSkill > i){
					cout<<skill&lt;&lt;"</font>, <font color=darkred>";
			}
			if(playerSkill == i){
				cout&lt;&lt;skill&lt;&lt;endl;
			}

		}
	}
	void attack(CMonster *monster);

};
class Barbarian : public CPlayer{					<font color=gray>//Derived barbarian class
</font>
public:
	Barbarian(){									<font color=gray>//Default constructor set to what i like for a Barbarian
</font>
		setHealth(100);
		setMaxHealth(100);
		setMana(20);
		setMaxMana(20);
		setStrength(60);
		setSpeed(40);
		setDefense(60);
		setName(nameSet());
		setClass("</font>Barbarian<font color=darkred>");
		initSkills();
	}
	void printInfo(){							   <font color=gray>//Prints not always same stuff as other characters.
</font>
		system("</font>cls<font color=darkred><font color=darkred>");
		cout&lt;&lt;"</font></font>Class: <font color=darkred><font color=darkred>"&lt;&lt;getClass()&lt;&lt;endl;
		printBaseInfo();
		cout&lt;&lt;"</font></font>	Health: <font color=darkred><font color=darkred>"&lt;&lt;getHealth()&lt;&lt;"</font></font>/<font color=darkred><font color=darkred>"&lt;&lt;getMaxHealth()&lt;&lt;endl;
		cout&lt;&lt;"</font></font>	Mana: <font color=darkred><font color=darkred>"&lt;&lt;getMana()&lt;&lt;"</font></font>/<font color=darkred><font color=darkred>"&lt;&lt;getMaxMana()&lt;&lt;endl;
		cout&lt;&lt;"</font></font>	Strength: <font color=darkred><font color=darkred>"&lt;&lt;getStrength()&lt;&lt;endl;
		cout&lt;&lt;"</font></font>	Speed: <font color=darkred><font color=darkred>"&lt;&lt;getSpeed()&lt;&lt;endl;
		cout&lt;&lt;"</font></font>	Defense: <font color=darkred>"&lt;&lt;getDefense()&lt;&lt;endl;
		printSkills();
	}
	void initSkills(){							<font color=gray>//Initialize barbarians skills
</font>
		skill[0] = "</font>Bruise<font color=darkred>";
		skill[1] = "</font>Bash<font color=darkred>";
		skill[2] = "</font>Crush<font color=darkred>";
		skill[3] = "</font>Bang<font color=darkred>";
		skill[4] = "</font>Break<font color=darkred>";
		skill[5] = "</font>Boom<font color=darkred>";
		skill[6] = "</font>Crack<font color=darkred>";
		skill[7] = "</font>Shatter<font color=darkred>";
		skill[8] = "</font>Destroy<font color=darkred>";
		skill[9] = "</font>Annihilate<font color=darkred>";
	}

};
class Necromancer : public CPlayer{				<font color=gray>//Derived necromancer class
</font>
public:								
	Necromancer(){								<font color=gray>//Default constructor stats i want for a necromancer
</font>
		setHealth(100);
		setMaxHealth(100);
		setMana(60);
		setMaxMana(60);
		setStrength(20);
		setSpeed(60);
		setDefense(40);
		setName(nameSet());
		setClass("</font>Necromancer<font color=darkred>");
		initSkills();
	}
	void printInfo(){							<font color=gray>//Same as above
</font>
		system("</font>cls<font color=darkred><font color=darkred>");
		cout&lt;&lt;"</font></font>Class: <font color=darkred><font color=darkred>"&lt;&lt;getClass()&lt;&lt;endl;
		printBaseInfo();
		cout&lt;&lt;"</font></font>	Health: <font color=darkred><font color=darkred>"&lt;&lt;getHealth()&lt;&lt;"</font></font>/<font color=darkred><font color=darkred>"&lt;&lt;getMaxHealth()&lt;&lt;endl;
		cout&lt;&lt;"</font></font>	Mana: <font color=darkred><font color=darkred>"&lt;&lt;getMana()&lt;&lt;"</font></font>/<font color=darkred><font color=darkred>"&lt;&lt;getMaxMana()&lt;&lt;endl;
		cout&lt;&lt;"</font></font>	Strength: <font color=darkred><font color=darkred>"&lt;&lt;getStrength()&lt;&lt;endl;
		cout&lt;&lt;"</font></font>	Speed: <font color=darkred><font color=darkred>"&lt;&lt;getSpeed()&lt;&lt;endl;
		cout&lt;&lt;"</font></font>	Defense: <font color=darkred>"&lt;&lt;getDefense()&lt;&lt;endl;
		printSkills();
	}
	void initSkills(){							<font color=gray>//Same as above cept its for necromancer
</font>
		skill[0] = "</font>Fire<font color=darkred>";
		skill[1] = "</font>Flame<font color=darkred>";
		skill[2] = "</font>Burn<font color=darkred>";
		skill[3] = "</font>Big Burn<font color=darkred>";
		skill[4] = "</font>Blaze<font color=darkred>";
		skill[5] = "</font>Firestorm<font color=darkred>";
		skill[6] = "</font>Forest Fire<font color=darkred>";
		skill[7] = "</font>Flame of Demon<font color=darkred>";
		skill[8] = "</font>Smoke Rings<font color=darkred>";
		skill[9] = "</font>Hell Fire<font color=darkred>";
	}
};
class CMonster{
private:
	int health;
	int maxhealth;
	int defense;
	int speed;
	int strength;
public:
	CMonster(){
		health = 100;
		maxhealth = 100;
		defense = 100;
		speed = 100;
		strength = 100;
	}
	int getMonsterHealth(){
		return health;
	}
	void setMonsterHealth(int newhealth){
		health = newhealth;
	}
	int getMonsterDefense(){
		return defense;
	}
}big;
int chartype;
void getCharacterType(){									
	cout&lt;&lt;"</font>1) Barbarian\n<font color=darkred><font color=darkred>";
	cout&lt;&lt;"</font></font>2) Necromancer\n<font color=darkred><font color=darkred>";
	cout&lt;&lt;"</font></font>What kind of character would you like to be?<font color=darkred>";
	cin&gt;&gt;chartype;
}

void main(){									<font color=gray>//Main Does nothing haven''t started actual game coding yet
</font>
	getCharacterType();
	if(chartype == 1){
		Barbarian player;
	}
	else{
		Necromancer player;
	}
	cout&lt;&lt;player.getStrength();
}
string nameSet(){								<font color=gray>//It gets the name from the user when the constructor for 
</font>
	string charname;							<font color=gray>//the class is called;
</font>
	cout&lt;&lt;"</font>Enter a name:";
	cin&gt;&gt;charname;
	<font color=blue>return</font> charname;
}		
<font color=blue>void</font> CPlayer::attack(CMonster *monster){
	monster-&gt;setMonsterHealth((monster-&gt;getMonsterHealth() + (.050 * monster-&gt;getMonsterDefense())) - (getStrength()));
}
</pre><!–ENDSCRIPT–>
The error is player not defined… I hate asking so many questions but I couldn''t find out this information anywhere else.
Thanks yet again.

   

<hr>
<font face="" color="Blue">Favorite Quotes:</font><font face="" color="red">Gandalf: You shall not pass!</font>|<font face="" color="orange">Smeagol: We don''t need you!</font>|<font face="" color="violet">Sloth: Hey you guys!</font>|
<hr>   
Favorite Quotes:Gandalf: You cannot pass!|Smeagol: We don't need you!|Sloth: Hey you guys!|
Advertisement
A couple of things going on here:

1. When you declare a variable within a block (between two braces), it is only valid within the block. Like so:

if(a){    int b;    print(b); // can use it here!    {        print(b); // here, too!    }}print(b); // ERROR-- can't use it here!


2. A particular name in a particular scope can only refer to one datatype. It's one or the other. HOWEVER, if Barbarian and Necromancer inherit from a common base class, you can use virtual functions on a pointer to that base class to accomplish much the same thing. Read up on virtual functions in your C++ book.

How appropriate. You fight like a cow.

[edited by - sneftel on November 6, 2003 11:10:57 PM]
you can use inheritence

class Player{    // Common player functions};class Barbarian : public Player{};class Necromancer : public Player{}void main(){    Player* p = 0;    if( /* choice one*/ )        p = new Barabarian();    else        p = new Necromancer();}


You''ll have toput all the methods you want to use in the Player base class and then if you need different functionality for different classes, you can re-impliment them in the derived classes. read up on the keyword ''virtual''

:::: [ Triple Buffer ] ::::
[size=2]aliak.net
First of all, since you''re declaring the variable player in an if statement, it goes out of scope once you hit the end of the block.

Secondly, you need a pointer to the base class in order to use all of the common functions when you don''t know what type of player they will choose.

CPlayer *player = 0;if(chartype == 1){   player = new Barbarian();}else{   player = new Necromancer();}cout << player->getStrength();if (player != 0)   delete player;
The problem is in the scope of the local variable. When you have an if statement, and declare a variable inside a block (surrounded by braces), that variable is only valid inside the block. For example:

if (WorldIsFlat)
{
bool ColumbusWasWrong = true;
}

if (ColumbusWasWrong) // Compile error here!

When a variable is declared inside a block, it cannot be referenced outside the block.

You could have a CPlayer pointer, and have the different player variables declared outside the block, and then point the CPlayer to the appropriate variable. Or, do a ''new'' to create either of the player objects depending on the choice:


CPlayer *player;
if (chartype == 1)
player = new Barbarian();
else
player = new Necomancer();

// Use player

delete player;
To begin with, static variables exist only in the block of code they are defined in.
e.g.{    int i;}i = 8; // compiler error   

So you'll need polymorphism, basically

CPlayer* player;// get choice, thenplayer = new Barbarian;// orplayer = new Necromancer; 

This will be hard to use if you haven't learnt pointers and polymorphism, if you/when you have, it'll be easy.

Keep at it.

PS. I think there is a good tute at www.gametutorials.com

EDIT: Beaten to it 4 times!

Wizza Wuzza?

[edited by - Chris Hare on November 6, 2003 11:19:17 PM]

[edited by - Chris Hare on November 6, 2003 11:21:02 PM]
quote:Original post by Chris Hare
To begin with, static variables exist only in the block of code they are defined in.
Hrmph... while that is kindof true, noone have spoken about static variables. One could claim that statics, as opposed to non-statics, do exist outside the block they are defined in. You may have meant local variables, though.
Well, first of all, when you declare a variable, you can only use it in that sc--

oh. I already replied. Nevermind.

How appropriate. You fight like a cow.
'But then when i want to use a method it gives me errors... Is there a way to make it so I can do this...'

What are your exact errors?

I think you need to ask yourself if inheritence is really needed for your game. You could implement just the 'CPlayer' class and instead of using a derived class to initialize all of the member variables, just make a function for each player class that initializes the variables to the proper values.

It would make things a lot simpler for you at the moment. Sometimes it's far better to have a completed project that may not be the most technical piece of work, than to have a technically complex project which you never get to work.

Edit: Maybe go one step further an just turn the CPlayer class into a struct. Since you're exposing all of the private class data via get and set methods, you're not really achieving any sort of true data encapsulation. You can still use a constructor with a struct to initialize default values if you need to, but even that could be avoided.


[edited by - SysOp_1101 on November 6, 2003 11:44:02 PM]
SysOp_1101
quote:
quote:
--------------------------------------------------------------------------------
Original post by Chris Hare
To begin with, static variables exist only in the block of code they are defined in.
--------------------------------------------------------------------------------

Hrmph... while that is kindof true, noone have spoken about static variables. One could claim that statics, as opposed to non-statics, do exist outside the block they are defined in. You may have meant local variables, though.


Sorry, I meant ''statically created'' object, as opposed to dynamically with new / malloc, not as in the C++ keyword.



Wizza Wuzza?

This topic is closed to new replies.

Advertisement