#問題
これはn桁の数を探すゲームです。
適当な数を入れると桁も数字もあっていれば「Hit」としその個数が、
数字はあっているが桁が異なっていれば「Blow」としてその個数が出力されます。
それを繰り返すことで答えを探すことができます。
このゲームを作成しなさい。
答えの数は乱数を使って毎回別の答えを用意しましょう。
※こちらのサイトから引用
#解答
hit_blow.rb
# 桁数を設定(問題の仕様上、最大は10桁)
# 今回は例に従い4桁
DIGIT_NUMBER = 4
# 正解の数を乱数で生成するメソッド
# 正解の数は各桁の数字が異ならなければならない
# 返り値:生成されたn桁の乱数
def make_answer_number
# 正解の数が生成できたか調べるフラグ
answer_number_flag = false
# 各桁の数が異なる数が生成されるまで無限ループ
while !answer_number_flag
# フラグは最初はtrue
answer_number_flag = true
# 正解の数を生成
# 正解の数は10^(n-1)〜(10^n)-1の数
rand_number = rand((10**(DIGIT_NUMBER - 1))..((10**DIGIT_NUMBER) - 1))
# return用の変数
return_answer_number = rand_number
# 各桁の数を格納する配列
rand_number_array = []
# 各桁の数を配列に格納
DIGIT_NUMBER.times do
rand_number_array.push(rand_number % 10)
rand_number /= 10
end
# 各桁の数が異なっているか調べる
rand_number_array.each_with_index do |digit_number, index|
(index + 1).upto(rand_number_array.length - 1) do |upto_times|
if digit_number == rand_number_array[upto_times]
answer_number_flag = false
end
end
end
end
return_answer_number
end
# ゲーム説明を表示するメソッド
def show_rule
puts "数当てゲームを行います"
puts "これは#{DIGIT_NUMBER}桁の数を探すゲームです"
puts "適当な数を入れると桁も数字もあっていれば「hit」としその個数が、"
puts "数字はあっているが桁が異なっていれば「blow」としてその個数が出力されます"
puts "それを繰り返すことで答えを探すことができます"
puts "それではゲームを開始します"
end
# 入力された整数が設定した桁数と等しいか判断するメソッド
# n桁の整数の場合、10^(n-1)〜(10^n)-1の範囲に存在していればよい
# input_number:入力された整数
def input_number_judge(input_number)
# 正しかったらtrueを、間違っていたらfalseを返す
if input_number < 10**(DIGIT_NUMBER) && input_number >= 10**(DIGIT_NUMBER - 1)
true
else
puts "入力された数は#{DIGIT_NUMBER}桁ではありません"
puts "もう一度入力してください"
false
end
end
# n桁の整数の各桁の数を順に取り出していくメソッド
# 返り値は要素数nの配列
# number:n桁の整数
def number_to_array(number)
number_array = []
DIGIT_NUMBER.times do
# 桁数の数だけ10で割った余りを配列に追加
number_array.push(number % 10)
# より上位の桁を求めるため10で割る
number /= 10
end
# 下位の桁から順に入っているため配列を反転してreturn
number_array.reverse
end
# 正解の数と入力された数を比較するメソッド
# input_number:入力された数
# set_number:正解の数
def input_answer_judge(input_number, set_number)
# hitとblowの数を数えるための変数
hit_time = 0
blow_time = 0
# 入力された数を配列として取り出し
input_number_array = number_to_array(input_number)
# 正解の数を配列として取り出し
set_number_array = number_to_array(set_number)
# 正解の数と入力された数の比較
input_number_array.each_with_index do |current_input_number, input_index|
# hitかどうか判定
if current_input_number == set_number_array[input_index]
hit_time += 1
# hitしたら次の桁へ
next
# hitじゃなかったらblowかどうか判定
else
# 正解データと1つずつ比較
set_number_array.each_with_index do |current_set_number, set_index|
# 同じ桁は上でhitしていないので異なることは自明なので飛ばす
next if input_index == set_index
if current_set_number == current_input_number
blow_time += 1
# blowだったらループから抜ける
break
end
end
end
end
puts "#{hit_time}hit, #{blow_time}blow"
# hit数が桁数と同じだったら正解と完全一致だからtrueを返す
# 一致しなかったらfalseを返す
if hit_time == DIGIT_NUMBER
true
else
false
end
end
#=========================================================
# ここからゲーム開始
#=========================================================
# 正解の数を生成
answer_number = make_answer_number
# ゲーム説明を表示
show_rule
# 正解かどうか判定するフラグ
answer_flag = false
# 不正解の間はずっとループ
while !answer_flag
print "#{DIGIT_NUMBER}桁の数を入力してください : "
# 数を入力
anticipated_number = gets.to_i
# 入力された数の桁数が正しいか判定
# 正しくなかったらもう一度入力
redo unless input_number_judge(anticipated_number)
# 入力された数を正解の数と比較する
answer_flag = input_answer_judge(anticipated_number, answer_number)
end
puts "正解です!"
#結果
数当てゲームを行います
これは4桁の数を探すゲームです
適当な数を入れると桁も数字もあっていれば「hit」としその個数が、
数字はあっているが桁が異なっていれば「blow」としてその個数が出力されます
それを繰り返すことで答えを探すことができます
それではゲームを開始します
4桁の数を入力してください : 999
入力された数は4桁ではありません
もう一度入力してください
4桁の数を入力してください : 10000
入力された数は4桁ではありません
もう一度入力してください
4桁の数を入力してください : 1359
0hit, 0blow
4桁の数を入力してください : 1627
1hit, 1blow
4桁の数を入力してください : 2615
2hit, 0blow
4桁の数を入力してください : 2604
2hit, 2blow
4桁の数を入力してください : 2640
4hit, 0blow
正解です!
#参考