Random number generator doesn't seem to save number - ruby

My RNG guessing game seems to generate a new number constantly, and not save the number for the current session of the game for the player to guess.
def initialize
##answer = rand(1..100).to_s
end
def answer
##answer
end
def guessing
puts "What's your guess?"
##guess = gets.chomp.downcase
while ##guess != answer
wrong_answer
end
right_answer
end

I don't see any problem with your code, but it could be the way are initializing the class (if you are calling guessing explicitly everytime you want to make a guess).
You need to store the initialized class in a variable:
guess = Guess.new
guess.guessing
guess.guessing
Also you don't want to use class instance variables unless necessary i.e, use #guess, #answer instead of ##guess and ##answer.
Another way
def guessing
puts "What's your guess?"
#guess = gets.chomp.downcase
while #guess != answer
puts "wrong_answer"
#guess = gets.chomp.downcase
end
puts "right_answer"
end

I think if you store the random number in an attr_reader, you can then reference it and compare it to the guess. If you store the guess in an attr_accessor, you can compare the guess to the stored random number and have the User continue the game by updating their guess until it matches the random number. I can include an example that you can copy and paste right into IRB. To start the game just call PlayGame.new and you are off and running. Enter cheat for the random number and hint for a hint.
class RandomNumber
attr_reader :number
def initialize
#number = rand(1..100).to_s
end
def hint
random_number = number.to_i
puts case
when random_number >= 75
"Your number is in the range of 75 to 100"
when random_number >= 50
"Your number is in the range of 50 to 74."
when random_number >= 25
"Your number is in the range of 25 to 49"
else random_number > 0
"Your number is 24 or less."
end
end
end
class PlayGame
attr_accessor :input
attr_reader :number
def initialize
#generate_number = RandomNumber.new
#number = #generate_number.number
puts "What's your guess?"
#input = gets.chomp.downcase
validate
end
def validate
case
when input == number
puts "You win!"
when input == "cheat"
puts "The number is #{number}"
get_guess
when input == "hint"
#generate_number.hint
get_guess
else
get_guess
end
end
def get_guess
puts "Try again, what's your guess?"
#input = gets.chomp.downcase
validate
end
end

Related

Can't use include? with an instance variable in a method

I am trying to use 'gets' to get input and then check to see if the instance variable includes the input inside of a method but I can't get it work. Here is the code:
class Game
attr_accessor :available_moves
def initialize
#available_moves = ["0","1","2","3","4","5","6","7","8"]
end
def play_game
puts ("Welcome")
while true
puts "Player 1, choose a square"
player1_choice = gets
# v this is what I can't get to work v
if #available_moves.include?(player1_choice)
puts "yes"
break
else
puts "no"
end
end
end
end
game1 = Game.new
game1.play_game
No matter what I try, the 'else' condition is met and "no" is printed.
When the user inputs text with gets they press Enter, which sends a newline. You need to remove the newline with gets.chomp:
class Game
attr_accessor :available_moves
def initialize
#available_moves = ["0","1","2","3","4","5","6","7","8"]
end
def play_game
puts ("Welcome")
while true
puts "Player 1, choose a square"
# Note the .chomp here to remove the newline that the user inputs
player1_choice = gets.chomp
# v this is what I can't get to work v
if #available_moves.include?(player1_choice)
puts "yes"
break
else
puts "no"
end
end
end
end
game1 = Game.new
game1.play_game
Now you get:
game1.play_game
Welcome
Player 1, choose a square
1
yes
=> nil
See How does gets and gets.chomp in ruby work? for a more in-depth explanation.

How i can solve this issue ? undefined method for class

Have a problem, when run a code allways have error.
Expect: for the user add win or reduce his balance.
undefined method `balance=' for #<Dice:0x0000563d4d4dfd88 #name="foo", #balance=600, #bet=300>
Did you mean? balance
(repl):22:in `increase_decrease_cash'
(repl):62:in `<class:Game>'
(repl):29:in `<main>'
This error always comes out, retried everything I could guess, but nothing came of it and I don’t understand how it can be googled
class Dice
attr_accessor :name, :bet
attr_reader :balance
def initialize(name, balance, bet)
#name = name
#balance = balance
#bet = bet
end
def self.roll
#roll_dice = rand(1..2)
end
def self.check_bet
if #player.bet > #player.balance
puts "Enter number from 1 to #{#player.balance}"
end
end
def self.increase_decrease_cash
if #roll == #my_number
#player.balance += #player.bet
else
#player.balance -= #player.bet
end
end
end
class Game < Dice
#player = Dice.new("foo", 600, 0)
puts "Hello #{#player.name} your balance is: #{#player.balance}"
puts "Bones throwing count times"
a = 2 #gets.chomp.to_i
while a > 0 do
puts ""
puts "Enter your bet !!!"
# PLAYER BET
#player.bet = 300 #gets.chomp.to_i
check_bet
puts "Respected #{#player.name} your bet is: #{#player.bet}"
puts "Now select number 1-2"
# BONES ROLL
#my_number = roll # gets.chomp.to_i
puts "###################"
puts "Now we throw bones"
#roll = roll
puts "Nuber is #{roll}"
if #roll == #my_number
puts "Your win, you get #{#player.bet}"
else
puts "You lose #{#player.bet}"
end
p "$$$$"
p #player.balance
p "$$$$"
a -= 1
increase_decrease_cash
end
end
This error always comes out, retried everything I could guess, but nothing came of it and I don’t understand how it can be googled
attr_reader creates only the get method for balance. You need both get and set method for balance. Because you set balance in the initialize method. So, you should use attr_accessor instead of attr_reader.
attr_accessor :balance

Ruby labeling printed outputs

I'm writing a short program that asks a user to enter a car model, maker, and year input and it passes that input through an algorithm. My question is, is there a way to label multiple printed outputs after it has been put through the formula to where it will number each output? Would I have to use a for each loop? I'm just trying to get a general idea of how I would accomplish this.
say for example the printed output would look like this.
class Car
attr_reader :make, :model, :year
def initialize
end
def set_make(make)
#make = make
end
def set_model(model)
#model = model
end
def set_year(year)
#year = year
end
def get_make
#make
end
def get_year
#year
end
def get_model
#model
end
end
array_of_cars = Array.new
print "How many cars do you want to create? "
num_cars = gets.to_i
for i in 1..num_cars
puts
print "Enter make for car #{i}: "
make = gets.chomp
print "Enter model for car #{i}: "
model = gets.chomp
print "Enter year of car #{i}: "
year = gets.to_i
c = Car.new
c.set_make(make)
c.set_model(model)
c.set_year(year)
array_of_cars << c
end
puts
puts "You have the following cars: "
puts
for car in array_of_cars
puts "#{car.get_year} #{car.get_make} #{car.get_model}"
end
puts
2014 Ford Expedition
2017 Toyota 86
2017 Aston Martin DB11
is there a way to add those numbers to the output?
Instead using a for loop you could try using each_with_index, which will allow you to get each element inside the array_of_cars and also the index for each element, in this case adding 1 to the current index will give you the value starting from 1:
array_of_cars.each_with_index do |car, index|
puts "#{index + 1}. #{car.get_year} #{car.get_make} #{car.get_model}"
end
Or you can use each and with_index passing the first element, in this case 1 as argument:
array_of_cars.each.with_index(1) do |car, index|
puts "#{index}. #{car.get_year} #{car.get_make} #{car.get_model}"
end
You don't need so many methods. Use attr_accessor to set getters and setters and utilize initialize better. Then using the basic idea from this answer by tadman, we can collect newly made objects into an array within the class itself. All together we can compress your class to:
class Car
attr_accessor :make, :model, :year
def self.all
#all ||= []
end
def initialize(make, model, year)
#make = make
#model = model
#year = year
Car.all << self
end
end
We can use times to run a piece of code n times.
puts "How many cars do you want to create? "
n = gets.to_i
n.times.with_index(1) { |_,i|
puts "Enter make for car #{i}"
make = gets.chomp
puts "Enter model for car #{i}: "
model = gets.chomp
puts "Enter year of car #{i}: "
year = gets.to_i
puts
Car.new(make, model, year)
}
Then as Sebastián Palma has already suggested, use each.with_index(1) to print your cars. The argument offsets the index by 1.
Car.all.each.with_index(1) { |c, i| puts "#{i}. #{c.year} #{c.make} #{c.make}" }
Sidenotes: 1. Avoid using for loops in Ruby 2. Use puts not print.

Ruby program help (ATM program)

I'm a newb Ruby user using Ruby version 2.1.5p273 and below I created an Atm simulator program that takes user input of deposits and withdrawals, and then it displays the balance after. I am struggling with ifs, elses and loops. I want to put a decision making statement in the beginning, that asks if the user wants to withdraw, deposit, check balance, or end your session. I also want to put a decision making statement in the end, that asks if the user wants to continue (which would go back to the beginning, or end the session). My general idea of what I want it to look like would be below, the overall program is below the idea code. I know it's wrong but it's just what I want it to look like, so any help in making it into correct and working code would be greatly appreciated.
print "Would you like to (w)ithdraw, (d)eposit, or (c)heck your balance or (e)nd your session?
if "(w)ithdraw" # i'd like to make this do a "press w for withdraw"
bank_account.withdraw
elsif "(d)eposit" # i'd like to make this do a "press d for deposit"
bank_account.deposit
elsif "(c)heck your balance" # i'd like to make this do a "press c to check your balance"
bank_account.show_balance
elseif "(e)nd your session" # i'd like to make this do a "press e to end your session"
end
#This program is an ATM simulator, it takes user input of deposits and withdrawals, and then displays the balance after.
class BankAccount
def initialize(name)
#transations = []
#balance = 0
end
def deposit
print "How much would you like to deposit? "
amount = gets.chomp
#balance += amount.to_f
puts "$#{amount} deposited."
end
def withdraw
print "How much would you like to withdraw?"
amount = gets.chomp
#balance -= amount.to_f
puts "#{amount} withdrawn"
end
def show_balance
puts "Your balance is #{#balance}"
end
end
bank_account = BankAccount.new("Justin G")
bank_account.class # => BankAccount
print "Welcome to Jay's ATM!\n"
bank_account.deposit
bank_account.show_balance
bank_account.withdraw
`enter code here`bank_account.show_balance
puts "Thank you"
This is fairly rudimentary but should get you started. Please let me know if you have additional questions on what I'm doing in the code. For the most part it should be fairly self-explanatory if you're familiar with other object-oriented programming languages.
Here's your ATM:
# atm.rb
require './bank_account.rb'
cmd = ""
account = BankAccount.new("Justin G")
puts "***Welcome to #{account.name}'s ATM***\n\n"
while cmd != "e" do
puts "Would you like to (w)ithdraw, (d)eposit or (c)heck your balance?"
puts "You can also (e)nd your session."
cmd = gets.chomp
case cmd
when "w"
puts "How much would you like to withdraw?"
amount = gets.chomp # expect this to be a float
# handle incorrect input somehow, either here or
# preferably in the BankAccount#withdraw method
account.withdraw(amount)
when "d"
puts "How much would you like to deposit?"
amount = gets.chomp # expect this to be a float
# handle incorrect input somehow, either here or
# preferably in the BankAccount#deposit method
account.deposit(amount)
when "c"
puts "Your balance is $%.2f\n" % account.balance
else
# didn't understand the command
puts "Didn't understand your command. Try again." unless cmd == "e"
end
end
Here's the bank account code:
# bank_account.rb
class BankAccount
attr_reader :name, :balance
def initialize(name)
#name = name
#transactions = []
#balance = 0.0
end
def withdraw(amount)
# TODO: check that amount is valid, else error
#balance -= amount.to_f
# TODO: check if sufficient funds available
puts "$%.2f successfully withdrawn.\n" % amount
end
def deposit(amount)
# TODO: check that amount is valid, else error
#balance += amount.to_f
puts "$%.2f successfully deposited.\n" % amount
end
end

Outputting correct object attribute based on user input from an array of objects in Ruby

I have created an array of objects containing information on the Oscars using a text file with all the category names, winners and nominees (winners appear in nominees list as well). I now want to be able to ask a user. Of which category would you like to know the winner? Once the question is asked it would return the answer. I can only get it to work on the last object of the array(best visual effects returns gravity). Can someone explain why this is happening?
class AwardCategory
attr_accessor :winner, :name, :nominees
def initialize(name)
#name = name
#nominees = []
end
end
class Nominee
attr_accessor :name
def initialize(name)
#name = name
end
end
file = File.open('oscar_noms.txt', 'r')
oscars = []
begin
while true do
award_category = AwardCategory.new(file.readline.downcase)
award_category.winner = file.readline.downcase
nominee = Nominee.new(file.readline.downcase)
award_category.nominees << nominee
next_nominee = Nominee.new(file.readline.downcase)
until next_nominee.name == "\n"
award_category.nominees << next_nominee
next_nominee = Nominee.new(file.readline.downcase)
end
oscars << award_category
end
rescue EOFError => e
puts 'rescued'
end
#puts oscars.inspect
#Read input here
puts "What category do you want to know the winner for?"
answer = gets
oscars.each
if answer.downcase == award_category.name
puts award_category.winner
else
puts "That is not a category"
end
That piece of code
puts "What category do you want to know the winner for?"
answer = gets
oscars.each
if answer.downcase == award_category.name
puts award_category.winner
else
puts "That is not a category"
end
Now with correct indentation
puts "What category do you want to know the winner for?"
answer = gets
oscars.each
if answer.downcase == award_category.name
puts award_category.winner
else
puts "That is not a category"
end
Note that the part below oscars.each is not indented, because each needs a do/end block which it will execute once for every element. What you probably want is this
puts "What category do you want to know the winner for?"
answer = gets
oscars.each do |award_category|
if answer.downcase == award_category.name
puts award_category.winner
else
puts "That is not a category"
end
end
Although I suggest you leave off the else, because you will get the message "That is not a category" for every answer that did not match. Also, you should use gets.chomp to remove the newline from the user input and do downcase outside of the each loop. As a last note, some of your variables are poorly named. For example, why should a list of award categories be named oscars? It should be award_categories instead.

Resources