Ruby練習問題3-☆2:石取りゲームを作ろう

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

Rubyの初心者向け問題3-☆2:石取りゲームを作ろう

この問題を解くために必要な知識:
【レベル1~2の知識】
コメントの書き方、変数と定数、基本データ型、四則演算と演算子、入力と出力、文字列操作、分岐処理(if、if~else、elsif、case)、繰り返し処理(for、while、until、each)、範囲(Range)、例外処理(begin-rescue-end)、配列(Array)、ハッシュ(Hash)、コレクション操作(配列、ハッシュの操作)、Enumerableモジュール

【レベル3の知識】
メソッドの定義と呼び出し、メソッドの戻り値クラスの定義と使用コンストラクタクラスの継承モジュールの定義と使用ミックスイン

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

Ruby練習問題3-☆2:石取りゲームを作ろう

シンプルな「石取りゲーム」を作成しましょう。

このゲームでは全部で10個ある石の中からプレイヤーとコンピュータが交互に石を取っていき、最後の1つを取った方が負けとなります。

ゲームはプレイヤーが終了を選択するまで続きます。

この問題の要件

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

  • プレイヤーが1回に取ることができる石の数は1つから3つまでとすること。
  • コンピュータも1回に1つから3つの石をランダムに取ること。
  • 石の総数は10個とし、誰かが最後の1つを取った時点でその人が負けとすること。
  • ゲームはプレイヤーが終了を選択するまで繰り返されること。

ただし、以下のような実行結果となること。

----- ↓出力される結果の例↓ -----

残りの石の数: 10
取る石の数を入力してください(1から3まで):
2
残りの石の数: 8
コンピュータが取った石の数: 3
残りの石の数: 5
取る石の数を入力してください(1から3まで):
1
残りの石の数: 4
コンピュータが取った石の数: 2
残りの石の数: 2
取る石の数を入力してください(1から3まで):
1
残りの石の数: 1
コンピュータが取った石の数: 1
コンピュータの負けです。
ゲームを続けますか?(続けるにはエンターキーを押してください。終了するには「終了」と入力してください。)

----- ↑出力される結果の例↑ -----

この問題を解くヒント

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

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

正解のコードは上から順に以下のような構成となっています。

1.プレイヤーの入力を受け取るメソッド get_player_choice の定義
 1-1. puts を使ってプレイヤーに入力を求める
 1-2. gets.chomp でプレイヤーの入力を取得し、 Integer で整数に変換
 1-3. 1から3以外の入力があった場合に raise で例外を発生させる
 1-4. rescue で無効な入力に対してエラーメッセージを表示し、再入力を求める
 1-5. 有効な選択肢が入力されたら、その数値を返す

2.コンピュータの手をランダムに選ぶメソッド get_computer_choice の定義
 2-1. rand(1..3) を使って1から3の範囲でランダムに数値を生成し、その数値を返す

3.ゲームのメインループ play_game の定義
 3-1. 残りの石の数 total_stones を10に初期化
 3-2. 残りの石が0になるまでループを繰り返す
  3-2-1. 残りの石の数を表示
  3-2-2. プレイヤーのターン
   3-2-2-1. get_player_choice を呼び出し、プレイヤーの選択した数を取得
   3-2-2-2. 選択した数だけ total_stones を減らす
   3-2-2-3. 残りの石が0以下になった場合、プレイヤーの負けと判定し、ループを終了
  3-2-3. コンピュータのターン
   3-2-3-1. get_computer_choice を呼び出し、コンピュータが選んだ数を取得
   3-2-3-2. 選択した数だけ total_stones を減らす
   3-2-3-3. 残りの石が0以下になった場合、コンピュータの負けと判定し、ループを終了

4.ゲームの開始とループ処理
 4-1. play_game メソッドを呼び出してゲームを開始
 4-2. プレイヤーにゲームを続けるかどうかを確認
  4-2-1. プレイヤーが「終了」と入力した場合、ゲームを終了
 4-3. 「終了」と入力されなかった場合、再度 play_game を呼び出してゲームを繰り返す

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

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

# プレイヤーの入力を受け取るメソッド
def get_player_choice
  begin
    puts "取る石の数を入力してください(1から3まで):"
    =begin 【穴埋め問題1】
    ここにプレイヤーからの入力を取得して整数に変換し、変数choiceに格納するコードを書いてください。
    =end
    raise if choice < 1 || choice > 3  # 1から3以外の数は無効
  rescue
    puts "無効な入力です。もう一度入力してください。"
    retry
  end
  choice
end

# コンピュータの手をランダムに選ぶメソッド
def get_computer_choice
  =begin 【穴埋め問題2】
  ここに1から3の範囲でランダムに数を選んで返すコードを書いてください。
  =end
end

# ゲームのメインループ
def play_game
  total_stones = 10  # 石の総数を10に設定
  while total_stones > 0
    puts "残りの石の数: #{total_stones}"
    
    # プレイヤーのターン
    player_choice = get_player_choice
    total_stones -= player_choice
    if total_stones <= 0
      puts "あなたの負けです。"
      break
    end
    
    # コンピュータのターン
    =begin 【穴埋め問題3】
    ここにコンピュータがランダムに1から3の石を取るコードを書いてください。
    =end
    puts "コンピュータが取った石の数: #{computer_choice}"
    total_stones -= computer_choice
    if total_stones <= 0
      puts "コンピュータの負けです。"
      break
    end
  end
end

# ゲームの開始
loop do
  play_game
  puts "ゲームを続けますか?(続けるにはエンターキーを押してください。終了するには「終了」と入力してください。)"
  continue_game = gets.chomp
  break if continue_game == "終了"
end

puts "ゲームを終了します。"

 

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



解答例と解説

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

正解コードの例

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

********************

# メソッドを定義して石取りゲームを実装します

# プレイヤーの入力を受け取るメソッド
def get_player_choice
  begin
    puts "取る石の数を入力してください(1から3まで):"
    choice = Integer(gets.chomp)  # 入力を整数に変換
    raise if choice < 1 || choice > 3  # 1から3以外の数は無効
  rescue
    puts "無効な入力です。もう一度入力してください。"
    retry
  end
  choice
end

# コンピュータの手をランダムに選ぶメソッド
def get_computer_choice
  rand(1..3)  # 1から3の範囲でランダムに選ぶ
end

# ゲームのメインループ
def play_game
  total_stones = 10  # 石の総数を10に設定
  while total_stones > 0
    puts "残りの石の数: #{total_stones}"
    
    # プレイヤーのターン
    player_choice = get_player_choice
    total_stones -= player_choice
    if total_stones <= 0
      puts "あなたの負けです。"
      break
    end
    
    # コンピュータのターン
    computer_choice = get_computer_choice
    puts "コンピュータが取った石の数: #{computer_choice}"
    total_stones -= computer_choice
    if total_stones <= 0
      puts "コンピュータの負けです。"
      break
    end
  end
end

# ゲームの開始
loop do
  play_game
  puts "ゲームを続けますか?(続けるにはエンターキーを押してください。終了するには「終了」と入力してください。)"
  continue_game = gets.chomp
  break if continue_game == "終了"
end

puts "ゲームを終了します。"

********************

コードの解説

このプログラムは、プレイヤーとコンピュータが交互に石を取り、最後の石を取った方が負けとなるゲームです。では、コードをブロックごとに分けて解説します。

プレイヤーの入力を受け取るメソッド

def get_player_choice
  begin
    puts "取る石の数を入力してください(1から3まで):"
    choice = Integer(gets.chomp)
    raise if choice < 1 || choice > 3
  rescue
    puts "無効な入力です。もう一度入力してください。"
    retry
  end
  choice
end

このメソッドでは、プレイヤーから1から3までの整数を入力してもらいます。

  • gets.chomp で入力を受け取り、それを Integer で数値に変換します。
  • raise を使って1から3以外の数が入力された場合、例外を発生させます。
  • 例外が発生したら rescue ブロックが実行され、エラーメッセージを表示し、retry で再度入力を求めます。

コンピュータの手をランダムに選ぶメソッド

def get_computer_choice
  rand(1..3)
end

このメソッドでは、コンピュータが1から3の間でランダムに石を取る数を決定します。
rand(1..3) は、1から3の範囲でランダムな数を生成します。

ゲームのメインループ

def play_game
  total_stones = 10
  while total_stones > 0
    puts "残りの石の数: #{total_stones}"
    
    player_choice = get_player_choice
    total_stones -= player_choice
    if total_stones <= 0
      puts "あなたの負けです。"
      break
    end
    
    computer_choice = get_computer_choice
    puts "コンピュータが取った石の数: #{computer_choice}"
    total_stones -= computer_choice
    if total_stones <= 0
      puts "コンピュータの負けです。"
      break
    end
  end
end

このメソッドがゲームのメイン部分です。

  • 最初に石の総数 total_stones を10に設定します。
  • while total_stones > 0 のループでゲームが続きます。石が残っている限りプレイヤーとコンピュータが交互に石を取ります。
  • プレイヤーとコンピュータが取った石の数を total_stones から引き、その結果に応じてゲームの勝敗を決定します。

ゲームの開始とループ処理

loop do
  play_game
  puts "ゲームを続けますか?(続けるにはエンターキーを押してください。終了するには「終了」と入力してください。)"
  continue_game = gets.chomp
  break if continue_game == "終了"
end

ここでは、loop を使ってゲームを繰り返しプレイすることができます。
プレイヤーが「終了」と入力すると、ループが終了し、ゲームが終了します。再度 play_game メソッドを呼び出すことで、新しいゲームが始まります。

このコードは基本的な制御構文(while ループ、if 文、メソッドの定義)を学ぶ良い機会となります。

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

この問題への質問・コメント

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

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






    Ruby練習問題集へ戻る
    トップページへ戻る