以某种方式访问​​不同的实例变量

时间:2018-06-05 23:43:58

标签: ruby class instance-variables

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没有正确跟踪我的猜测字母。我把它们印在两个区域。一个在ComputerPlayer#guess中,一个在ComputerPlayer#guess_most_common中。 guess方法使用已经猜到的字母正确打印@guessed_letters数组。 guess_most_common方法总是打印一个空的@guessed_letters数组。怎么可能他们都打印不同的东西?

1 个答案:

答案 0 :(得分:1)

所以你的问题是,在下面的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

原因是你没有告诉任何代码,你已经猜到了“e”,但是(你没有用“e”调用processed_most_common)。你只告诉guesser董事会处于一个状态,即2个中间字母是“e”。

例如,如果我们将测试更改为:

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

现在,我们让董事会处于一个状态,让它知道“e”位于中间2个位置,然后我们告诉它猜测最常见的字母,这仍然是“e”因为{{ 1}}不知道它猜对了(因为它没有)。在那之后,我们告诉它猜测下一个字母,这次是“l”,并且“HERE2”代码正确地输出“e”已经猜到了(因为它已经有了)。

还有其他方法可以解决此问题,您只需要确保使用“e”调用guesser,以解决您所看到的问题。但是如果你让代码完成了整个猜测过程,那么你最终就不会错过任何可能预期的步骤。