Head First Ruby - #{10 — num_guesses} error - ruby

Here is book code. And he is not work...
# Get My Number Game
# Written by: you!
puts "Welcome to 'Get My Number!'"
# Получение имени игрока и вывод приветствия.
print "What's your name? "
input = gets
name = input.chomp
puts "Welcome, #{name}!"
# Сохранение случайного числа.
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
puts "You've got #{10 — num_guesses} guesses left."
print "Make a guess: "
guess = gets.to_i
num_guesses += 1
# Сравнение введенного числа с загаданным
# и вывод соответствующего сообщения.
if guess < target
puts "Oops. Your guess was LOW."
elsif guess > target
puts "Oops. Your guess was HIGH."
elsif guess == target
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. (It was #{target}.)"
end
The error:
test.rb:18: syntax error, unexpected tIDENTIFIER, expecting t│ => String
STRING_DEND │2.4.0 :016 > name * 3
puts "You've got #{10 — num_guesses} guesses left."

I'm not sure what that character is between the 10 and the num_guesses but it's probably a hyphen.
#{10 — num_guesses}
it's not a minus sign, which would look like this...
#{10 - num_guesses}
What sort of editor did you use to enter your code?
Anyway, change the hyphen to a minus sign and that will fix your problem.

Related

How to get my number of attempts correct?

Hello all I previously asked how to fix a guessing number game on ruby which I got all done but now the number of attempts or tries is not reflecting nicely. Do I resolve this?
This is the code:
def check(int, r_int)
tries = 0
if int < r_int
tries +=1
puts "Guess Higher"
elsif int > r_int
tries +=1
puts "Guess Lower"
elsif int == r_int
win = true
puts "You are correct"
puts "You had attempted this "+ tries.to_s + " times to win"
abort
end
end
This is the main function:
def main
win = false
puts "Lets play a game!"
puts "I am thinking of a number between 1 and 100"
rnd_int = rand(100)
while not win
guess = gets.chomp.to_i
value = check(guess, rnd_int)
end
end
Overall everything works but the tries at the end of the game remains at 0 not sure where the mistake is.
Perhaps the code could look like following (just a suggestion)
def check(attempts,guess,number)
puts ">>> Attempts [#{attempts}]: guess higher" if guess < number
puts ">>> Attempts [#{attempts}]: guess lower" if guess > number
if guess == number
puts "Winner!!!"
return true
end
return false
end
if __FILE__ == $0
win = false
attempts = 5
puts "
Lets play a game!
I am thinking of a number between 1 and 100
"
number = rand(100)
while not win
print "Your guess: "
guess = gets.chomp.to_i
attempts -= 1
unless attempts
puts "You could not guess right"
exit
end
win = check(attempts, guess, number)
end
end
Output sample
Lets play a game!
I am thinking of a number between 1 and 100
Your guess: 50
>>> Attempts [4]: guess higher
Your guess: 80
>>> Attempts [3]: guess higher
Your guess: 90
>>> Attempts [2]: guess lower
Your guess: 86
Winner!!!
The code could be of following shape
win = false
attempts = 5
puts "
Lets play a game!
I am thinking of a number between 1 and 100
"
number = rand(100)
while not win
print "Your guess: "
guess = gets.chomp.to_i
attempts -= 1
score = guess <=> number
win = true if score == 0
puts "Attempts [#{attempts}]: guess higher" if score < 0
puts "Attempts [#{attempts}]: guess lower" if score > 0
unless attempts > 0
puts "You could not guess it right"
exit
end
end
puts "You are winner!!!"
Utilizing <=> operator the code would be shaped as following
attempts = 5
puts "
Lets play a game!
I am thinking of a number between 1 and 100
"
number = rand(100)
while true
print "Your guess: "
guess = gets.chomp.to_i
attempts -= 1
case guess <=> number
when 0
puts "\n>>> Nice guess, you are winner!!!"
exit
when -1
puts "Attempts [#{attempts}]: guess higher" if attempts > 0
when 1
puts "Attempts [#{attempts}]: guess lower" if attempts > 0
end
unless attempts > 0
puts "\n>>> Sorry, you could not guess it right"
exit
end
end

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
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.
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
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

Ruby exact string match

so I'm teaching myself Ruby, and I made a simple heads or tails game. The user types in 'h' to choose heads and 't' to select tails. Under normal use, everything works fine, but unfortunately if the user types in 'th' they can win every time. How do I only reward exact string matches?
puts "~~~~~ HEADS OR TAILS ~~~~~"
print "Choose: Heads or Tails? (h,t): "
choice = gets.to_s
flip = rand(0..1)
if !choice.match('h') && !choice.match('t')
puts "oops"
elsif flip === 0
puts "The coin flipped as heads!"
puts "You chose: " + choice.to_s
if choice.match('h')
puts "YOU WIN!"
elsif !choice.match('h')
puts "YOU LOSE."
end
elsif flip === 1
puts "The coin flipped as tails"
puts "You chose: " + choice.to_s
if choice.match('t')
puts "YOU WIN!"
elsif !choice.match('t')
puts "YOU LOSE."
end
end
choice.match('t') will be truthy for any string where there is t anywhere in it. Use choice == 't'. Or, if you really want to be using regular expressions, choice.match(/\At\Z/) (match beginning, t and end of the string).
To fix your issue, you can update your code with below changes:
1. Replace match with eql? in the above code. This will perform
case-sensitive string comparisons in the program. In order to
ensure, for case-insensitive comparisons, you can use 'casecmp'
method defined in ruby.
2. Also, you can enhance your code by replacing
to_s with chomp() method it will strip off \r,\n.
Updated code is as follows:
puts "~~~~~ HEADS OR TAILS ~~~~~"
print "Choose: Heads or Tails? (h,t): "
choice = gets.chomp
flip = rand(0..1)
if !choice.eql?('h') && !choice.eql?('t')
puts "oops"
elsif flip === 0
puts "The coin flipped as heads!"
puts "You chose: " + choice
if choice.match('h')
puts "YOU WIN!"
elsif !choice.match('h')
puts "YOU LOSE."
end
elsif flip === 1
puts "The coin flipped as tails"
puts "You chose: " + choice
if choice.match('t')
puts "YOU WIN!"
elsif !choice.match('t')
puts "YOU LOSE."
end
Also, you can refer to the document "http://ruby-doc.org/core-2.2.2/Object.html#method-i-eql-3F".

Program won't output what it's supposed to

I am following tutorial and I can't figure out what I am doing wrong. It's outputting everything up to if down
puts "we are going down the cave" I can't get it to output the else statement or anything afterwards. I am just learning and the answer is probably really simple.
puts("Would you like to go up or down?")
user_input = gets()
down = "cave"
up = "mountain"
if down
puts "we are going down the cave"
else up
puts "we are going up the mountain"
puts("Pick a number between 1 and 100")
LOCATION = "cave"
NUMBER = gets()
if NUMBER == 100
puts "You've achieved enlightment in the #{LOCATION}! Spread joy around the world!"
elsif NUMBER >= 50 > 100
puts "There are #{NUMBER} goblins in the #{LOCATION}. WE MUST FIGHT!"
elsif NUMBER > 20 > 50
puts "There is still hope that we will make it to the #{LOCATION}. before the #{NUMBER} Snufflebums get us!"
else NUMBER <= 20
puts "We have conquered the Goon Squad of the #{LOCATION}.. It only took us #{NUMBER} years!!!"
end
end
down is "cave" and is always 'truthy' so if down is always, always true. You want to be testing the user_input, not the variable down
What I think you want is...
user_input = gets.chomp
# you need the chomp to remove the return character
down = "cave"
up = "mountain"
if user_input == down
puts "we are going down the cave"
elsif user_input == up
puts "we are going up the mountain"
end
# you need the end statement, otherwise everything that follows is part of the "else"
And remove the last end

Ruby script need fix

I'm having a problem with my ruby script. If anyone could help, I'd really appreciate it. The problem is that the number is stuck between 1-2; where 2 is too high and 1 is too low. The guesses should be integers only.
#!/usr/bin/ruby
def highLow(max)
again = "yes"
while again == "yes"
puts "Welcome to the High Low game"
playGame(max)
print "Would you like to play again? (yes/no): "
again = STDIN.gets.chomp
if again == 'no'
puts "Have a nice day, Goodbye"
end
end
end
#This method contains the logic for a single game and call the feedback method.
def playGame(max)
puts "The game gets played now"
puts "I am thinking of a number between 1 and #{max}." #It show what chosen by user
randomNumber = rand(max)+ 1
print "Make your guess: "
guess = STDIN.gets.chomp
feedback(guess, randomNumber)
end
#Start while loop
#Logic for feedback method. It's ganna check the guess if it's high or low.
def feedback(guess, randomNumber)
count = 1
while guess.to_i != randomNumber
count = count + 1
if guess.to_i < randomNumber
print "That's too low. Guess again: "
else
print "That's too high. Guess again: "
end
guess = STDIN.gets.chomp
end
puts "Correct! You guessed the answer in #{count} tries!"
end
highLow(ARGV[0])
Change your last line to this:
highLow(ARGV[0].to_i)
The ARGV array contains all the passed in arguments as strings, so you have to cast it to integer.

Resources