0コメント

Python初心者の第一歩:簡単RPGゲームで学ぶクラスとループ


Python初心者向け:テキストベースRPGゲームで学ぶプログラミング基礎


この記事では、シンプルなテキストベースのRPGゲームを通じて、Pythonの基本を学びます。このゲームでは、プレイヤーが敵(スライム)と戦い、ターン制で攻撃や逃げる行動を選択します。コードを一行ずつ解説し、クラスループ条件分岐乱数生成ユーザー入力などの概念を学びます。初心者でも理解しやすいように、コードの各行の役割を詳しく説明します。



ゲームの概要と学べること



    • 目的: プレイヤーが敵と戦い、勝利または敗北するまでターン制で進行。

    • 機能:

        • プレイヤーと敵にHP(ヒットポイント)を設定。

        • プレイヤーは「攻撃」または「逃げる」を選択。

        • 攻撃はランダムなダメージを与える。

        • 敵もランダムなダメージで反撃。

        • HPが0以下でゲーム終了。



    • 学べるPythonの概念:

        • クラスとオブジェクト(オブジェクト指向プログラミング)

        • ループ(while文)

        • 条件分岐(if文)

        • 乱数生成(randomモジュール)

        • ユーザー入力(input関数)





コード全体


以下がゲームの全コードです。次に、各行を詳しく解説します。


import random


class Character:

    def __init__(self, name, hp, attack_min, attack_max):

        self.name = name

        self.hp = hp

        self.attack_min = attack_min

        self.attack_max = attack_max


    def attack(self, target):

        damage = random.randint(self.attack_min, self.attack_max)

        target.hp -= damage

        print(f"{self.name}が{target.name}に{damage}のダメージを与えた!")

        if target.hp < 0:

            target.hp = 0


    def is_alive(self):

        return self.hp > 0


def main():

    player = Character("勇者", 100, 10, 20)

    enemy = Character("スライム", 50, 5, 15)


    print("戦闘開始!")

    print(f"{player.name}: HP {player.hp}")

    print(f"{enemy.name}: HP {enemy.hp}")


    while player.is_alive() and enemy.is_alive():

        print("\n=== ターン開始 ===")

        print(f"{player.name}のHP: {player.hp}")

        print(f"{enemy.name}のHP: {enemy.hp}")


        action = input("行動を選択してください (1: 攻撃, 2: 逃げる): ")


        if action == "1":

            player.attack(enemy)

            if not enemy.is_alive():

                print(f"{enemy.name}を倒した!")

                break

        elif action == "2":

            print(f"{player.name}は逃げ出した!")

            break

        else:

            print("無効な入力です。1または2を選択してください。")

            continue


        if enemy.is_alive():

            enemy.attack(player)

            if not player.is_alive():

                print(f"{player.name}は倒れた...")

                break


    if player.is_alive() and not enemy.is_alive():

        print("勝利!おめでとう!")

    elif not player.is_alive():

        print("ゲームオーバー...")

    else:

        print("戦闘終了。")


if __name__ == "__main__":

    main()



コードの行ごとの解説:Pythonの基礎を学ぼう


1. import random


Pythonのrandomモジュールをインポートします。このモジュールは乱数を生成する機能を提供し、攻撃のダメージをランダムにするために使います。


学習ポイント: モジュールはPythonに追加の機能を提供する「道具箱」。randomはゲームにランダム性を持たせる重要なツールです。



2. class Character:


キャラクター(プレイヤーや敵)の「設計図」となるCharacterクラスを定義します。クラスは、名前やHPなどの属性や、攻撃などの動作をまとめます。


学習ポイント: クラスはオブジェクト指向プログラミングの基本。オブジェクト(例: 勇者、スライム)はこの設計図から作られます。



3. def __init__(self, name, hp, attack_min, attack_max):


クラスのコンストラクタ(初期化メソッド)。キャラクターを作成する際に、名前、HP、攻撃力の範囲を設定します。


学習ポイント: __init__はキャラクター作成時に自動で呼ばれる。selfはそのキャラクター自身を指します。



4. self.name = name


キャラクターの名前を引数nameから受け取り、self.nameに保存します(例: 「勇者」)。


学習ポイント: self.nameはキャラクターごとの名前を保持する変数。クラス内でデータを管理する方法を学びます。



5. self.hp = hp


キャラクターのHP(ヒットポイント)を引数hpから受け取り、self.hpに保存します。


学習ポイント: HPは戦闘で減る数値。ゲームの進行に重要なデータです。



6. self.attack_min = attack_min


攻撃力の最小値を引数attack_minから受け取り、self.attack_minに保存します。


学習ポイント: 攻撃力の範囲を設定し、ランダムなダメージ計算に備えます。



7. self.attack_max = attack_max


攻撃力の最大値を引数attack_maxから受け取り、self.attack_maxに保存します。


学習ポイント: 最小値と最大値で攻撃のランダム性を制御します。



8. def attack(self, target):


キャラクターが攻撃するメソッド。攻撃対象(target)を受け取ります。


学習ポイント: メソッドはクラス内の関数。攻撃ロジックをここで定義します。



9. damage = random.randint(self.attack_min, self.attack_max)


random.randint(a, b)で攻撃力の範囲からランダムなダメージを生成し、damageに保存します。


学習ポイント: randomモジュールでゲームにランダム性を持たせます。例: 勇者の攻撃は10~20のダメージ。



10. target.hp -= damage


攻撃対象のHPからダメージ分を減らします。


学習ポイント: -=は「その値を減らす」演算子。例: HPが50でダメージが15なら35に。



11. print(f"{self.name}が{target.name}に{damage}のダメージを与えた!")


攻撃結果を表示(例: 「勇者がスライムに15のダメージを与えた!」)。


学習ポイント: f文字列(f-string)は変数を文字列に埋め込む便利な方法。ユーザーに状況を伝えます。



12. if target.hp < 0:


攻撃対象のHPが0未満かチェックします。


学習ポイント: HPがマイナスになるのは不自然なので、次の行で修正します。条件分岐の基本。



13. target.hp = 0


HPが0未満なら0に設定します。


学習ポイント: ゲームらしい表示にするため、HPは0で止まります。



14. def is_alive(self):


キャラクターが生きているか(HP > 0)を判定するメソッドを定義します。


学習ポイント: メソッドは特定の役割(生死判定)を持ち、コードを整理します。



15. return self.hp > 0


HPが0より大きければTrue、そうでなければFalseを返します。


学習ポイント: returnで結果を返す。戦闘ループの継続判定に使います。



16. def main():


ゲームのメイン処理をまとめた関数を定義します。


学習ポイント: 関数でコードを整理し、プログラムの流れを管理します。



17. player = Character("勇者", 100, 10, 20)


プレイヤー(勇者)を作成。名前「勇者」、HP100、攻撃力10~20。


学習ポイント: クラスから具体的なオブジェクト(勇者)を作成します。



18. enemy = Character("スライム", 50, 5, 15)


敵(スライム)を作成。名前「スライム」、HP50、攻撃力5~15。


学習ポイント: 同じクラスで異なるステータスのキャラクターを作れます。



19. print("戦闘開始!")


ゲーム開始のメッセージを表示します。


学習ポイント: print()でユーザーに状況を伝えます。



20. print(f"{player.name}: HP {player.hp}")


プレイヤーの名前とHPを表示(例: 「勇者: HP 100」)。


学習ポイント: f文字列でキャラクターの状態をわかりやすく表示。



21. print(f"{enemy.name}: HP {enemy.hp}")


敵の名前とHPを表示(例: 「スライム: HP 50」)。


学習ポイント: 初期状態をユーザーに伝える。



22. while player.is_alive() and enemy.is_alive():


プレイヤーと敵が両方生きている間、戦闘ループを続けます。


学習ポイント: whileループで条件がTrueの間繰り返します。andは「両方」の意味。



23. print("\n=== ターン開始 ===")


新しいターンの開始を示します。\nは改行。


学習ポイント: 改行と区切り線でゲームの進行を視覚的に整理。



24. print(f"{player.name}のHP: {player.hp}")


ターン開始時にプレイヤーのHPを表示。


学習ポイント: 毎ターン状態を確認できるようにします。



25. print(f"{enemy.name}のHP: {enemy.hp}")


ターン開始時に敵のHPを表示。


学習ポイント: 敵の状態も毎ターン確認可能。



26. action = input("行動を選択してください (1: 攻撃, 2: 逃げる): ")


プレイヤーに行動(1: 攻撃、2: 逃げる)を入力させ、actionに保存。


学習ポイント: input()でユーザーからの入力を受け取ります。入力は文字列です。



27. if action == "1":


入力が「1」(攻撃)だった場合の処理を開始。


学習ポイント: ifで条件分岐。==で入力が「1」かチェック。



28. player.attack(enemy)


プレイヤーが敵を攻撃します。


学習ポイント: クラスのメソッドを呼び出し、勇者がスライムにダメージを与えます。



29. if not enemy.is_alive():


敵が死んでいるか(HP <= 0)チェック。


学習ポイント: notで「~でない」を判定。敵が死んだら戦闘終了。



30. print(f"{enemy.name}を倒した!")


敵が死んだ場合、「スライムを倒した!」と表示。


学習ポイント: 勝利をユーザーに伝えます。



31. break


戦闘ループを終了。


学習ポイント: breakwhileループを強制終了。敵が死んだので戦闘終了。



32. elif action == "2":


入力が「2」(逃げる)だった場合の処理。


学習ポイント: elifは「else if」で、別の条件をチェック。



33. print(f"{player.name}は逃げ出した!")


プレイヤーが逃げたことを表示。


学習ポイント: 逃げるを選択したら戦闘終了。



34. break


逃げたので戦闘ループを終了。


学習ポイント: breakでループを抜け、ゲーム終了へ。



35. else:


入力が「1」でも「2」でもない場合(無効な入力)の処理。


学習ポイント: 無効な入力を処理して、ユーザーに再入力を促します。



36. print("無効な入力です。1または2を選択してください。")


無効な入力であることを表示。


学習ポイント: エラーメッセージでユーザーに正しい入力を促します。



37. continue


ループの先頭に戻り、次のターンへ。


学習ポイント: continueは現在のループをスキップして次の繰り返しへ。



38. if enemy.is_alive():


敵が生きているかチェック。生きていれば敵の攻撃ターン。


学習ポイント: 敵が死んでいる場合は攻撃させないための条件。



39. enemy.attack(player)


敵がプレイヤーを攻撃。


学習ポイント: スライムが勇者にランダムなダメージを与えます。



40. if not player.is_alive():


プレイヤーが死んでいるか(HP <= 0)チェック。


学習ポイント: プレイヤーが死んだらゲームオーバー。



41. print(f"{player.name}は倒れた...")


プレイヤーが死んだことを表示。


学習ポイント: ゲームオーバーのメッセージ。



42. break


プレイヤーが死んだので戦闘ループを終了。


学習ポイント: ループを抜けてゲーム終了へ。



43. if player.is_alive() and not enemy.is_alive():


戦闘終了後、プレイヤーが生きていて敵が死んでいる(勝利)かチェック。


学習ポイント: 勝利条件を判定。複数の条件を組み合わせます。



44. print("勝利!おめでとう!")


勝利メッセージを表示。


学習ポイント: プレイヤーにゲームクリアを伝えます。



45. elif not player.is_alive():


プレイヤーが死んでいる場合(ゲームオーバー)をチェック。


学習ポイント: 敗北条件の判定。



46. print("ゲームオーバー...")


ゲームオーバーメッセージを表示。


学習ポイント: プレイヤーに敗北を伝えます。



47. else:


勝利でも敗北でもない場合(例: 逃げた場合)の処理。


学習ポイント: その他の終了条件を処理。



48. print("戦闘終了。")


戦闘が終了したことを表示。


学習ポイント: 逃げた場合などの終了メッセージ。



49. if __name__ == "__main__":


プログラムが直接実行された場合にのみmain()を呼び出します。


学習ポイント: Pythonの標準的な書き方。コードが他のファイルからインポートされた場合にmain()が自動実行されないようにします。



50. main()


main()関数を呼び出してゲームを開始。


学習ポイント: ここでゲームの実行が始まります。



学んだことのまとめ



    • クラスとオブジェクト: Characterクラスでキャラクターの設計図を作り、勇者やスライムを作成。

    • ループ: whileで戦闘を繰り返し、ゲームの進行を管理。

    • 条件分岐: ifelifelseで行動や勝敗を処理。

    • 乱数生成: random.randint()で攻撃ダメージにランダム性を持たせる。

    • ユーザー入力: input()でプレイヤーの選択を受け取る。



次のステップ:ゲームをカスタマイズしよう


このコードを動かして理解したら、以下のアイデアでさらに学びを深めましょう:



    • エラー処理: try-exceptで数字以外の入力(例: "abc")を防ぐ。

    • 機能追加: 回復アイテムや複数の敵を追加。

    • デバッグ: print()で変数の値を確認しながらコードの動きを追う。

    • GUI化: tkinterでグラフィカルなインターフェースを追加。


このプロジェクトは、Pythonの基本を楽しく学びながら、プログラミングの思考を養うのに最適です。コードをコピーして動かしてみて、質問があればぜひ挑戦してみてください!




この記事へのコメント