Question

My goal is to create a game of hangman. I wrote code similar to this:

c = []
players_guess = gets
b = "example"
b.scan(/./) {|letter| c << letter}

c.each do |letter|
  if letter == players_guess
    puts letter
  else
    puts "*"
  end
end  

The code checks if the player guessed the right letter from the password hidden in variable c, and then displays the password hidden behind the *s and only revealed guessed letters. But when I run the program, the result is always the same, it displays players_guess, and then gives seven *. What is wrong here?

Was it helpful?

Solution

Here's a simple way to do what you want:

word = "example"
puts "Type a letter: "
guess = gets.chomp
puts word.tr("^#{guess}", "*")

This uses the String#tr method to replace all but the guess to *.

The output if you typed e would be e*****e.

OTHER TIPS

Your If/Then Logic is Wrong

Your code is as follows:

c.each do |letter|
  if letter == players_guess
    puts letter
  else
    puts "*"
  end
end

The conditional will generally be false, since no single letter is likely to match the entire line retrieved by gets. As a result, you get an asterisk printed for each letter in c.

Some Options to Fix Your Code

You can do a couple of things here.

  1. Just show the string if the strings are equal.

    puts players_guess if b == players_guess.chomp
    
  2. Use a counter in your loop to index into your arrays or strings.

  3. Split both strings into an array, and compare the arrays, printing letters that match or an asterisk on a non-match.

    c.each_with_index do |char, idx|
      puts char == players_guess.scan(/./)[idx] ? char : '*'
    end
    
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top