Reputation: 9
I'm building a hangman game and I have no idea how to replace underscores in hidden_word (String) with matching letters in player_input (Array). Any ideas what I should do? Thank you in advance, I appreciate it!
def update
if @the_word.chars.any? do |letter|
@player_input.include?(letter.downcase)
end
puts "updated hidden word" #how to replace underscores?
end
puts @hidden_word
puts "You have #{@attempts_left-1} attempts left."
end
I have two Strings, the_word and hidden_word, and an Array, player_input. Whenever the player selects a letter which matches with the_word, the hidden_word should update.
For example
the_word = "RUBY"
hidden_word = "_ _ _ _"
Player chooses "g", hidden_word still "_ _ _ _"
Player chooses "r", hidden_word updates "R _ _ _"
Here's the rest of the code:
class Game
attr_reader :the_word
def initialize
@the_word = random_word.upcase
@player_input = Array.new
@attempts_left = 10
end
def random_word
@the_word = File.readlines("../5desk.txt").sample.strip()
end
def hide_the_word
@hidden_word = "_" * @the_word.size
puts "Can you find out this word? #{@hidden_word}"
puts "You have #{@attempts_left} attempts left."
puts @the_word #delete this
end
def update
if @the_word.chars.any? do |letter|
@player_input.include?(letter.downcase)
end
puts "updated hidden word" #how to replace underscores?
end
puts @hidden_word
puts "You have #{@attempts_left-1} attempts left."
end
def guess_a_letter
@player_input << gets.chomp
puts "All the letters you have guessed: #{@player_input}"
end
def has_won?
if !@hidden_word.include?("_") || @player_input.include?(@the_word.downcase)
puts "You won!"
elsif @attempts_left == 0
puts "You lost..."
end
end
def game_round #the loop need fixin
puts "Let's play hangman!"
hide_the_word
while @attempts_left > 0
guess_a_letter
update
@attempts_left -= 1 #fix this
has_won?
break if @player_input.include?("q") #delete this
end
end
end
new_game = Game.new
new_game.game_round
Upvotes: 0
Views: 283
Reputation: 323
One option is to use a regular expression:
@hidden_word = @the_word.gsub(/[^#{@player_input.join('')}\s]/i, '_')
Upvotes: 0
Reputation: 15517
I don't sure about downcase
because you have used uppercase
too.
Choose only one letter case.
But it will work for you:
def update
@the_word.each_char.with_index do |letter, index|
@hidden_word[index] = letter if @player_input.include?(letter.downcase)
end
puts @hidden_word
puts "You have #{@attempts_left-1} attempts left."
end
It compares each letter of secret word with user's inputs and changes underscore in hidden word by coincidence.
Here I used String#each_char
, String#[]=
, Enumerator#with_index
Upvotes: 0
Reputation: 10054
Here's some code that should get you going. Collect the guessed letters in an array. Then, map the chars of the word to either the char if it was guessed or an underscore.
word = "RHUBARB"
guessed_letters = ['A', 'R', 'U']
hidden_word = word.chars.map { |c| guessed_letters.include?(c) ? c : '_' }.join
# => "R_U_AR_"
Upvotes: 1