【Ruby】確認問題5-☆1:モンスター捕獲ゲームを作ろう

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

この記事の練習問題で使用する知識:
基礎文法、制御構造、メソッド(レッスン1~3)配列の基本eachメソッドクラスの定義と使用イニシャライザアクセスメソッド

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

<<前のページ Ruby記事一覧 次のページ>>

確認問題:モンスター捕獲ゲームを作ろう

Rubyでモンスターを捕獲するシンプルなゲームを作成しましょう。

ゲームには3種類のモンスターが登場します。それぞれのモンスターはサイコロを振り、プレイヤーも同じようにサイコロを振ります。

サイコロの出目を競い、プレイヤーがモンスターの出目を上回るとモンスターを捕まえることができます。ただし、プレイヤーがモンスターに負けた場合はゲームオーバーになります。

ゲームを進める中で、すべてのモンスターを捕まえることを目指しましょう。

この問題の要件

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

  1. モンスタークラスを定義すること:
    • インスタンス変数 @name を持つ。
    • dice_roll メソッドを定義し、1から6までの乱数を返すこと。
  2. モンスター捕獲ゲームクラスを定義すること:
    • 3種類のモンスター(例: スライム、ゴブリン、ドラゴン)をリストとして保持する。
    • プレイヤーがサイコロを振ってモンスターと出目を競う仕組みを実装する。
  3. ゲーム進行の詳細
    • プレイヤーがサイコロを振るか選択できること。
    • プレイヤーがモンスターより高い出目を出した場合、そのモンスターを捕まえたと表示すること。
    • プレイヤーが負けた場合は「ゲームオーバー」と表示してゲームを終了すること。
    • 引き分けの場合は再挑戦する。
  4. ゲーム終了後
    • 捕まえたモンスターのリストを表示する。

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

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

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

この問題を解くヒント

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

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

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

1:Monsterクラスを定義
  □ attr_readerでname属性を公開
  □ initializeメソッドを定義し、引数nameを@nameに代入
  □ dice_rollメソッドを定義し、rand(1..6)を返す
2:MonsterCaptureGameクラスを定義
  □ initializeメソッドを定義
  □ □ @monstersにMonsterクラスのインスタンス(スライム、ゴブリン、ドラゴン)を格納
  □ □ @captured_monstersに空の配列を代入
  □ start_gameメソッドを定義
  □ □ 「モンスター捕獲ゲームを始めます!」と出力
  □ □ @monstersをループで処理
  □ □ □ モンスター名を出力
  □ □ □ capturedフラグをfalseに設定
  □ □ □ whileループをcapturedがtrueになるまで繰り返す
  □ □ □ □ モンスターのdice_rollメソッドを呼び出し、出目を出力
  □ □ □ □ 「サイコロを振りますか?」と出力し、ユーザー入力を取得
  □ □ □ □ if文で入力が”no”の場合を判定
  □ □ □ □ □ 「次のモンスターへ進みます。」と出力し、breakでループを抜ける
  □ □ □ □ player_rollを乱数で取得し、出目を出力
  □ □ □ □ if文でプレイヤーの出目がモンスターより大きい場合を判定
  □ □ □ □ □ モンスターを捕獲し、名前を@captured_monstersに追加
  □ □ □ □ □ capturedをtrueに設定
  □ □ □ □ elsif文で引き分けの場合を判定
  □ □ □ □ □ 「引き分けでもう一度!」と出力
  □ □ □ □ else文でプレイヤーの出目が負けた場合を判定
  □ □ □ □ □ 「ゲームオーバー!」と出力し、end_gameメソッドを呼び出して終了
  □ end_gameメソッドを定義
  □ □ 捕獲したモンスターのリストを出力
  □ □ 「ゲーム終了」と出力
3:MonsterCaptureGameクラスのインスタンスを生成し、start_gameメソッドを呼び出してゲームを開始

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

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

# モンスタークラス
class Monster
  attr_reader :name

=begin
  【穴埋め問題1】
  initializeメソッドを定義し、引数nameをインスタンス変数@nameに代入するコードを書いてください。
=end

=begin
  【穴埋め問題2】
  dice_rollメソッドを定義し、1から6までの乱数を返すコードを書いてください。
=end
end

# ゲームクラス
class MonsterCaptureGame
=begin
  【穴埋め問題3】
  initializeメソッドを定義し、以下の内容を実装してください。
  ・@monstersにMonsterクラスのインスタンス(スライム、ゴブリン、ドラゴン)を格納すること。
  ・@captured_monstersに空の配列を代入すること。
=end

=begin
  【穴埋め問題4】
  start_gameメソッドを定義し、以下を実装してください。
  ・「モンスター捕獲ゲームを始めます!」と出力すること。
  ・@monstersをループで処理し、各モンスターに対してサイコロの勝負を行うコードを書くこと。
  ・プレイヤーがモンスターに勝った場合、そのモンスターを捕まえるコードを書くこと。
  ・プレイヤーが負けた場合、ゲームオーバーを表示して終了するコードを書くこと。
=end

=begin
  【穴埋め問題5】
  end_gameメソッドを定義し、以下を実装してください。
  ・捕まえたモンスターのリストを出力すること。
  ・「ゲーム終了」と出力すること。
=end
end

# ゲーム開始
=begin
【穴埋め問題6】
MonsterCaptureGameクラスのインスタンスを生成し、start_gameメソッドを呼び出すコードを書いてください。
=end

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

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

モンスター捕獲ゲームの正解コードと解説

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

正解コードの例

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

# モンスタークラス
class Monster
  attr_reader :name

  def initialize(name)
    @name = name
  end

  def dice_roll
    rand(1..6) # 1から6までのランダムな数字を返す
  end
end

# ゲームクラス
class MonsterCaptureGame
  def initialize
    @monsters = [
      Monster.new("スライム"),
      Monster.new("ゴブリン"),
      Monster.new("ドラゴン")
    ]
    @captured_monsters = []
  end

  def start_game
    puts "モンスター捕獲ゲームを始めます!"

    @monsters.each do |monster|
      puts "#{monster.name}が現れた!"
      captured = false

      while !captured
        monster_roll = monster.dice_roll
        puts "#{monster.name}がサイコロを振った。出目は #{monster_roll}"

        print "サイコロを振りますか? (yes/no): "
        response = gets.chomp.downcase

        if response == "no"
          puts "次のモンスターへ進みます。"
          break
        end

        player_roll = rand(1..6)
        puts "プレイヤーがサイコロを振った。出目は #{player_roll}"

        if player_roll > monster_roll
          puts "#{monster.name}を捕まえた!"
          @captured_monsters << monster.name
          captured = true
        elsif player_roll == monster_roll
          puts "引き分けでもう一度!"
        else
          puts "#{monster.name}を捕まえられなかった。ゲームオーバー!"
          return end_game
        end
      end
    end

    end_game
  end

  def end_game
    puts "捕まえたモンスター: #{@captured_monsters.join(', ')}"
    puts "ゲーム終了"
  end
end

# ゲーム開始
game = MonsterCaptureGame.new
game.start_game

正解コードの解説

このプログラムはモンスター捕獲ゲームを実装したものです。

モンスターごとにサイコロで対決し、勝利することでモンスターを捕まえることができます。

以下にコードをブロックごとに分割しながら解説します。

モンスタークラスの定義

class Monster
  attr_reader :name

  def initialize(name)
    @name = name
  end

  def dice_roll
    rand(1..6)
  end
end
  • class Monster: これはRubyでクラスを定義する構文です。Monsterはモンスターの性質を表現するクラスです。
  • attr_reader :name: この文法は@nameというインスタンス変数を読み取るためのゲッターメソッドを自動生成します。これにより外部からモンスターの名前を取得できます。
  • initializeメソッド: クラスのインスタンスが作られるときに実行されるコンストラクタです。@nameにモンスターの名前を設定しています。
  • dice_rollメソッド: サイコロを振る処理を表現しています。rand(1..6)で1から6のランダムな整数を生成します。

モンスター捕獲ゲームクラスの定義

class MonsterCaptureGame
  def initialize
    @monsters = [
      Monster.new("スライム"),
      Monster.new("ゴブリン"),
      Monster.new("ドラゴン")
    ]
    @captured_monsters = []
  end
  1. class MonsterCaptureGame: ゲーム全体のロジックを管理するクラスです。
  2. initializeメソッド:
    • @monsters: モンスターを管理する配列です。各要素はMonsterクラスのインスタンスです。
    • @captured_monsters: 捕獲したモンスターの名前を保持する空の配列です。

ゲーム開始のメインロジック

def start_game
  puts "モンスター捕獲ゲームを始めます!"

  @monsters.each do |monster|
    puts "#{monster.name}が現れた!"
    captured = false
  • start_gameメソッド: ゲームの進行を管理するメソッドです。
  • @monsters.each: 配列@monstersをループで処理し、各モンスターを順に操作します。
  • captured = false: 各モンスターが捕獲されたかどうかを追跡するフラグです。

プレイヤーのサイコロ対決の処理

    while !captured
      monster_roll = monster.dice_roll
      puts "#{monster.name}がサイコロを振った。出目は #{monster_roll}"

      print "サイコロを振りますか? (yes/no): "
      response = gets.chomp.downcase
  • while !captured: モンスターが捕獲されるまでループを継続します。
  • monster.dice_roll: モンスターがサイコロを振ります。その出目をmonster_rollに格納します。
  • gets.chomp.downcase: プレイヤーが「yes」または「no」を入力する処理です。入力を小文字に変換して処理します。

プレイヤーとモンスターの勝負

      player_roll = rand(1..6)
      puts "プレイヤーがサイコロを振った。出目は #{player_roll}"

      if player_roll > monster_roll
        puts "#{monster.name}を捕まえた!"
        @captured_monsters << monster.name
        captured = true
      elsif player_roll == monster_roll
        puts "引き分けでもう一度!"
      else
        puts "#{monster.name}を捕まえられなかった。ゲームオーバー!"
        return end_game
      end
    end
  • player_roll = rand(1..6): プレイヤーがサイコロを振り、その出目を生成します。
  • if player_roll > monster_roll: プレイヤーの出目がモンスターより大きい場合、モンスターを捕まえます。
  • elsif player_roll == monster_roll: 引き分けの場合、再挑戦となります。
  • else: プレイヤーが負けた場合、ゲームオーバーを宣言し、ゲームを終了します。

ゲーム終了処理

def end_game
  puts "捕まえたモンスター: #{@captured_monsters.join(', ')}"
  puts "ゲーム終了"
end
  • end_gameメソッド: 捕獲したモンスターのリストを表示し、ゲーム終了を告げる処理です。
  • @captured_monsters.join(', '): 配列をカンマで結合して文字列に変換します。

ゲームの実行

game = MonsterCaptureGame.new
game.start_game
  • MonsterCaptureGame.new: MonsterCaptureGameクラスの新しいインスタンスを作成します。
  • game.start_game: ゲームを開始します。

まとめ

このプログラムを通じてRubyのクラス設計や配列の操作、ランダム値の生成、条件分岐を学ぶことができます。

初心者が楽しく学べる構造で設計されており、プログラミングの基礎を自然に身につけられるでしょう。

実際にコードを変更して、独自のモンスターやゲームルールを追加してみるのも良い練習です。

ぜひ挑戦してみてください!

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

<<前のページ Ruby記事一覧 次のページ>>

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

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

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






    Rubyテキスト&問題集へ戻る
    トップページへ戻る