My Longsword is broken.

B

Ben Galyean

Hello all,

Just started my first Ruby prog and hit a snag almost instantly. I
simply wish to have my selected weapon do it's prescribed damage as I
intend (in this case, it's 1-8 damage). Complete noob here so any help
at all would be greatly appreciated. The following is a re-creation of
my problem:

#***********************************
class Sword
attr_accessor:)realDam)

def initialize(aRealDam)
@realDam = aRealDam
end
end

Longsword = Sword.new(rand(8)+1)
weapon = Longsword

begin

5.times {p weapon.realDam}
puts
5.times {p (rand(8)+1)}

end
#*************************************

Output looks like this:

#****Current Longsword damage (Picks a number and 'keeps' it).****
6
6
6
6
6

#****Intended output for the longsword here****
6
8
8
4
8
 
G

Gerardo Santana Gómez Garrido

class Sword
def initialize(&block)
@damage = block
end

def realDam
@damage.call
end
end

Longsword = Sword.new { rand(8)+1 }
weapon = Longsword

5.times {p weapon.realDam}
puts
5.times {p(rand(8)+1)}

------- output --------
3
2
1
4
8

1
5
4
1
5
 
S

Stefano Crocco

Hello all,

Just started my first Ruby prog and hit a snag almost instantly. I
simply wish to have my selected weapon do it's prescribed damage as I
intend (in this case, it's 1-8 damage). Complete noob here so any help
at all would be greatly appreciated. The following is a re-creation of
my problem:

#***********************************
class Sword
attr_accessor:)realDam)

def initialize(aRealDam)
@realDam = aRealDam
end
end

Longsword = Sword.new(rand(8)+1)
weapon = Longsword

begin

5.times {p weapon.realDam}
puts
5.times {p (rand(8)+1)}

end
#*************************************

Output looks like this:

#****Current Longsword damage (Picks a number and 'keeps' it).****
6
6
6
6
6

#****Intended output for the longsword here****
6
8
8
4
8

When you write:

Longsword = Sword.new(rand(8)+1), you're setting the @realDam attribute to the
return value of rand(8)+1. To do what you want, you should pass to the
constructor (that is, initialize) the maximum damage, then call rand in the
realDam method. Of course, this means that you shouldn't create the realDam
method using attr_accessor, but write it by hand. For example:

class Sword
def initialize max_dam
@max_dam = max_dam
end

def real_dam
rand(@max_dam)+1
end
end

weapon = Sword.new(8)
5.times{p weapon.real_dam}

This should produce 5 random values between 1 and 8.

By the way, are you sure it is right to assign to the constant LongSword an
instance of class Sword? Of course, I can't know how your application is
structured, but I think that both Sword and LongSword should be classes,
representing the generic sword or long sword, maybe with LongSword inheriting
from Sword. Your code, in my opinion, can create confusion, since it creates
two constants, each with the name of a weapon, but with very different
behaviour: one, Sword, represents the 'abstract' sword, while the other
(LongSword) is a 'concrete' weapon. This difference has very practical
consequences, of course: you can't call the realDam method on Sword, but you
can on LongSword.

Stefano
 
M

Martin Voigt

Hi Ben,

if I understand it correctly, your program shows completely normal
behavior: you instantiate your Sword class and assign a number to
@realDam and then just read this variable 5 times. What you might want
is this:

class Sword
def intialize(maxDam)
@maxDam = maxDam
end
def realDam
return rand(@maxDam) + 1
end
end

So everytime you access sword_instance.realDam you get a freshly
calculated random number which is never higher than @maxDam. Since
everything is a method call in ruby (even accessing an instance
variable), there is no need to declare one (in your special case
however), the realDam method behaves like a getter.

Hope that helps,
Martin
 
S

Shawn Anderson

[Note: parts of this message were removed to make it a legal post.]

A few ruby basics:
foo_bar is a variable name (all lowercase separated by underscores)
FOO_BAR is a constant (all caps separated by underscore)
FooBar is a class or module (starts with cap and is bumpy case)

So:
Longsword = Sword.new(rand(8)+1)
is a little funky.

Secondly,
The ...

Apparently, I type too slow and Gerardo has finished my work for me.
Hope that helps.

/Shawn
 
C

Chris Hulan

Hello all,

#***********************************
class Sword
attr_accessor:)realDam)

def initialize(aRealDam)
@realDam = aRealDam
end
end

Longsword = Sword.new(rand(8)+1)

Here you generate a value that gets stored
try:

class Sword
def initialize(maxDamage, modifier)
@maxDamage, @modifier = maxDamage, modifier
end

def hitDamage()
return rand(@maxDamage)+1 + @modifier
end
end

not tested, but should be close

cheers
Chris
 
A

Aaron Patterson

Hello all,

Just started my first Ruby prog and hit a snag almost instantly. I
simply wish to have my selected weapon do it's prescribed damage as I
intend (in this case, it's 1-8 damage). Complete noob here so any help
at all would be greatly appreciated. The following is a re-creation of
my problem:

Sometimes to fix your longsword, you must adjust your johnson:

require 'johnson'

ctx = Johnson::Context.new
ctx[:ruby_rand] = lambda { |x| rand(x) }
ctx.evaluate(<<-END
var LongSword = {
realDamage: function() {
return ruby_rand(this.maxDamage);
}
}
END
)
ctx[:LongSword].maxDamage = 8
puts ctx[:LongSword].realDamage()

http://github.com/jbarnette/johnson/tree/master

Though there might be easier solutions......
 
J

John Barnette

Sometimes to fix your longsword, you must adjust your johnson:

require "johnson"
Johnson.evaluate("Math.floor(max * Math.random() + 1)", :max => 8)


~ j.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,290
Messages
2,571,454
Members
48,131
Latest member
AntoniaSep

Latest Threads

Top