【勉強日記】クラスを使ってRPGを作ろう④【第20回】

プログラミング

はじめに

今回の記事では、クラスを使って作成したRPGプログラムを実際に動かし、おさらいをしていきます。解説だけでなく作成したコードを掲載し、動かしている部分も確認できるようになっています。これまでのおさらいに役立てていただけると嬉しいです。

もくじ

  • はじめに
  • 作ったRPGプログラムを見てみよう
  • 実際に遊んでみよう!
  • 作り方のおさらいとまとめ
    • 仕様をきめる
    • 大まかな流れをつくる
    • クラスをつくる
    • メインプログラムに組み込む
  • おまけ 作ったプログラムを改良してみよう
  • おしらせ

作ったRPGプログラムを見てみよう

今回のブログでは、作ったRPGプログラムを実際に動かして遊んでみます。

動かしながら、作成の振り返りを行っていきます。作成したプログラムは以下になります。

import random


class Player():  # プレイヤークラス

    def __init__(self, name):
        self.name = name
        self.HP = 60
        self.is_defenced = False

    def attack(self):
        self.is_defenced = False
        self.damage = 10

        return self.damage

    def defence(self, player_HP):
        self.is_defenced = True
        self.HP = player_HP

        return self.HP


class Caster(Player):  # 魔法使いクラス

    def attack(self):
        self.damage = 10
        print(f'{self.name}は魔法をくりだした!')  # 攻撃を魔法攻撃にオーバーライド
        self.is_defenced = False
        self.probability = random.random()

        if self.probability >= 0.8:  # 20%の確率で攻撃が外れる
            print('攻撃が外れてしまった!')
            self.damage = 0
            return self.damage

        else:

            return self.damage

    def defence(self, player_HP):
        self.is_defenced = True
        self.HP = player_HP + 5 # 魔法使いは防御ごとにHPが+5するのでオーバーライド

        return self.HP


class Knight(Player):  # 騎士クラス

    def attack(self):
        self.damage = 10
        print(f'{self.name}は斬撃をくりだした!')  # 攻撃を斬撃攻撃にオーバーライド
        self.is_defenced = False
        self.probability = random.random()

        if self.probability >= 0.8:  # 20%の確率で急所、20%の確率で攻撃が外れる
            print('急所に当たった!')
            self.damage = self.damage + 10

            return self.damage

        elif 0.8 > self.probability > 0.2:

            return self.damage

        else:
            print('攻撃が外れてしまった!')
            self.damage = 0

            return self.damage


class Enemy():  # エネミークラス

    def __init__(self):
        enemy_type = {'スライム': 20, 'デビル': 30, 'ドラゴン': 60}
        self.monster = random.choice(list(enemy_type.items()))

    def attack(self):
        enemy_attack_damage = [0, 10, 20, 30]
        self.probability = random.random()
        monster_name = self.monster[0]

        if self.probability > 0.9:
            print(f'{monster_name}の攻撃が急所に当たった!')
            self.damage = enemy_attack_damage[3]

            return self.damage

        elif 0.9 >= self.probability > 0.7:
            self.damage = enemy_attack_damage[2]

            return self.damage

        elif 0.7 >= self.probability > 0.2:
            self.damage = enemy_attack_damage[1]

            return self.damage

        else:
            self.damage = enemy_attack_damage[0]
            print(f'{monster_name}の攻撃は外れた!')

            return self.damage


def input_name():
    player_name = input("あなたの名前を教えてください :")

    if player_name == '':  # 入力がない場合NGにする
        print("")
        print("正しく名前を入力してください")
        print("")
        return False

    elif len(player_name) > 20:  # 20文字以上の場合NGにする
        print("")
        print("名前が長すぎます")
        print("")
        return False

    else:
        return player_name


def input_job():
    player_job = input("あなたの職業を教えてください 1: 魔法使い 2: 騎士 :")

    if player_job == '': # 入力がない場合NGにする
        print("")
        print("職業を入力してください")
        print("")
        return False

    elif player_job == str(1) or str(2):
        return player_job

    else:
        print("正しく職業を入力してください") # 1,2以外が入力された場合NGにする
        return False


def main():
    # ゲームスタート
    # 主人公か敵のどちらかのHPが0になったら終了
    print("")
    print("「これは勇者様!モンスターが現れて大変困っているのです。」")

    input_check = False # チェックがTrueになったらループを抜けて次に進む

    while input_check is False:
        print("")
        name = input_name()
        if name is not False:
            job = input_job()
            if job is not False:
                input_check = True

    if job == str(1):  # 魔法使いクラスの場合 魔法使いインスタンスを生成
        caster = Caster(name)
        print("")
        print("「あなたは魔法使いなのですね。 是非私のお力になってください!」")
        print("")

        # モンスターが現れたのでインスタンスを生成
        enemy = Enemy()
        monster = enemy.monster[0]
        print(f"{monster}があらわれた!")
        enemy_HP = int(enemy.monster[1])
        player_HP = int(caster.HP)

        while True:

            if player_HP <= 0 or enemy_HP <= 0:
                if player_HP <= 0:
                    print(f"{caster.name}は{monster}に負けてしまった・・・")
                elif enemy_HP <= 0:
                    print(f"{monster}を倒した!おめでとう、{caster.name}!")

                break

            print(f"{caster.name}のHP:{player_HP}")
            print(f"{monster}のHP:{enemy_HP}")

            # プレイヤーのターン
            print("")
            caster_attack = input("あなたの行動を選んでください 1:攻撃 2:防御")

            if caster_attack == str(1):  # 攻撃を選んだ場合

                print("")
                print(f"{caster.name}の攻撃!")

                monster_damage = caster.attack()
                print(f"{monster}に{monster_damage}のダメージ!")
                enemy_HP = enemy_HP-monster_damage

                print(f"{caster.name}のHP:{player_HP}")
                print(f"{monster}のHP:{enemy_HP}")
                print("")

                if enemy_HP <= 0:
                    print(f"{monster}を倒した!おめでとう、{caster.name}!")
                    break

            elif caster_attack == str(2):  # 防御を選んだ場合5回復する

                print(f"{caster.name}は防御した!")
                player_HP = caster.defence(player_HP)

            else:
                continue

            # モンスターのターン

            print(f"{monster}の攻撃!")

            if caster.is_defenced is True:
                print(f"{caster.name}は防御している!")

            elif caster.is_defenced is False:
                player_damage = enemy.attack()
                print(f"{caster.name}に{player_damage}のダメージ!")
                player_HP = player_HP - player_damage

    elif job == str(2):  # 騎士クラスの場合 騎士インスタンスを作成
        knight = Knight(name)

        print("")
        print("「あなたは騎士なのですね。 是非私のお力になってください!」")
        print("")

        # モンスターが現れたのでインスタンスを生成
        enemy = Enemy()
        monster = enemy.monster[0]
        print(f"{monster}があらわれた!")
        enemy_HP = int(enemy.monster[1])
        player_HP = int(knight.HP)

        while True:

            if player_HP <= 0 or enemy_HP <= 0:
                if player_HP <= 0:
                    print(f"{knight.name}は{monster}に負けてしまった・・・")
                elif enemy_HP <= 0:
                    print(f"{monster}を倒した!おめでとう、{knight.name}!")

                break

            print(f"{knight.name}のHP:{player_HP}")
            print(f"{monster}のHP:{enemy_HP}")

            # プレイヤーのターン
            print("")
            night_attack = input("あなたの行動を選んでください 1:攻撃 2:防御")

            if night_attack == str(1):  # 攻撃を選んだ場合

                print("")
                print(f"{knight.name}の攻撃!")

                monster_damage = knight.attack()
                print(f"{monster}に{monster_damage}のダメージ!")
                enemy_HP = enemy_HP-monster_damage

                print(f"{knight.name}のHP:{player_HP}")
                print(f"{monster}のHP:{enemy_HP}")
                print("")

                if enemy_HP <= 0:
                    print(f"{monster}を倒した!おめでとう、{knight.name}!")
                    break

            elif night_attack == str(2):  # 防御を選んだ場合

                print(f"{knight.name}は防御した!")
                player_HP = knight.defence(player_HP)
                print("")

            else:
                continue

            # モンスターのターン

            print(f"{monster}の攻撃!")

            if knight.is_defenced is True:
                print(f"{knight.name}は防御している!")

            elif knight.is_defenced is False:
                player_damage = enemy.attack()
                print(f"{knight.name}に{player_damage}のダメージ!")
                player_HP = player_HP - player_damage


if __name__ == "__main__":

    main()

実際にRPGで遊んでみよう!

それでは実際にRPGプログラムを実行して遊んでみましょう!

まずはプログラムが書かれたpythonのファイルを実行します(vscodeなら右上の再生ボタンで実行できます)。すると、名前の入力画面が表示されます。

まずは名前を入力して、魔法使いを選択してみましょう。

選択すると、モンスターの種類とHP、プレイヤーの体力が表示されました!さっそく行動に移していきます。さっそく攻撃を選んでみます。

こちらの攻撃は当たったようです!スライムからは20ダメージを受けて、HPが40になってしまいました。つぎに、防御を選択してみます。

防御すると、魔法使いなのでHPが40から45に増えました。次の攻撃でスライムが倒せるので、攻撃を選んでみます。

攻撃が外れてしまいました・・・このように運要素が入るのはバトルゲームの面白いところです。次こそ倒すために攻撃してみます。

攻撃が当たり、スライムを倒すことができました!倒したところで、プログラムがしっかり終了しています。

今回は魔法使いで遊んでみましたが、騎士を選ぶと回復なしのバトルでより緊迫感のあるゲームになります。自分の作ったプログラムでたくさん遊んでみましょう!

作り方のおさらい&まとめ

実際にプログラムを動かして遊んでみたところで、RPG作成の振り返りをしていきましょう。今回のクラスを用いたプログラム作成の手順は以下になります。

  1. 仕様を決める
  2. 大まかな流れをつくる
  3. クラスをつくる
  4. メインプログラムに組み込む

①作りたいRPGの仕様を決める

まずは仕様をざっくり決めていきます。何ができるか?どんなステータスをもつか?など、いったんはプログラムの処理として考えるのではなく、実際にプレイする場面を想像して考えていきます。断片でもいいので、部分的な仕様を挙げていきます。

②大まかな流れをつくる

仕様を決めたら、それを実際のプレイ順に並べていきます。 RPGゲームなら「このターン攻撃したあとは~」など流れを意識してフロー図に起こしていきます。

③クラスをつくる

大まかな流れができたら、クラスを作成していきます。 今回はキャラクターをクラスにまとめましたが、まとめた方が便利そうな値や処理がある場合はクラスにできないか考えることで、後の処理が簡単になる場合があります。 クラスの機能を考えたら、実際にプログラムとして作りこんでいきます。

④メインプログラムに組み込む

クラスが完成したら、クラスをメインプログラムに組み込んで各メソッドを呼び出していきます。メインプログラムでは、作成してあるフロー図に沿って細かい処理を実装していきます。実装する段階で、必要になった関数などがあればその都度作成していきます。

おまけ 作ったプログラムを改良してみよう

RPGプログラムを作成しましたが、今回完成したコードが正解ということはありません。

例えばクラスを作成するときに、今回はプレイヤークラスを継承して魔法使いクラス、騎士クラスの2つを作成しました。このとき、キャラクタークラスを継承して魔法使いクラス・騎士クラス・エネミークラス3つすべてを作成することも可能です。

作成したプログラムを「ここをもう少し簡単にできないか?」「同じ処理を省けないか?」など、改良していくことできれいでわかりやすいコードを作成できるようになります

仕様面でも、例えば今回のキャラクターのステータスに「すばやさ」を追加して、すばやさが早い方からターンを開始する仕様に変更したりすると改良のしがいがあるかもしれません。

おしらせ

今回でクラスを用いたプログラムの演習、およびpythonを用いたプログラミングの基本の解説は終了になります。20回にわたり掲載してきましたが、著者もプログラムについて振り返りながら執筆していくことでとても学びがありました。

次回からの内容は未定ですが、これからも初心者にわかりやすい記事を目指していこうと思います。

ここまで読んでくださってありがとうございました!

コメント

タイトルとURLをコピーしました