I wrote a program to simulate the rolling of polyhedral dice but every time I run it I get the error shown below. It displays my prompts and lets me input my numbers, but after that it screws up. I've been trying to find a fix online but I only find people talking about different problems with the times method being undefined. I'm new to Ruby, so any help would be appreciated.
My program:
p = 0
while p < 1
puts "Choose your die type"
die_type = gets.chomp
puts "Choose your number of die"
die_number = gets.chomp
total = 0
i = 1
die_number.times do
random_int = 1 + rand(die_type)
total += random_int
i += 1
end
puts total
end
The error I get:
/dieroll.rb:13: undefined method 'times' for "5":String (NoMethodError)
Change die_number = gets.chomp to die_number = gets.to_i. die_number = gets.chomp, assigns a string to the local variable die_number( Because Kernel#gets gives us a string object). String don't have any method called #times, rather Fixnum class has that method.
Change also die_type = gets.chomp to die_type = gets.to_i, to avoid the next error waiting for you, once you will fix the first one.
1.respond_to?(:times) # => true
"1".respond_to?(:times) # => false
In you case die_number was "5", thus your attempt "5".times raised the error as undefined method 'times' for "5":String (NoMethodError).
Related
So I've been messing around with Ruby for the first time after finishing the codecademy course up to "Object Oriented Programming, Part I" and I decided to start making a calculator. For some reason though, I get this error:
calc.rb:13:in `addition': undefined local variable or method `user_input' for main:Object (NameError)
from calc.rb:21:in `<main>'
I'm confused why it doesn't see my "user_input" array. Is it out of the scope of the method? Did I initialize it wrong?
Here's the code so you can see for yourself, it's obviously nothing sophisticated and it's not finished. I'm just trying to test for addition right now.
#!/usr/bin/env ruby
user_input = Array.new
puts "Would you like to [a]dd, [s]ubtract, [m]ultiply, or [d]ivide? "
type_of_math = gets.chomp
def addition
operator = :+
puts "Please enter the numbers you want to add (enter \"=\" to stop adding numbers): "
until gets.chomp == "="
user_input << gets.chomp.to_i
end
sum = user_input.inject(operator)
return sum
end
case type_of_math
when "a"
addition
when "s"
puts "Test for subtraction"
when "m"
puts "Test for multiplication"
when "d"
puts "Test for division"
else
puts "Wrong"
end
Consider this untested variation on your code. It's more idiomatic:
def addition
user_input = []
puts 'Please enter the numbers you want to add (enter "=" to stop adding numbers): '
loop do
input = gets.chomp
break if input == '='
user_input << input
end
user_input.map(&:to_i).inject(:+)
end
Notice that it puts user_input into the method. It also uses the normal [] direct assignment of an empty array to initialize it. Rather than chomp.to_i each value as it's entered it waits to do that until after the loop exits.
Instead of while loops, consider using loop do. They tend to be more easily seen when scanning code.
Also notice there's no return at the end of the method. Ruby automatically returns the last value seen.
Hello I'm new to programming and I started with ruby. I'm trying to do my first program. I found online this code that generate a dice roll
class Die
def initialize(sides)
#sides = sides
end
def generate_die_roll
rand(#sides) + 1
end
def roll(number=1)
roll_array = []
number.times do
roll_array << generate_die_roll
end
total = 0
roll_array.each do |roll|
new_total = total + roll
total = new_total
end
total
end
end
and I would like to use in they way that if the number generated is inferior o equal to another print something otherwise something else.
It's probably very easy but i'm trying in every way and now I will need some help please.
that's my code:
require "./newdado.rb"
energia_vitale = 30
puts "Lancia un dado scrivendo (D) da sommare alla tua Energia Vitale iniziale di #{energia_vitale} punti"
scelta = gets.chomp
case scelta
when "D"
SIX_SIDED_DIE = "#{Die.new(6)}"
values = Array[]
values.push(SIX_SIDED_DIE.roll)
puts values
if values < 2
puts "c"
else puts "b"
end
end
when I run it i receive this error
C:/Users/fix/workspace/D&D Ruby/energia vitale.rb:11:in <main>': undefined methodroll' for "#":String (NoMethodError)
Sorry to bother the community with this beginner problem
Why as string?
this line
SIX_SIDED_DIE = "#{Die.new(6)}"`
should be something like
die = Die.new(6)
then you can do die.roll
I'm doing level 2 of ruby warrior on intermediate and every time I run this I get this error even though it doesn't seem I should. I am very new to ruby so I'd appreciate it if someone could tell me why this is happening even though I'm passing warrior for glance and glance has 1 slot for a variable to
here's the error:
wrong number of arguments (1 for 0)
Player.rb:24:in `glance'
Player.rb:6:in `play_turn'
here's my code:
class Player
def play_turn(warrior)
#warrior = warrior
glance(warrior)
actions
end
def actions
#warrior = warrior
glance(warrior)
if rightempty
warrior.walk!(:right)
elsif forwardenemy && rightempty == false
warrior.fight!
else
warrior.walk!(warrior.direction_of_stairs)
end
end
def glance(warrior)
#wariror = warrior
forwardempty = warrior.feel.empty?(:forward)
leftempty = warrior.feel.empty?(:left)
rightempty = warrior.feel.empty?(:right)
backwardempty = warrior.feel.empty?(:backward)
forwardenemy = warrior.feel.enemy?(:forward)
leftenemy = warrior.feel.enemy?(:left)
rightenemy = warrior.feel.enemy?(:right)
backwardenemy = warrior.feel.enemy?(:backward)
forwardcaptive = warrior.feel.captive?(:forward)
leftcaptive = warrior.feel.captive?(:left)
rightcaptive = warrior.feel.captive?(:right)
backwardenemy = warrior.feel.captive?(:backward)
end
end
The issue is not with the number of arguments being passed to glance, it's what's happening within that method.
You're calling empty? with one argument e.g. :forward when it doesn't take any - hence the error "1 for 0"
So, I made a hash called "facing". I call a case statement after, where I want to subtract 1 from the value if the user types L, or (I didn't get here yet) add 1 if the input = 'R'.
class Rover
attr_accessor :orientation
end
#facing = Hash.new
facing = {
0 => 0
}
bot = Rover.new
bot.orientation = "N"
puts "Bot's current orientation is: " + bot.orientation
puts "What direction to turn ('L' or 'R')?"
input = gets.chomp.to_s.capitalize
case input
when input = 'L'
facing do |key, value|
value - 1
end
end
The problem is that I get a method undefined (facing) error message. What am I doing wrong?
Have a look at the documentation for case.
This statement: input = 'L' means "give the variable input the value 'L'", not "check if it equals 'L'".
But that's not where your error is coming from. With facing do... You're giving a block to a hash, which is confusing the compiler and causing it to look for a facing method.
What exactly are you trying to do with the hash?
I'm having difficulty running the following. I get the following error
"': undefined method `name' for nil:NilClass (NoMethodError)"
at the
puts shopper[i].name
line
As if sometimes the object hasn't been created by the time it gets to that line
(0 .. 9).each do |i|
shopper[i] = Shopper.new("Shopper Number-#{i}")
(0 .. 19).each do |j|
r = rand(0 .. (k-1))
if shopper[i].unsuccessful_shopping_trip == true
puts "#{shopper[i].name} has failed to buy 3 times and has decided to go home"
i += 1
break
else
if shopper[i].add_product(shop.remove_product_bought_by_shopper(r)) == false
puts "#{shopper[i].name} has tried to buy #{(shop.products[r]).name} but it is sold out"
j -= 1
else
puts "#{shopper[i].name} has bought #{(shop.products[r]).name}"
end
end
end
puts shopper[i].name
puts shopper[i].shopping_list
total_shopper_net += shopper[i].total_net_value
total_shopper_gross += shopper[i].how_much_spent
total_shopper_product_count += shopper[i].total_product_count
end
Can anyone explain this?
You are manually incrementing i within the each iterator. Any subsequent reference to shopper[i] does not yet exist, since shoppers are created only at the top of the loop.