英単語しりとりプログラムをRubyで書いてみた

[練習問題- プログラミングスレまとめ in VIP](http://vipprog.net/wiki/exercise.html#x38ec247)にある英単語しりとりプログラミングを書いてみました
仕様は問題文にあるものを元にちょっと変えてます

全力を投じた物なので、コード本体や読みやすさなど、気になる所があればご指摘お願いします

# ディレクトリ構造
```
word_chain_game
├── lib
│   ├── dictionary.txt
│   ├── main_proces.rb
│   └── word_proces.rb
└── word_chain_game.rb
```

# コードたち
## word_cahin_game.rb
```ruby:word_cahin_game.rb
require_relative('./lib/main_proces')

first_person, first_char = bigin_game
loop_game(first_person, first_char)
```

## main_proces.rb
```ruby: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
```ruby: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
```