简体   繁体   中英

display each character of a string as an underscore with a space between each underscore ruby

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM