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
Sorry if this is crappy format but I am working on a Hangman Project but got stuck. I am trying to make the ComputerPlayer guess the most common letter. After it guesses the most common letter, it will guess the next most common letter and so fourth.
I've made a @guessed_letters = [] to keep track of the letters I've already guessed so I wont count it the next time the computer guesses a letter.
Problem is that @guessed_letter does not keep track of my guessed letters correctly. I printed them in 2 areas. One in class ComputerPlayer#guess and one in ComputerPlayer#guess_most_common. The guess method prints @guessed_letters array correctly with the letters already guessed. guess_most_common method always prints a empty @guessed_letters array. How is that possible that they're both printing different things?