練習問題- プログラミングスレまとめ in VIPにある英単語しりとりプログラミングを書いてみました
仕様は問題文にあるものを元にちょっと変えてます
全力を投じた物なので、コード本体や読みやすさなど、気になる所があればご指摘お願いします
ディレクトリ構造
word_chain_game
├── lib
│ ├── dictionary.txt
│ ├── main_proces.rb
│ └── word_proces.rb
└── word_chain_game.rb
コードたち
word_cahin_game.rb
word_cahin_game.rb
require_relative('./lib/main_proces')
first_person, first_char = bigin_game
loop_game(first_person, first_char)
main_proces.rb
main_proces.rb
require_relative('word_proces.rb')
# ゲーム進行処理
def bigin_game
first_person = ["あなた", "わたし"].sample
a_z_out_x_z = ("a".."y").to_a - ["x"]
first_char = a_z_out_x_z.sample
puts "me: 英単語しりとりゲームを始めます。"
puts "me: 同じ単語を使うか空行を入力するとあなたの負けです"
sleep 1
puts "me: 先行は#{first_person}です"
puts "me: 最初の文字は#{first_char}です" if first_person == "あなた"
return first_person, first_char
end
def loop_game(first_person, word)
# ループで戻ってくるか先手がわたしの時computerの番になる
loop.with_index do |_, i|
sleep 1
word = computer_main(word) if i != 0 || first_person == "わたし"
word = user_main(word)
end
end
def exit_game(luser, last_word = nil)
case luser
when"computer"
puts "me: まいりました!あなたの勝ちです"
when "user"
unless (is_retire = last_word == nil)
puts "me: その言葉は#{last_word[0]}回目に#{last_word[1]}が使用しています"
end
puts "me: わたしの勝ちです!"
when "draw"
puts "me: 申し訳ありません、システム内辞書が尽きたのでこれ以上ゲームを続けられません"
puts "me: 引き分けです"
end
sleep 1
puts "me: 今回のしりとりでは#{$used_words.size}個の単語を使用しました"
exit
end
# computerとuserのメイン処理
def computer_main(word)
judge_whether_computer_loses(word)
selected_word = select_computer_word(word)
puts "me: #{selected_word}"
tarn_pass("わたし", selected_word)
selected_word
end
def user_main(word)
print "you: "
input_word = gets.chomp
judge_whether_user_loses(word, input_word)
judge_whether_word_is_suitable(word, input_word)
tarn_pass("あなた", input_word)
input_word
rescue RuntimeError
puts "!! error: その単語は登録されていないか、しりとりになっていません !!"
puts "!! error: 他の単語を入力してください !!"
retry
end
word_proces.rb
word_proces.rb
$user_dictionary =
File.open(File.expand_path('../dictionary.txt', __FILE__)) do |f|
f.read.split("\n").group_by { |x| x.chr.downcase }
end
# computerの辞書は各アルファベットにつきランダムで8個
$computer_dictionary =
$user_dictionary.each_with_object({}) do |(k, v), ary|
ary[k] = v.sample(8)
end
$used_words = {}
$game_count = 1
# computerの単語処理
def judge_whether_computer_loses(word)
if ($computer_dictionary[word[-1]] - $used_words.keys) == []
exit_game("computer")
end
end
def select_computer_word(word)
$computer_dictionary[word[-1]].shift
end
# userの単語処理
# 以前使った単語か空行だと負け、辞書がなくなってたら引き分け
def judge_whether_user_loses(compter_word, user_word)
if $used_words.key?(user_word) || user_word == ""
exit_game("user", $used_words[user_word])
elsif ($user_dictionary[compter_word[-1]] - $used_words.keys) == []
exit_game("draw")
end
end
def judge_whether_word_is_suitable(computer_word, user_word)
dictionary_has_user_word =
$user_dictionary[computer_word[-1]].find { |x| x.downcase == user_word.downcase }
raise unless dictionary_has_user_word
end
# 全体の単語処理
def tarn_pass(passer, word)
$used_words[word] = [$game_count, passer]
$game_count += 1
end