guitarfreak
guitarfreak

Reputation: 89

Handling Ruby Case Statement

I tried to rewrite the "if/else statement" in the following piece of code by replacing it with a "case" statement, and I am deadly stuck with it for a few hours - what am I missing?

puts "Welcome to 'Guess My Number!'"
print "What is your name?"
input = gets
name = input.chomp

puts "Welcome, #{name.upcase!}!"
puts "I've got a random number between 1 and 100!"
puts "Can you guess it?"
target = rand(100) + 1 

num_guesses = 0
guessed_it = false
until num_guesses == 10 || guessed_it
    remaining_guesses = 10 - num_guesses
    puts "You've got #{remaining_guesses.to_s} guesses left!"
    print "Make a guess, put down a number: "
    guess = gets.chomp.to_i
    num_guesses = num_guesses + 1
end

puts case verification
    when guess < target 
        then "Ooops. Your guess was LOW."
    when guess > target
        then "Ooops. Your guess was HIGH."
    when guess < -1 
        then puts "Oooops. You have entered a number lower that 1!"
    when guess > 100
        then puts "Oooops. You have entered a number higher than 100!"
    when guess =~ /^([w])/
        then puts "Ooops. Looks like you have entered a non numeric 
value!"
    when guess == String
        then puts "Oooops! Looks like you have entered a non numeric 
value"

    when guess == target 
        then puts "Good job, #{name}!"  
             puts "You guessed my number in #{num_guesses} guesses!"
             guessed_it = true
end

unless guessed_it
    puts "Sorry, you didn't get my number. My number was #{target}."
end

The "case statement" was used to replace and enhance the logic of the following if else statement:

if guess < target
    puts "Ooops. Your guess was LOW."
 elsif guess > target
  puts "Ooops. Your guess was HIGH."
 elsif guess == target 
  puts "Good job, #{name}!" 
  puts "You guessed my number in #{num_guesses} guesses!"
  guessed_it = true
 end

Upvotes: 1

Views: 131

Answers (3)

guitarfreak
guitarfreak

Reputation: 89

Thanks a lot to everybody! With your invaluable help I managed to regain patience in my soul and satisfaction from this small task :) My mistake is that I violated the rules of common sense by trying to run several pieces of code in a wrong sequence. I moved the case statement inside the until loop and now all I have to do is correct the mistakes in particular when/then statements. It works :)

    until num_guesses == 10 || guessed_it
    remaining_guesses = 10 - num_guesses
    puts "You've got #{remaining_guesses.to_s} guesses left!"
    print "Make a guess, put down a number: "
    guess = gets.chomp.to_i
    num_guesses = num_guesses + 1

        puts case 
        when guess < target 
            then "Ooops. Your guess was LOW."
        when guess > target
            then "Ooops. Your guess was HIGH."
        when guess < -1 
            then puts "Oooops. You have entered a number lower that 1!"
        when guess > 100
            then puts "Oooops. You have entered a number higher than 100!"
        when guess =~ /^([w])/
            then puts "Ooops. Looks like you have entered a non numeric value!"
        when guess == String
            then puts "Oooops! Looks like you have entered a non numeric value"

        when guess == target 
            then puts "Good job, #{name}!"  
                 puts "You guessed my number in #{num_guesses} guesses!"
        guessed_it = true
    end
end

unless guessed_it
    puts "Sorry, you didn't get my number. My number was #{target}."
end

Upvotes: 0

Dan Kreiger
Dan Kreiger

Reputation: 5516

You can use a case statement like so:

class String
  def green;"\e[32m#{self}\e[0m";end
  def yellow;"\e[33m#{self}\e[0m";end
  def cyan;"\e[36m#{self}\e[0m";end
  def bg_blue;"\e[44m#{self}\e[0m";end
  def bold;"\e[1m#{self}\e[22m";end
  def underline;"\e[4m#{self}\e[24m";end
  def border(num);"\n#{'-' * num}\n#{self}\n#{'-' * num}\n";end
end

puts;puts "Welcome to 'Guess My Number!'".bold.bg_blue;puts
print 'What is your name? '.green
name = gets.chomp
puts "\nWelcome, #{name.upcase!}!\n".cyan.underline
puts "I've got a random number between 1 and 100!\nCan you guess it?".border(44)
target = rand(100) + 1

num_guesses = 0
guessed_it = false
until num_guesses == 10 || guessed_it
  remaining_guesses = 10 - num_guesses
  puts "\nYou've got #{remaining_guesses} guesses left!\n"
  puts;print 'Make a guess, put down a number: '
  guess = gets.chomp
  case guess.to_i
  when (1...target)
    puts 'Ooops. Your guess was LOW'.yellow.border(26)
  when (target + 1..100)
    puts 'Ooops. Your guess was HIGH'.yellow.border(26)
  when target
    puts; puts; puts
    puts "Good job, #{name}!".bold.green
    puts 'You guessed my number in ' + "#{num_guesses} guesses!".cyan
    puts; puts; puts
    guessed_it = true
  else
    puts "Oooops. You didn't enter a number from 1 to 100".yellow.border(47); puts
  end

  num_guesses += 1
end

unless guessed_it
  puts;puts;puts "Sorry, you didn't get my number. My number was #{target}.".yellow;puts
end

Upvotes: 0

Nils Landt
Nils Landt

Reputation: 3134

Your problem is that you're using the form of case with the optional condition, but you're using when clauses as if you were using the condition-less case.

puts case
     when guess < target 
       "Ooops. Your guess was LOW."

should work.

Further explanation: using case without a condition, the earliest when branch with a truthy expression is executed. This is what you want here.

But you were using case with verification. In this case, all branches are compared to verification, and the first branch where verification === branch condition is true is executed. Since in your example I'm guessing verification is always nil, and all your branches' conditions are always true or false, no branch will ever get executed.

Upvotes: 2

Related Questions