講義メモ

オブジェクト指向演習:「3人の魔導士」を仕上げて「大魔道出現」へ
ゲーム開発演習:imageオブジェクトのプロパティ、画像の重ね合わせなど

RPG演習5 「3人の魔導士」仕様の検討(つづき)

「3人の魔導士」の問題点を解決しよう=第3段階

① 3人の魔導士のHP、MPの初期値が異なるようにしたい
・合わせて、Randomオブジェクトを1個にして効率を上げるとよい
・MadoshiクラスのRandomオブジェクトを3人の魔導士が順に使えば良い
・方法は、MadoshiのRandomオブジェクトをstaticにしよう

② HPが尽きた魔導士は攻撃できないようにしたい
・MadoshiクラスのFight()に「hpが0以下なら0を返す」を追記

③ HPが尽きた魔導士を攻撃すると「魔導士●はもういない」と表示して無視し、魔導士の攻撃に進もう
・minimadouクラスで魔道士を攻撃する前にその魔道士のHPが0超であることをチェックしよう
・0以下の場合は「魔導士●はもういない」と表示する

④ 魔導士の攻撃中にプレイヤーのHPが0以下になったら、そこで終わらせたい
・魔道士の攻撃を全魔導士について繰返す条件に、プレイヤーのHPが0超であることを加えれば良い
・逃げられなくて、魔道士の攻撃を全魔導士について繰返す場合も同様

⑤ 3人を倒したら「3人の魔導士を倒した!」と表示しよう
・「あなたは死にました。」の表示後にreturnしよう(Mainメソッドから抜ける=終了)
・メインループの終了後に(逃げた場合を覗いて)「3人の魔導士を倒した!」と表示
・この判断のために、入力用のansをnullで初期化しておこう

作成例

//オブジェクト指向演習 RPG演習5(5)
using System;
class Madoshi { //魔導士を表すクラス
    int mp; //MP(カプセル化(p.166)のためにpublicにしない)
    int hp; //HP(〃)
    int id; //魔導士番号
    static Random rnd = new Random(); //【変更】乱数用のRandomクラスのインスタンスを生成
    public Madoshi(int id) { //コンストラクタ(p.167)で魔導士番号を受け取る
        mp = rnd.Next(10); //0~9の間のランダムな整数を得てMPの初期値とする
        hp = 10 + rnd.Next(10); //10~19の間のランダムな整数を得てHPの初期値とする
        this.id = id; //引数から魔導士番号を受け取る
    }
    public int HP { //HPを返すプロパティ
        get { return hp; } 
    }
    public void DispInfo() { //魔導士の情報を表示する
        Console.Write("魔導士{0}(HP={1} MP={2})", id, hp, mp); //情報表示(改行しない)
    }
    public int Fight() { //魔導士があなたを攻撃し、あなたのダメージ値を返す
        if (hp <= 0) return 0; //【追加】死んでいる場合は0を返す
        if (rnd.Next(2) == 1) { //確率1/2で魔法攻撃かどうかを選ぶ
            int j = rnd.Next(5) + 1; //消費MPは1~5の乱数
            DispInfo(); // 魔導士の情報を表示する
            Console.WriteLine("は消費MP" + j + "の魔法を唱えた!");
            if (mp < j) { // MP不足?
                Console.WriteLine("MPが足りない!");
                return 0; // あなたのダメージ=0を返す(攻撃終了)
            } else { // MP充足?
                Console.WriteLine("あなたは" + j * 4 + "のダメージを受けた!");
                mp -= j; //MP消費
                return j * 4; //あなたのダメージ=消費MPの4倍を返す(攻撃終了)
            }
        } else { //通常攻撃?
            int k = rnd.Next(5) + 1; //攻撃力は1~5の乱数
            DispInfo(); //魔導士の情報を表示する
            Console.WriteLine("の攻撃!");
            Console.WriteLine("あなたは" + k + "のダメージを受けた!");
            return k; //あなたのダメージ=1~50を返す(攻撃終了)
        }
    }
    public void Damage() { //魔導士があなたからダメージをくらう
        int k = 5 + rnd.Next(5); //あなたの攻撃力は5~9の乱数
        Console.WriteLine("あなたの攻撃!");
        DispInfo(); //魔導士の情報を表示する(攻撃を受けた後の魔導士のHPを表示)
        Console.WriteLine("に" + k + "のダメージを与えた!");
        hp -= k; //魔導士のHPをダウン
    }
}
class minimadou { //ゲーム本体のクラス
    public static void Main() { //ゲームを進行するメソッド
        Random rnd = new Random(); //乱数用のRandomクラスのインスタンスを生成
        string ans = null; //【変更】入力用
        // 戦闘開始
        int myhp = 40 + rnd.Next(21); //あなたのHPを40+0から40+20にする
        Madoshi[] m = { new Madoshi(1),new Madoshi(2),new Madoshi(3) }; //全魔導士を生成
        foreach (var w in m) { //全魔導士ついて繰返す
            w.DispInfo(); //魔導士の情報を表示する
            Console.WriteLine("が現れた。");
        }
        // 戦闘中(あなたが死ぬか,魔導士が死ぬまで繰り返す)
        while (myhp > 0 && (m[0].HP > 0 || m[1].HP > 0 || m[2].HP > 0)) { //あなたとどれかの魔導士のHPがある間
            Console.Write("残りHPは{0}です。どれを攻撃しますか?(1/2/3:魔導士1,2,3 0:やめる):", myhp); 
            ans = Console.ReadLine(); //回答を得る
            int ansi = int.Parse(ans) - 1; //整数変換して-1し魔導士の添字0~2を得る
            if (ansi == 0 || ansi == 1 || ansi == 2) { //魔導士を攻撃?
                if (m[ansi].HP > 0) { //【追加】活きている魔導士?
                    m[ansi].Damage(); //魔導士を攻撃する
                    if(m[ansi].HP <= 0) { //魔導士[]を倒した?
                        Console.WriteLine("魔導士{0}を倒した!", ans);
                    }
                } else { //【以下追加】
                    Console.WriteLine("魔導士{0}はもういない!", ans);
                }
                for (int i = 0; i < 3 && myhp > 0; i++) { //【変更】全魔導士について繰返す
                    myhp -= m[i].Fight(); //魔導士の攻撃!あなたのHPをマイナス
                }
            } else { // やめる?
                if (rnd.Next(2) == 0) { //確率50%で
                    Console.WriteLine("逃げることができた!");
                    break; // 繰り返し終了(p.125)
                } else {
                    Console.WriteLine("逃げられない!");
                    for (int i = 0; i < 3 && myhp > 0; i++) { //【変更】全魔導士について繰返す
                        myhp -= m[i].Fight(); //魔導士の攻撃!あなたのHPをマイナス
                    }
                }
            }
            if (myhp <= 0) { //あなたのHPがもうない?
                Console.WriteLine("あなたは死にました。");
                return; //【追加】ゲーム終了
            }
        }
        if (ans != "0") { //【以下追加】逃げたのでなければ
            Console.WriteLine("3人の魔導士を倒した!");
        }
    }
}

RPG演習6 「大魔導出現」仕様の検討

・大魔導はDaimadoクラス(Madoshiクラスの派生クラス)で実装しよう
・Fight()、Damage()メソッド、HPを返すプロパティは継承
・DispInfo()メソッドはオーバーライドして「大魔道(HP={0} MP={1})」表示にしよう
・データメンバはそのまま(魔導士番号は使わない)
・コンストラクタは引数不要でMPの初期値を40~49、HPの初期値を40~49にしよう(idは用いない)
・minimadouクラスでは「3人の魔導士を倒した!」の後に「大魔導が現れた!」に変更(つまり、逃げると大魔導)
・その後で「戦闘中(あなたが死ぬか,魔導士が死ぬまで繰り返す)」と同等の内容を「あなたか,大魔導が死ぬまで繰り返す」で
 行えば良い
・「どれを攻撃しますか?(1/2/3:魔導士1,2,3 0:やめる)」を「攻撃しますか?(1:する 0:やめる)」にしよう
・「整数変換して-1し魔導士の添字0~2を得る」は不要
・「魔導士を攻撃?」は「1ならば」でOK
・「活きている魔導士?」チェックは不要
・「魔導士{0}を倒した!」は「大魔導を倒した!」にして、returnしよう(Mainメソッドから抜ける=終了)
・「魔導士{0}はもういない!」は不要
・「全魔導士について繰返す」必要はない
・「逃げられない」のあとも、「全魔導士について繰返す」必要はない
・「3人の魔導士を倒した!」は不要
・大魔導との戦闘開始前にプレイヤーのHPを40~49に回復する(現HPより上回る場合のみ)

作成例

//オブジェクト指向演習 RPG演習6
using System;
class Madoshi { //魔導士を表すクラス
    protected int mp; //【変更】MP(カプセル化(p.166)のためにpublicにしない)
    protected int hp; //【変更】HP(〃)
    int id; //魔導士番号
    protected static Random rnd = new Random(); //【変更】乱数用のRandomクラスのインスタンスを生成
    public Madoshi() { } //【追加】デフォルトコンストラクタ(継承用)
    public Madoshi(int id) { //コンストラクタ(p.167)で魔導士番号を受け取る
        mp = rnd.Next(10); //0~9の間のランダムな整数を得てMPの初期値とする
        hp = 10 + rnd.Next(10); //10~19の間のランダムな整数を得てHPの初期値とする
        this.id = id; //引数から魔導士番号を受け取る
    }
    public int HP { //HPを返すプロパティ
        get { return hp; } 
    }
    public virtual void DispInfo() { //【変更】魔導士の情報を表示する
        Console.Write("魔導士{0}(HP={1} MP={2})", id, hp, mp); //情報表示(改行しない)
    }
    public int Fight() { //魔導士があなたを攻撃し、あなたのダメージ値を返す
        if (hp <= 0) return 0; //死んでいる場合は0を返す
        if (rnd.Next(2) == 1) { //確率1/2で魔法攻撃かどうかを選ぶ
            int j = rnd.Next(5) + 1; //消費MPは1~5の乱数
            DispInfo(); // 魔導士の情報を表示する
            Console.WriteLine("は消費MP" + j + "の魔法を唱えた!");
            if (mp < j) { // MP不足?
                Console.WriteLine("MPが足りない!");
                return 0; // あなたのダメージ=0を返す(攻撃終了)
            } else { // MP充足?
                Console.WriteLine("あなたは" + j * 4 + "のダメージを受けた!");
                mp -= j; //MP消費
                return j * 4; //あなたのダメージ=消費MPの4倍を返す(攻撃終了)
            }
        } else { //通常攻撃?
            int k = rnd.Next(5) + 1; //攻撃力は1~5の乱数
            DispInfo(); //魔導士の情報を表示する
            Console.WriteLine("の攻撃!");
            Console.WriteLine("あなたは" + k + "のダメージを受けた!");
            return k; //あなたのダメージ=1~50を返す(攻撃終了)
        }
    }
    public void Damage() { //魔導士があなたからダメージをくらう
        int k = 5 + rnd.Next(5); //あなたの攻撃力は5~9の乱数
        Console.WriteLine("あなたの攻撃!");
        DispInfo(); //魔導士の情報を表示する(攻撃を受けた後の魔導士のHPを表示)
        Console.WriteLine("に" + k + "のダメージを与えた!");
        hp -= k; //魔導士のHPをダウン
    }
}
class Daimado : Madoshi { //【以下追加】大魔導クラス(魔導士クラスの派生クラス)
    public Daimado() { //コンストラクタ
        mp = 40 + rnd.Next(10); //40~49の間のランダムな整数を得てMPの初期値とする
        hp = 40 + rnd.Next(10); //40~49の間のランダムな整数を得てHPの初期値とする
    }
    public override void DispInfo() { //大魔導の情報を表示する
        Console.Write("大魔導(HP={0} MP={1})", hp, mp); //情報表示(改行しない)
    }
}
class minimadou { //ゲーム本体のクラス
    public static void Main() { //ゲームを進行するメソッド
        Random rnd = new Random(); //乱数用のRandomクラスのインスタンスを生成
        string ans = null; //入力用
        // 戦闘開始
        int myhp = 40 + rnd.Next(21); //あなたのHPを40+0から40+20にする
        Madoshi[] m = { new Madoshi(1),new Madoshi(2),new Madoshi(3) }; //全魔導士を生成
        foreach (var w in m) { //全魔導士ついて繰返す
            w.DispInfo(); //魔導士の情報を表示する
            Console.WriteLine("が現れた。");
        }
        // 戦闘中(あなたが死ぬか,魔導士が死ぬまで繰り返す)
        while (myhp > 0 && (m[0].HP > 0 || m[1].HP > 0 || m[2].HP > 0)) { //あなたとどれかの魔導士のHPがある間
            Console.Write("残りHPは{0}です。どれを攻撃しますか?(1/2/3:魔導士1,2,3 0:やめる):", myhp); 
            ans = Console.ReadLine(); //回答を得る
            int ansi = int.Parse(ans) - 1; //整数変換して-1し魔導士の添字0~2を得る
            if (ansi == 0 || ansi == 1 || ansi == 2) { //魔導士を攻撃?
                if (m[ansi].HP > 0) { //活きている魔導士?
                    m[ansi].Damage(); //魔導士を攻撃する
                    if(m[ansi].HP <= 0) { //魔導士[]を倒した?
                        Console.WriteLine("魔導士{0}を倒した!", ans);
                    }
                } else { 
                    Console.WriteLine("魔導士{0}はもういない!", ans);
                }
                for (int i = 0; i < 3 && myhp > 0; i++) { //全魔導士について繰返す
                    myhp -= m[i].Fight(); //魔導士の攻撃!あなたのHPをマイナス
                }
            } else { // やめる?
                if (rnd.Next(2) == 0) { //確率50%で
                    Console.WriteLine("逃げることができた!");
                    break; // 繰り返し終了(p.125)
                } else {
                    Console.WriteLine("逃げられない!");
                    for (int i = 0; i < 3 && myhp > 0; i++) { //全魔導士について繰返す
                        myhp -= m[i].Fight(); //魔導士の攻撃!あなたのHPをマイナス
                    }
                }
            }
            if (myhp <= 0) { //あなたのHPがもうない?
                Console.WriteLine("あなたは死にました。");
                return; //ゲーム終了
            }
        }
        if (ans != "0") { //逃げたのでなければ
            Console.WriteLine("3人の魔導士を倒した!");
        }
        //【以下追加】ボス戦開始
        Daimado d = new Daimado(); //大魔導を生成
        d.DispInfo(); //大魔導の情報を表示する
        Console.WriteLine("が現れた。");
        int newhp = 40 + rnd.Next(10); //新しいHPを40から49で決める
        if (myhp < newhp) { //回復する?
            myhp = newhp; //HPを回復
            Console.WriteLine("HPを回復!");
        }
        // 戦闘中(あなたが死ぬか,大魔導が死ぬまで繰り返す)
        while (myhp > 0 && d.HP > 0) { //あなたと大魔導のHPがある間
            Console.Write("残りHPは{0}です。攻撃しますか?(1:攻撃する 0:やめる):", myhp); 
            ans = Console.ReadLine(); //回答を得る
            if (ans == "1") { //大魔導を攻撃?
                d.Damage(); //大魔導を攻撃する
                if(d.HP <= 0) { //大魔導を倒した?
                    Console.WriteLine("大魔導を倒した!");
                    break; //ゲーム終了
                }
                myhp -= d.Fight(); //大魔導の攻撃!あなたのHPをマイナス
            } else { // やめる?
                if (rnd.Next(2) == 0) { //確率50%で
                    Console.WriteLine("逃げることができた!");
                    break; //ゲーム終了
                } else {
                    Console.WriteLine("逃げられない!");
                    myhp -= d.Fight(); //大魔導の攻撃!あなたのHPをマイナス
                }
            }
            if (myhp <= 0) { //あなたのHPがもうない?
                Console.WriteLine("あなたは死にました。");
                break; //ゲーム終了
            }
        }
    }
}

提出:「3人の魔導士・大魔道出現」

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です