戻り値のあるメソッドの学習

戻り値のあるメソッドを学ぶことで、メソッドが処理の結果を返し、その結果を活用する方法を理解できます。RPGでは「攻撃力を計算する」や「クリティカル判定を行う」など、戻り値を使う場面が多くあります。


前提

次の作成を終えてから取り組んでください

1. 戻り値の基本

  • 戻り値はメソッドが呼び出し元に結果を返す仕組みです。
  • 例えば、「攻撃力を計算するメソッド」では、計算結果(数値)を返します。

2. 攻撃力を計算するメソッド

以下は、攻撃力を計算するメソッドを private にして、外部からは呼び出せないようにした例です。

Characterクラス

using System;

class Character
{
    public string Name; // 名前
    public int HP;      // ヒットポイント
    public int MP;      // マジックポイント
    public string Job;  // 職業
    public int Level = 1; // レベル
    public int EXP = 0;   // 経験値

    // 攻撃力を計算する(外部からは呼び出せない)
    private int CalculateAttackPower()
    {
        Random random = new Random();
        return Level * 10 + random.Next(0, 6); // レベルに比例 + ランダム値
    }

    // 攻撃する(ダメージを計算して返す)
    public int Attack()
    {
        int damage = CalculateAttackPower(); // 戻り値を利用
        Console.WriteLine($"{Name}は攻撃した! 攻撃力: {damage}");
        return damage;
    }
}

3. 戻り値を利用する戦闘システム

メソッドの戻り値を利用して、キャラクター同士が攻撃し合う戦闘システムを実装します。

Program.cs

using System;

namespace RPGExample
{
    class Program
    {
        static void Main(string[] args)
        {
            // キャラクターの作成
            Character hero = new Character { Name = "ヒロト", HP = 100, MP = 20, Job = "勇者" };
            Character enemy = new Character { Name = "ゴブリン", HP = 60, MP = 10, Job = "敵" };

            Console.WriteLine("戦闘開始!");
            Console.WriteLine($"{hero.Name} VS {enemy.Name}");

            // 戦闘ループ
            while (hero.HP > 0 && enemy.HP > 0)
            {
                // 勇者の攻撃
                Console.WriteLine($"{hero.Name}の攻撃!");
                int heroDamage = hero.Attack(); // 戻り値を利用
                enemy.HP -= heroDamage;
                Console.WriteLine($"{enemy.Name}のHP: {enemy.HP}");

                // 敵の反撃
                if (enemy.HP > 0)
                {
                    Console.WriteLine($"{enemy.Name}の反撃!");
                    int enemyDamage = enemy.Attack(); // 戻り値を利用
                    hero.HP -= enemyDamage;
                    Console.WriteLine($"{hero.Name}のHP: {hero.HP}");
                }
            }

            // 勝敗判定
            if (hero.HP > 0)
            {
                Console.WriteLine($"{hero.Name}の勝利!");
            }
            else
            {
                Console.WriteLine($"{enemy.Name}の勝利!");
            }
        }
    }
}

4. ランダムなクリティカル攻撃

戻り値を使って、クリティカル攻撃(ダメージ2倍)を実装します。

Characterクラスの追加メソッド

public int CalculateCriticalAttackPower()
{
    Random random = new Random();
    int isCritical = random.Next(0, 2); // 0か1をランダムに生成
    int damage = CalculateAttackPower();
    if (isCritical == 1)
    {
        Console.WriteLine("クリティカルヒット!");
        return damage * 2;
    }
    return damage;
}

5. 戻り値を確認するコード例

メインプログラムで確認する例:

// 勇者の攻撃力を確認
int attackPower = hero.Attack();
Console.WriteLine($"{hero.Name}の攻撃力: {attackPower}");

// クリティカル攻撃を確認
int criticalAttack = hero.CalculateCriticalAttackPower();
Console.WriteLine($"{hero.Name}のクリティカル攻撃力: {criticalAttack}");

実行結果例:

ヒロトは攻撃した! 攻撃力: 15
ヒロトの攻撃力: 15
クリティカルヒット!
ヒロトのクリティカル攻撃力: 30

6. 戻り値のあるメソッドの練習問題

練習1: 敵の行動をランダムに決める

  • メソッドを作成し、敵が「攻撃」「防御」「逃げる」のいずれかをランダムに返す。
public string DecideEnemyAction()
{
    string[] actions = { "攻撃", "防御", "逃げる" };
    Random random = new Random();
    int index = random.Next(actions.Length);
    return actions[index];
}

使用例:

string enemyAction = enemy.DecideEnemyAction();
Console.WriteLine($"{enemy.Name}は{enemyAction}を選択した!");

ポイント解説

  1. 戻り値を使うメリット:
    • メソッドを呼び出した後の処理を柔軟に制御できます。
    • 例えば、「攻撃力を返す」「クリティカル判定を行う」など。
  2. private メソッドの使い方:
    • CalculateAttackPowerprivate にすることで、内部処理として隠蔽し、安全性を高めます。
  3. ランダム性と条件分岐:
    • ランダム性やクリティカル判定を導入することで、実践的な戻り値の活用方法を学べます。

この例では、戻り値を使う具体的なメリットを理解しながら、RPGのシステムを通じて実践的に学べる構成になっています!

全体のコード

以下は、これまでの要素をすべて統合した「トータルのメインメソッド」です。勇者とゴブリンが戦う戦闘システムに、戻り値を利用した攻撃力の計算やクリティカル攻撃を取り入れています。


メインメソッド(Program.cs


using System;

namespace RPGExample
{
    class Program
    {
        static void Main(string[] args)
        {
            // キャラクターの作成
            Character hero = new Character { Name = "ヒロト", HP = 100, MP = 20, Job = "勇者", Level = 5 };
            Character enemy = new Character { Name = "ゴブリン", HP = 60, MP = 10, Job = "敵", Level = 3 };

            Console.WriteLine("=== 戦闘開始 ===");
            Console.WriteLine($"{hero.Name} VS {enemy.Name}");
            Console.WriteLine($"勇者: HP={hero.HP}, MP={hero.MP}, レベル={hero.Level}");
            Console.WriteLine($"敵: HP={enemy.HP}, MP={enemy.MP}, レベル={enemy.Level}");

            // 戦闘ループ
            while (hero.HP > 0 && enemy.HP > 0)
            {
                // 勇者の攻撃
                Console.WriteLine($"\n{hero.Name}の攻撃!");
                int heroDamage = hero.CalculateCriticalAttackPower(); // クリティカル判定付き攻撃
                enemy.HP -= heroDamage;
                Console.WriteLine($"{enemy.Name}の残りHP: {enemy.HP}");

                // 敵の反撃
                if (enemy.HP > 0)
                {
                    Console.WriteLine($"{enemy.Name}の反撃!");
                    int enemyDamage = enemy.CalculateCriticalAttackPower(); // クリティカル判定付き攻撃
                    hero.HP -= enemyDamage;
                    Console.WriteLine($"{hero.Name}の残りHP: {hero.HP}");
                }
            }

            // 勝敗判定
            if (hero.HP > 0)
            {
                Console.WriteLine($"\n{hero.Name}の勝利!");
                hero.GainExperience(50); // 経験値を獲得
            }
            else
            {
                Console.WriteLine($"\n{enemy.Name}の勝利!");
            }

            Console.WriteLine("\n=== 戦闘終了 ===");
        }
    }
}

関連クラス

以下に必要な Character クラスの完全なコードを再掲します。

Character.cs

using System;

namespace RPGExample
{
    class Character
    {
        public string Name; // 名前
        public int HP;      // ヒットポイント
        public int MP;      // マジックポイント
        public string Job;  // 職業
        public int Level = 1; // レベル
        public int EXP = 0;   // 経験値

        // 攻撃力を計算する(内部処理)
        private int CalculateAttackPower()
        {
            Random random = new Random();
            return Level * 10 + random.Next(0, 6); // レベルに比例 + ランダム値
        }

        // クリティカル判定付き攻撃
        public int CalculateCriticalAttackPower()
        {
            Random random = new Random();
            int isCritical = random.Next(0, 2); // 0か1をランダムに生成
            int damage = CalculateAttackPower();
            if (isCritical == 1)
            {
                Console.WriteLine("クリティカルヒット!");
                return damage * 2; // クリティカルでダメージ2倍
            }
            return damage;
        }

        // 経験値を得る
        public void GainExperience(int amount)
        {
            EXP += amount;
            Console.WriteLine($"{Name}は{amount}の経験値を得た!");

            // レベルアップ判定
            if (EXP >= 100)
            {
                LevelUp();
            }
        }

        // レベルアップ処理
        private void LevelUp()
        {
            EXP -= 100;
            Level++;
            HP += 10; // レベルアップでHP増加
            MP += 5;  // レベルアップでMP増加
            Console.WriteLine($"{Name}はレベル{Level}に上がった!");
        }
    }
}

実行結果例

=== 戦闘開始 ===
ヒロト VS ゴブリン
勇者: HP=100, MP=20, レベル=5
敵: HP=60, MP=10, レベル=3

ヒロトの攻撃!
クリティカルヒット!
ゴブリンの残りHP: 40

ゴブリンの反撃!
ヒロトの残りHP: 90

ヒロトの攻撃!
ゴブリンの残りHP: 20

ゴブリンの反撃!
クリティカルヒット!
ヒロトの残りHP: 70

ヒロトの攻撃!
ゴブリンの残りHP: 0

ヒロトの勝利!
ヒロトは50の経験値を得た!

=== 戦闘終了 ===

ポイント

  1. 戻り値の活用:
    • CalculateAttackPowerCalculateCriticalAttackPower を通じて、攻撃力の計算結果を柔軟に活用。
    • 戻り値を使って「どのくらいのダメージを与えるか」を制御。
  2. ランダム性とクリティカル判定:
    • クリティカル攻撃やランダムな攻撃力を取り入れ、戦闘にリアリティを追加。
  3. レベルアップと経験値:
    • 戦闘後に経験値を獲得し、一定量たまるとレベルアップ。
  4. プログラムの流れ:
    • 戦闘ループ内でキャラクターの行動を交互に処理。
    • 戦闘終了後に結果を表示。

C#,メソッド

Posted by hidepon