【Python】レッスン5-☆1:モンスター捕獲ゲームを作ろう

記事内に商品プロモーションを含む場合があります

この記事の練習問題で使用する知識:
レッスン1~2の知識関数の定義と使用戻り値とデフォルト引数リストの定義と要素追加クラスの定義と使用__init__メソッドメソッドの定義と使用

Pythonのゲームコード一覧はこちら

<<前の問題 問題集Top 次の問題>>

練習問題5-☆1:モンスター捕獲ゲームを作ろう

モンスター捕獲ゲームを作成しましょう。

プレイヤーはスライム、ゴブリン、ドラゴンの3種類のモンスターに挑みます。

それぞれのモンスターとサイコロを使って勝負し、プレイヤーのサイコロの出目がモンスターの出目より大きければ捕獲に成功します。

モンスターを一匹でも多く捕まえることを目指し、捕まえたモンスターのリストを最後に表示してください。

この問題の要件

以下の要件に従ってコードを完成させてください。

  • 3匹のモンスター(スライム、ゴブリン、ドラゴン)が登場すること。
  • モンスターとプレイヤーがサイコロを振り、ランダムな1から6の数字を生成すること。
  • プレイヤーがサイコロを振るかどうか選択できるようにすること(yesnoで入力を受け付ける)。
  • モンスターの出目よりプレイヤーの出目が大きければ捕獲成功、小さければ失敗し、その時点でゲーム終了とすること。
  • 捕獲に成功したモンスターをリストで管理し、最後に捕まえたモンスターを一覧で表示すること。

ただし、以下のような実行結果となるコードを書くこと。

*****↓↓正解コードの実行結果の例↓↓*****

スライムが現れた!
スライムがサイコロを振った。出目は 3
サイコロを振りますか? (yes/no): yes
プレイヤーがサイコロを振った。出目は 5
スライムを捕まえた!
ゴブリンが現れた!
ゴブリンがサイコロを振った。出目は 4
サイコロを振りますか? (yes/no): yes
プレイヤーがサイコロを振った。出目は 2
ゴブリンを捕まえられなかった。ゲームオーバー!

この問題を解くヒント

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)

1:randomモジュールのインポート

2:Monsterクラスの定義
□ __init__メソッドにて、モンスター名を受け取り、インスタンス変数nameに格納
□ get_nameメソッドを定義し、モンスターの名前を返す
□ dice_rollメソッドを定義し、1から6のランダムな整数を返す

3:monster_capture_game関数の定義
□ モンスター(スライム、ゴブリン、ドラゴン)のリストを作成
□ 捕獲したモンスターの名前を格納するリストcaptured_monstersを作成
□ for文でモンスターリストをループ処理
□ □ printでモンスター名を表示
□ □ capturedフラグをFalseに設定
□ □ while not capturedで捕獲されるまでループ
□ □ □ モンスターのサイコロの出目を生成するためにmonster.dice_rollを呼び出し、monster_rollに格納
□ □ □ printでモンスターの出目を表示
□ □ □ input関数でプレイヤーにサイコロを振るか確認し、入力をresponseに格納
□ □ □ if response == "no"でサイコロを振らない場合、breakでループを終了
□ □ □ プレイヤーがサイコロを振る場合
□ □ □ □ プレイヤーのサイコロを振るためにmonster.dice_rollを呼び出し、player_rollに格納
□ □ □ □ printでプレイヤーの出目を表示
□ □ □ プレイヤーの出目とモンスターの出目を比較
□ □ □ □ if player_roll > monster_rollでプレイヤーが勝った場合、モンスターを捕獲し、captured_monstersリストに追加
□ □ □ □ 捕獲成功時にcapturedTrueに設定し、ループを終了
□ □ □ □ elif player_roll == monster_rollで引き分け時に「引き分けでもう一度!」と表示し、ループを繰り返す
□ □ □ □ elseでゲームオーバーを表示し、returnで関数を終了
□ ループ終了後、捕まえたモンスターリストを表示
□ printでゲーム終了メッセージを表示

4:if __name__ == "__main__":によりプログラムを実行
□ monster_capture_game()関数を呼び出し、ゲームを開始

ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

import random

# モンスタークラス
class Monster:
    def __init__(self, name):
        """【穴埋め問題1】ここにモンスターの名前をself.nameに設定するコードを書いてください。"""

    # モンスターの名前を取得
    def get_name(self):
        """【穴埋め問題2】ここにモンスターの名前を返すコードを書いてください。"""

    # サイコロを振る(1~6のランダムな数字を返す)
    def dice_roll(self):
        """【穴埋め問題3】ここに1から6までのランダムな数値を返すコードを書いてください。"""

# モンスター捕獲ゲーム関数
def monster_capture_game():
    """【穴埋め問題4】ここにモンスターのリストを作成するコードを書いてください。"""
    captured_monsters = []

    # 各モンスターとの対決
    for monster in monsters:
        print(f"{monster.get_name()}が現れた!")
        captured = False

        while not captured:
            """【穴埋め問題5】ここにモンスターがサイコロを振って出目を表示するコードを書いてください。"""

            # プレイヤーにサイコロを振るか選ばせる
            response = input("サイコロを振りますか? (yes/no): ").strip().lower()

            if response == "no":
                break

            """【穴埋め問題6】ここにプレイヤーがサイコロを振る処理を追加して、出目を表示するコードを書いてください。"""

            # プレイヤーの出目による判定
            """【穴埋め問題7】ここにプレイヤーとモンスターの出目を比較して、プレイヤーが勝った場合、引き分けの場合、負けた場合の処理を追加してください。"""

    # 捕まえたモンスターを表示
    """【穴埋め問題8】ここに捕まえたモンスターを表示し、ゲームを終了する処理を書いてください。"""

# ゲームを実行
if __name__ == "__main__":
    monster_capture_game()

以上がこの問題の穴埋めコードです。

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。

解答例と解説

この問題の一つの正解例とそのコードの解説を以下に示します。

正解コードの例

例えば以下のようなプログラムが考えられます。

import random

# モンスタークラス
class Monster:
    def __init__(self, name):
        self.name = name

    # モンスターの名前を取得
    def get_name(self):
        return self.name

    # サイコロを振る(1~6のランダムな数字を返す)
    def dice_roll(self):
        return random.randint(1, 6)

# モンスター捕獲ゲーム関数
def monster_capture_game():
    monsters = [Monster("スライム"), Monster("ゴブリン"), Monster("ドラゴン")]
    captured_monsters = []

    # 各モンスターとの対決
    for monster in monsters:
        print(f"{monster.get_name()}が現れた!")
        captured = False

        while not captured:
            monster_roll = monster.dice_roll()
            print(f"{monster.get_name()}がサイコロを振った。出目は {monster_roll}")

            # プレイヤーにサイコロを振るか選ばせる
            response = input("サイコロを振りますか? (yes/no): ").strip().lower()

            if response == "no":
                break

            player_roll = monster.dice_roll()
            print(f"プレイヤーがサイコロを振った。出目は {player_roll}")

            # プレイヤーの出目による判定
            if player_roll > monster_roll:
                print(f"{monster.get_name()}を捕まえた!")
                captured_monsters.append(monster.get_name())
                captured = True
            elif player_roll == monster_roll:
                print("引き分けでもう一度!")
            else:
                print(f"{monster.get_name()}を捕まえられなかった。ゲームオーバー!")
                return

    # 捕まえたモンスターを表示
    print("捕まえたモンスター: " + ", ".join(captured_monsters))
    print("ゲーム終了")

# ゲームを実行
if __name__ == "__main__":
    monster_capture_game()

正解コードの解説

このプログラムではモンスターを捕獲するゲームを作成しています。

各ブロックごとに説明していきます。

Monster クラスの定義

class Monster:
    def __init__(self, name):
        self.name = name

この部分はモンスターを表すクラスの定義です。

__init__ メソッドはクラスのコンストラクタで、モンスターの名前を設定します。モンスターの名前は self.name に格納されます。

get_name メソッド

def get_name(self):
    return self.name

このメソッドはモンスターの名前を取得するためのものです。

self.name をそのまま返すことで、モンスターの名前が外部から参照できるようになります。

dice_roll メソッド

def dice_roll(self):
    return random.randint(1, 6)

このメソッドはサイコロを振る機能を提供します。

random.randint(1, 6) によって、1から6までのランダムな数値を生成し、それを返します。モンスターとの対決に使われます。

monster_capture_game 関数

def monster_capture_game():
    monsters = [Monster("スライム"), Monster("ゴブリン"), Monster("ドラゴン")]
    captured_monsters = []

ここではモンスターのリストを作成し、ゲームのメインループを定義しています。

モンスターは「スライム」、「ゴブリン」、「ドラゴン」の3種類が登場します。

また捕まえたモンスターを記録するためのリスト captured_monsters も用意されています。

モンスターとの対決のループ

for monster in monsters:
    print(f"{monster.get_name()}が現れた!")
    captured = False

for ループを使用して順番にモンスターと対決していきます。

各モンスターが現れるたびに、プレイヤーがサイコロを振るか選択できる場面になります。

サイコロを振るロジック

monster_roll = monster.dice_roll()
print(f"{monster.get_name()}がサイコロを振った。出目は {monster_roll}")

response = input("サイコロを振りますか? (yes/no): ").strip().lower()

モンスターがサイコロを振り、その出目が表示されます。

次にプレイヤーがサイコロを振るかどうかを選択できます。input 関数でプレイヤーに選択を求めます。

プレイヤーのサイコロの結果を比較

player_roll = monster.dice_roll()
print(f"プレイヤーがサイコロを振った。出目は {player_roll}")

if player_roll > monster_roll:
    print(f"{monster.get_name()}を捕まえた!")
    captured_monsters.append(monster.get_name())
    captured = True
elif player_roll == monster_roll:
    print("引き分けでもう一度!")
else:
    print(f"{monster.get_name()}を捕まえられなかった。ゲームオーバー!")
    return

ここではプレイヤーのサイコロの出目とモンスターの出目を比較しています。

プレイヤーの出目がモンスターより大きい場合、そのモンスターを捕まえることができ、モンスターの名前を captured_monsters に追加します。

引き分けの場合は再挑戦し、モンスターに負けた場合はゲームオーバーです。

捕まえたモンスターを表示

print("捕まえたモンスター: " + ", ".join(captured_monsters))
print("ゲーム終了")

ゲームが終わった後、捕まえたモンスターの一覧が表示され、ゲームが終了します。

まとめ

このプログラムではサイコロを使ったシンプルなゲームを通じて、オブジェクト指向プログラミングの考え方に触れることができました。

初心者にとってこのプログラムは理解しやすく、楽しみながらPythonの基礎を身につけることができる良い練習問題です。

次はモンスターを増やしたり、ゲームのルールを拡張したりして、さらに発展させてみましょう!

Pythonのゲームコード一覧はこちら

<<前の問題 問題集Top 次の問題>>

この記事への質問・コメント

この記事を作成するにあたりAIを活用しています。

問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。






    Python記事トップへ戻る
    トップページへ戻る