この記事の練習問題で使用する知識:
基礎文法、制御構造、メソッド(レッスン1~3)、配列の基本、eachメソッド、クラスの定義と使用、イニシャライザ、アクセスメソッド
Rubyのゲームコード一覧はこちら
<<前のページ | Ruby記事一覧 |
次のページ>> |
確認問題:モンスター捕獲ゲームを作ろう
Rubyでモンスターを捕獲するシンプルなゲームを作成しましょう。
ゲームには3種類のモンスターが登場します。それぞれのモンスターはサイコロを振り、プレイヤーも同じようにサイコロを振ります。
サイコロの出目を競い、プレイヤーがモンスターの出目を上回るとモンスターを捕まえることができます。ただし、プレイヤーがモンスターに負けた場合はゲームオーバーになります。
ゲームを進める中で、すべてのモンスターを捕まえることを目指しましょう。
この問題の要件
以下の要件に従ってコードを完成させてください。
- モンスタークラスを定義すること:
- インスタンス変数
@name
を持つ。 dice_roll
メソッドを定義し、1から6までの乱数を返すこと。
- インスタンス変数
- モンスター捕獲ゲームクラスを定義すること:
- 3種類のモンスター(例: スライム、ゴブリン、ドラゴン)をリストとして保持する。
- プレイヤーがサイコロを振ってモンスターと出目を競う仕組みを実装する。
- ゲーム進行の詳細:
- プレイヤーがサイコロを振るか選択できること。
- プレイヤーがモンスターより高い出目を出した場合、そのモンスターを捕まえたと表示すること。
- プレイヤーが負けた場合は「ゲームオーバー」と表示してゲームを終了すること。
- 引き分けの場合は再挑戦する。
- ゲーム終了後:
- 捕まえたモンスターのリストを表示する。
ただし、以下のような実行結果となるコードを書くこと。
*****↓↓正解コードの実行結果の例↓↓*****
モンスター捕獲ゲームを始めます! スライムが現れた! スライムがサイコロを振った。出目は 3 サイコロを振りますか? (yes/no): yes プレイヤーがサイコロを振った。出目は 4 スライムを捕まえた! ゴブリンが現れた! ゴブリンがサイコロを振った。出目は 6 サイコロを振りますか? (yes/no): yes プレイヤーがサイコロを振った。出目は 2 ゴブリンを捕まえられなかった。ゲームオーバー! 捕まえたモンスター: スライム ゲーム終了
この問題を解くヒント
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メソッドを呼び出してゲームを開始
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
# モンスタークラス 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
class MonsterCaptureGame
: ゲーム全体のロジックを管理するクラスです。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を活用しています。
問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。