キーワード辞典
かなり乱暴なクラスの話(2)

登録日 13/06/01   更新日 13/06/04


この辺って、 言語処理系によってもかなり違って来るので、 物凄くざっくりと。

クラスの継承

クラスでは、コードの再利用が出来る。 これを継承と呼ぶ。 例えば、 ロールプレイングゲームのキャラクターで、 全ての登場人物に共通な部分を作っておき、 それを継承して、別途、戦士や魔法使いといった特殊能力の部分を追加する、 といった事が出来る。


C++による、ロールプレイングゲーム風のサンプル例。 サイコロを振る方式に変えました。
時間も無くて、我ながら手抜きだ、というのは、自覚しております。 雰囲気だけです。実行時のエラー処理をしていないので要注意です。 敢えてインラインで書いているので コンパイルすると警告が出ることがあります。

基本となるPersonクラスを基底にして、 魔法使いのWizardクラスと戦士のFighterクラスを派生させています。 Personクラスでは、基本となるパラメタと行動を、 WizardとFighterの各クラスでは、 各々に特有のパラメタと行動を指定しています。 基底クラスでメンバをprotectedにすると、 派生クラスから以外のアクセスが出来なくなります。
面倒臭いので、していませんが、パラメタを増やしたり、 経験値によってパラメタを変化させたりも、出来ます。
右の図では、説明を単純にする為に main()の中で魔法使いと戦士を一人ずつ登場させていますが、 下のプログラムではmain()の外で配列で登場させています。 また、黒い矢印は、アクセスが可能かどうかをあらわしています。

// RynRPG2a.cpp		2013.06.03

#include <iostream>
#include <iomanip>
using namespace std;

class Person{					// 基底クラス Person
    protected:
	char name[10];				// 名前
	int  life;				// ライフポイント
	int  gold;				// ゴールド

	void kihon_init(int i){
		cout << i+1 << "人目の名前(10文字以内) ";
		fflush(stdin);
		fgets(name, sizeof(name), stdin);
		name[strlen(name) - 1] = '\0';
		life = 200;
		gold = 200;
	}

	void kihon_disp(){
			cout << setw(10) << name << "さん";
			cout << " life = " << setw(4) << life;
			cout << " gold = " << setw(4) << gold;
	}

    public:
	void takarakuji(){
		int flg;
		flg = rand() % 5;
		if(flg == 0){
			cout <<"1等! 100gold" << endl;
			gold += 90;
		}else if(flg == 1){
			cout << "2等  50gold" << endl;
			gold += 40;
		}else{
			cout << "はずれ!" << endl;
			gold -= 10;
		}
	}

	void name_disp(int i){
			cout << i+1 << ":" << name << " ";
	}
};

class Wizard : public Person{		// 派生クラス 魔法使い
    private:
	int maryoku;				// 魔力

    public:
	void tatakau(){
		int flg = rand() % 2;
		int flg2 = (rand() % maryoku) + 10;

		cout << name << "「わしの術を受けてみよ!」" << endl;
		if(flg !=0){
			cout << name << "さんの勝ち! ";
			cout << flg2 << "goldを手に入れた!" << endl;
			gold += flg2;
			maryoku += 10;
		}else{
			cout << name << "さんの負け! ";
			cout << flg2 << "のlifeとgoldのダメージ" << endl;
			gold -= flg2;
			life -= flg2;
		}
	}

	void hataraku(){
		cout << "わしは魔法使い。いやじゃ" << endl;
	}

	void init(int i){
		kihon_init(i);
		maryoku = 10;
	}

	void disp(){
		kihon_disp();
		cout << " maryoku = " << setw(4) << maryoku << endl;
	}
};

class Fighter : public Person{		// 派生クラス 戦士
    private:
	int buryoku;				// 武力

    public:
	void tatakau(){
		int flg, flg2;
		flg  = rand() % 2;
		flg2 = (rand() % 10) * buryoku + 10;

		cout << name << "「俺の剣を受けてみよ!」" << endl;
		if(flg !=0){
			cout << name << "さんの勝ち! ";
			cout << flg2 << "goldを手に入れた!" << endl;
			gold += flg2;
			buryoku++;
		}else{
			cout << name << "さんの負け! ";
			cout << flg2 << "のlifeとgoldのダメージ" << endl;
			gold -= flg2;
			life -= flg2;
		}
	}

	void hataraku(){
		int flg;

		flg = (rand() % 10) * 10 + 10;
		cout << name << "さんが" << flg << "goldを手に入れた!" << endl;
		gold += flg;
	}

	void init(int i){
		kihon_init(i);
		buryoku = 0;
	}

	void disp(){
		kihon_disp();
		cout << " buryoku = " << setw(4) << buryoku << endl;
	}
};

#define WNINZU 1					// 魔法使いの人数
#define FNINZU 2					// 戦士の人数
#define NINZU WNINZU + FNINZU

int saikoro();
int jinsen();

Wizard  w[WNINZU];
Fighter f[FNINZU];

int main()
{
	int i=1;
	int j;

	cout << "Wizards" << endl;
	for(j = 0; j < WNINZU; j++)
		w[j].init(j);
	cout << "Fighters" << endl;
	for(j = 0; j < FNINZU; j++)
		f[j].init(j);
	
	while((i > 0)&&(i < (NINZU + 1))){
		for(j = 0; j < WNINZU; j++){
			cout << "Wizard  ";
			w[j].disp();
		}
		for(j = 0; j < FNINZU; j++){
			cout << "Fighter ";
			f[j].disp();
		}
		i = saikoro();
	}
}

int saikoro()
{
	int me, i, j;
	me = rand() % 4;
	if(me < 2){
		cout << endl << "敵があらわれた!" << endl;
		i = jinsen();
		if((i > 0) && (i < (WNINZU + 1)))
			w[i-1].tatakau();
		else if((i > WNINZU) && (i < (NINZU + 1)))
			f[i-WNINZU-1].tatakau();
	}else if(me == 2){
		cout << endl << "バイト先を見つけた!" << endl;
		i = jinsen();
		if((i > 0) && (i < (WNINZU + 1)))
			w[i-1].hataraku();
		else if((i > WNINZU) && (i < (NINZU + 1)))
			f[i-WNINZU-1].hataraku();
	}else if(me == 3){
		cout << endl << "宝くじを10goldで買うことにした!" << endl;
		i = jinsen();
		if((i > 0) && (i < (WNINZU + 1)))
			w[i-1].takarakuji();
		else if((i > WNINZU) && (i < (NINZU + 1)))
			f[i-WNINZU-1].takarakuji();
	}
	return i;
}

int jinsen()
{
	int i,j;
	cout << "誰が? (";
	for(j = 0; j < WNINZU; j++)
		w[j].name_disp(j);
	for(j = 0; j < FNINZU; j++)
		f[j].name_disp(WNINZU + j);
	cout << ")";
	cin >> i;
	return i;
}





[ 赤い玉の画像 ] 「キーワード辞典」の目次へ

[ 黒板消しとチョーク受けの画像 ]