Игра виселица в Ruby


Я всего несколько месяцев в изучении кода и никогда не было рассмотрен код. Это структура класса ОК? Я должен разделить его иначе? Как код в целом?

require "json"
class Hangman

  def initialize
    @secret_word = select_word
    @display_content = "_" * @secret_word.length
    @failed_attemps = 0
  end

  def main_menu
    option = "3"
    until option == "1" || option == "2"
      puts "(1) New game"
      puts "(2) Load game"
      print "Play new game or load the saved game? "
      option = gets.chomp[0]
      if option == "2" 
        if File.exist?("saved_state.json")
          load_state
        else
          puts "There is no saved game, save one first"
          option = "3"
        end
      end
    end
    start_game
  end

  private

  def save_state
    json_object = { 
      :secret_word => @secret_word, 
      :display_content => @display_content,
      :failed_attemps => @failed_attemps 
    }.to_json
    File.open("saved_state.json", "w") { |file| file.write(json_object) }
  end

  def load_state
    save_file = File.read("saved_state.json")
    json_hash = JSON.parse(save_file)
    @secret_word = json_hash["secret_word"]
    @display_content = json_hash["display_content"]
    @failed_attemps = json_hash["failed_attemps"]
  end

  def start_game
    player_won = false
    while @failed_attemps != 10 
      puts @display_content
      puts "#{10 - @failed_attemps.to_i} turns left" 
      print "Enter a letter or attempt the full word: "
      letters = gets.chomp
      if letters == "save"
        save_state
        next
      end
      break if letters == "exit"
      update_display(letters) if letters
      player_won = player_won?
      break if player_won
    end
    puts "Game over, the secret word was: #{@secret_word}" if @failed_attemps == 10
  end

  def select_word
    words = File.readlines("5desk.txt").select { |word| word.length.between?(5, 12) }
    words[rand(words.length)].strip
  end

  def update_display(letters)
    letters.downcase!
    current_state = "#{@display_content}"
    if letters.length == 1
      @display_content.length.times do |index|
        @display_content[index] = letters if @secret_word[index].downcase == letters
      end
    else
      @display_content = letters if letters == @secret_word.downcase
    end

    current_state == @display_content ? print_toon(1) : print_toon(0)
  end

  def player_won?
    unless @display_content.include?("_")
      puts "You found the correct word!"
      true
    end
  end

  def print_toon(increment)
    @failed_attemps += increment

    case @failed_attemps
    when 0
      puts "  ______"
      puts "        |"
      puts "        |"
      puts "        |"
      puts "        |"
    when 1
      puts "  ______"
      puts " |      |"
      puts "        |"
      puts "        |"
      puts "        |"
    when 2
      puts "  ______"
      puts " |      |"
      puts "(oo)    |"
      puts "        |"
      puts "        |"
    when 3
      puts "  ______"
      puts " |      |"
      puts "(oo)    |"
      puts " |      |"
      puts "        |"
    when 4
      puts "  ______"
      puts " |      |"
      puts "(oo)    |"
      puts " ||     |"
      puts "        |"  
    when 5
      puts "  ______"
      puts " |      |"
      puts "(oo)    |"
      puts "/||     |"
      puts "        |"
    when 6
      puts "  ______"
      puts " |      |"
      puts "(oo)    |"
      puts "/||\\    |"
      puts "        |"
    when 7
      puts "  ______"
      puts " |      |"
      puts "(oo)    |"
      puts "/||\\    |"
      puts "/       |"
    when 8
      puts "  ______"
      puts " |      |"
      puts "(oo)    |"
      puts "/||\\    |"
      puts "/  \\    |"
    when 9
      puts "  ______"
      puts " |      |"
      puts "(ox)    |"
      puts "/||\\    |"
      puts "/  \\    |"  
    when 10
      puts "  ______"
      puts " |      |"
      puts "(xx)    |"
      puts "/||\\    |"
      puts "/  \\    |"           
    end
    puts ""
  end

end

my_game = Hangman.new
my_game.main_menu


323
5
задан 15 марта 2018 в 04:03 Источник Поделиться
Комментарии
3 ответа

Он хорошо смотрится и читается.

Несколько заметок :


  • current_state = "#{@display_content}" может быть написано current_state = @display_content.clone

  • words[rand(words.length)].strip может быть words.sample.strip

  • select { |word| word.length.between?(5, 12) } подберем слова с длиной между 4 и 11 в связи с новой строки.

  • Было бы неплохо иметь еще несколько отзывов:


    • когда игра была успешно saved

    • когда игра была загружена, что рисунок выглядит как

    • когда последнее письмо было догадаться, что полное слово. Вот пример вывода:



_u_ar_
4 turns left
Enter a letter or attempt the full word: s
______
| |
(oo) |
/||\ |
|

su_ars
4 turns left
Enter a letter or attempt the full word: g
______
| |
(oo) |
/||\ |
|

You found the correct word!


  • Можно заменить весь case;when заявление с массивом строк.

Следите за хорошую работу!

1
ответ дан 21 марта 2018 в 12:03 Источник Поделиться

Очень незначительная деталь стиля является окрошка. Где у вас есть:

json_object = { :secret_word => @secret_word, :display_content => @display_content,
:failed_attemps => @failed_attemps }.to_json

Я хотел изменить отступы, так что каждая строка кода делает одна конкретная вещь. Я также хотел бы использовать синтаксис Ruby 1.9 хэш:

json_object = {
secret_word: @secret_word,
display_content: @display_content,
failed_attemps: @failed_attemps
}.to_json

Также, я бы изменил название переменной failed_attemps для failed_attempts :-)

1
ответ дан 15 апреля 2018 в 01:04 Источник Поделиться

Первое, что я заметил, был сбежал \\; вам не нужно, что если вы используете 'hello\world' вместо "hello\\world" (В общем с символьных строк лучше использовать '' потому что вы не должны обращать столько внимания на побег как с "").

0
ответ дан 5 апреля 2018 в 09:04 Источник Поделиться