Каким-то образом доступ к различным переменным экземпляра - PullRequest
0 голосов
/ 06 июня 2018
class Hangman
  attr_reader :guesser, :referee, :board 
  def initialize(options = {})
    @guesser = options[:guesser]
    @referee = options[:referee]    #class objects
  end

  def play
    setup
    take_turn until over?
    conclude
  end


  def setup
    secret_length = @referee.pick_secret_word
    @guesser.register_secret_length(secret_length)
    @board = Array.new(secret_length)
  end

  def take_turn
    letter = @guesser.guess(@board)
    correct_indicies = @referee.check_guess(letter)
    self.update_board(letter,correct_indicies)
    @guesser.handle_response(letter,correct_indicies)
  end

  def update_board(letter,correct_indicies)
    correct_indicies.each{|index| @board[index] = letter}
  end

  private

    def over?
      @board.count(nil) == 0
    end

    def conclude
      puts "Congrats the game is over."
      puts "The hidden word was #{board.join}"
    end

end



class HumanPlayer

  def initialize
    @guessed_letters = []
  end

  def pick_secret_word
    puts "Enter the length of your word."
    gets.chomp.to_i
  end

  def register_secret_length(length)
    puts "The length of the word is #{length}"
  end

  def guess(board)
    print_board(board)
    print "> "
    guess = gets.chomp
    processed_guess(guess)
  end

  def check_guess(letter)
    puts "The letter, #{letter}, guessed was at these indicies."
    puts "Input formart ex. (2 4 6)"
    indicies = gets.chomp.split(" ").map(&:to_i)
  end

  def handle_response(letter, indicies)
    puts "Found #{letter} at positions #{indicies}"
  end

  private

    def print_board(board)
      board_string = board.map do |el|
        el.nil? ? "_" : el
      end.join("")
      puts "Secret word: #{board_string}"
    end

    def processed_guess(guess)
      unless @guessed_letters.include?(guess) || guess.length > 1 
        @guessed_letters << guess
        return guess
      else
        puts "You have already guessed #{guess}"
        puts "Please try again."
        puts "You have guessed #{@guessed_letters}"
        print "> "
        guess = gets.chomp
        processed_guess(guess)
      end
    end

end

class ComputerPlayer
  attr_reader :secret_word, :secret_word_length, :candidate_words, 
:guessed_letters
  def initialize(dictionary = ComputerPlayer.default_dictionary)
    @dictionary = dictionary
    @alphabet = ("a".."z").to_a
    @guessed_letters = []
  end

  def self.default_dictionary
    contents = File.readlines("dictionary.txt").map{|word| word.chomp}
  end


  def pick_secret_word
    @secret_word = @dictionary.sample
    print @secret_word
    secret_word_length = @secret_word.length
  end

  def check_guess(letter)
    secret_word_arr =   @secret_word.chars
    secret_word_arr.each_index.select{|index| @secret_word[index] == letter}
  end

  def register_secret_length(secret_length)
    @candidate_words = @dictionary.select{|word| word.length == secret_length}
  end

  def guess(board)
    print_board(board)
    letter = guess_most_common
    processed_most_common(letter)
    puts "HERE #{@guessed_letters}"
    letter
  end

  def handle_response(letter, indicies)
    @candidate_words.select! do |word|
      indicies == word.chars.each_index.select {|index| word[index] == letter} #so the problem here is if you guess "r" give correct index of [0] and it checks "rear" it would assume its correct even tho theres an extra "r" 
    end
     puts "Found #{letter} at positions #{indicies}"

  end


  def guess_most_common
    puts "HERE2 #{@guessed_letters}"
    most_common_hash = Hash.new(0)
    uniq_candidate_arr = @candidate_words.map{|word| word.chars.uniq.join}
    uniq_candidate_arr.join.each_char{|char| most_common_hash[char] += 1 unless @guessed_letters.include?(char)
  p char}
    print "#{most_common_hash}"
    most_common_letter = most_common_hash.sort_by{|key,value| value}.reverse.to_h.keys.first

  end


  private

    def print_board(board)
      board_string = board.map do |el|
        el.nil? ? "_" : el
      end.join("")
      puts "Secret word: #{board_string}"
    end

    def processed_most_common(letter)
      @guessed_letters << letter unless @guessed_letters.include?(letter)
    end 
end

if __FILE__ == $PROGRAM_NAME
  my_computer = ComputerPlayer.new
  my_human = HumanPlayer.new

  game = Hangman.new({guesser:my_human, referee:my_computer})

  game.play
end

Извините, если это дерьмовый формат, но я работаю над проектом Hangman, но застрял.Я пытаюсь заставить ComputerPlayer угадать самое распространенное письмо.После того, как он угадает наиболее распространенную букву, он будет угадывать следующую наиболее распространенную букву и, следовательно, четвертую.

Я сделал @guessed_letters = [], чтобы отслеживать буквы, которые я уже угадал, поэтому я не буду считать это в следующий раз, когда компьютер угадывает букву.

Проблема в том, что@guessed_letter не отслеживает мои угаданные письма правильно.Я напечатал их в 2 областях.Один в классе ComputerPlayer # guess и один в ComputerPlayer # guess_most_common.Метод предположения печатает массив @guessed_letters правильно с уже угаданными буквами.Метод guess_most_common всегда печатает пустой массив @guessed_letters.Как это возможно, что они оба печатают разные вещи?

1 Ответ

0 голосов
/ 06 июня 2018

Итак, проблема в том, что в следующем тестовом примере RSpec "HERE2" является пустым массивом и пока не содержит предположение "e":

describe "Phase III" do
  describe "#guess" do
    let(:guesser) { ComputerPlayer.new(["reel","keel","meet"]) }
    before(:each) { guesser.register_secret_length(4) }

    context "when a guess has been made" do
      it "returns the most common letter in the remaining #candidate_words" do
      board = [nil, "e", "e", nil]

      expect(guesser.guess(board)).to eq("l")
    end
  end
end

Причинаэто то, что вы еще не сказали ни одного кода, который угадали «е» (то есть вы не вызывали processed_most_common с «е»).Вы только сообщаете guesser, что доска находится в таком состоянии, что две средние буквы - это «е».

Если бы мы, например, изменили тест на:

context "when a guess has been made" do
  it "returns the most common letter in the remaining #candidate_words" do
    board = [nil, "e", "e", nil]

    guesser.guess(board) # guesses 'e' and marks it as guessed.
    expect(guesser.guess(board)).to eq("l")
  end
end

Теперь у нас есть доска в таком состоянии, что она знает, что «е» находится в средних 2 позициях, и затем мы говорим ей угадать наиболее распространенную букву, которая все еще «е», потому что guesser не знает, что он догадался (потому что не знает).После этого мы говорим угадать следующую букву, которая на этот раз является «l», и код «HERE2» правильно выводит, что «e» уже угадано (потому что оно есть).

Естьдругие способы исправить это, вам просто нужно убедиться, что processed_most_common вызывается с "e", чтобы исправить проблему, которую вы видите.Но если у вас есть код, проходящий весь процесс угадывания, вы не пропустите ни одного другого шага, который можно было бы ожидать.

...