My Longsword is broken

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

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

On Monday 14 April 2008, Ben G. wrote:

attr_accessor(:realDam)

6
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

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

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

On Mon, Apr 14, 2008 at 10:08 AM, Ben G. [email protected]

On Apr 14, 1:08 pm, Ben G. [email protected] wrote:

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

On Tue, Apr 15, 2008 at 02:08:42AM +0900, Ben G. wrote:

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()

Though there might be easier solutions…

On Mon, Apr 14, 2008 at 4:43 PM, Aaron P.
[email protected] wrote:

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

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

~ j.