I am trying to create a word guessing game which takes a string as an input. I have found it very difficult trying to display each character of the string as an underscore with spaces between them. For example the word "cookie" to be displayed as _ _ _ _ _ _
each underscore representing each character of the string. I have tried using scan and tr but haven't been able to get it to work. I have the following code:
class Game
attr_reader :word
attr_accessor :guess_counts
def initialize(word)
@word = word
end
def guesses_available
@guess_counts = @word.length
end
def display
print @word.tr_s('a-z','_ ')
end
end
# user interface
puts "Please enter a word to initialize the Guessing The Word game"
secret_word = gets.chomp
game = Game.new(secret_word)
puts "you have #{@guess_counts} attemps left"
game.display
Since you do not care about the actual characters, but want to present every character as a _
, I would do something like this:
Array.new("cookie".length, '_').join(' ')
#=> "_ _ _ _ _ _"
Or:
('_' * "cookie".length).split(//).join(' ')
#=> "_ _ _ _ _ _"
Replace "cookie"
with your string variable...
I'm assuming you will eventually want to store the user's guesses and display only the letters they've guessed. Try this:
guesses = [] #letters guessed go into this array
@word.chars.map { |c| guesses.include?(c) ? c : '_' }.join(' ')
If you're just trying to display underscores for each letter without any additional logic, you can do this:
@word.chars.map { |c| '_' }.join(' ')
If you want to act on a single letter guessed by the user, you can do this:
letter = 'a' #or whatever letter you get from the user
@word.chars.map { |c| letter == c ? '-' : '_' }.join(' ')
Here's a simple but fully functional hangman example based on the first code snippet. Basically all i'm doing is running the first snippet in a loop and getting user input each time, doing a little bit of logic to see if they guessed the right letter, and keeping track of how many tries are left.
@word = 'boop'
guesses = [] #letters guessed go into this array
tries = 5
while tries > 0
guess = gets[0]
if !@word.include? guess
puts "wrong."
tries -= 1
next
end
guesses << guess
display = @word.chars.map { |c| guesses.include?(c) ? c : '_' }.join(' ')
puts display
if !display.include? '_'
puts 'you win!'
break
end
end
You're on the right track with tr
but you need to use the inversion operator ^
to not flip the guesses that match. Here's the core function you need:
def underscored(word, guesses)
word.tr('^' + guesses, '_').chars.join(' ')
end
For example:
underscored('transistor', 'aebr')
# => "_ r a _ _ _ _ _ _ r"
If you append each guessed letter to a string, like guesses << guess
then it works quite neatly with tr
. Remember a string is fundamentally an array of characters, so don't bother making an explicit array for such things.
如果您想跟踪@guess_counts,我会考虑将其初始化并在每个计数后添加一个,并在告诉他们有多少初始猜测时仅调用game.guesses_available。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.