06 Jan, 2009, Chris Bailey wrote in the 1st comment:
Votes: 0
So I have this god awful ugly way of equipping items right now, I think it could be better. The real problem comes down to the way I am searching the array, but any revisions to the system itself would be more than appreciated.

Here is our basic item class, it's very simple right now but it keeps track of whether or not an item is equipped.
class Item
@@count = 0
attr_accessor :name, :weight, :item_id

def initialize(name='New Item')
@name = name
@weight = 0
@item_id = @@count
@equipped = false

@@count += 1
end

def equipped?
@equipped
end

def equip
if @equipped == false
@equipped = true
end
end

def remove
if @equipped == true
@equipped = false
end
end

def to_yaml_properties
['@name', '@weight','@equipped']
end

end

And here is the item equipping command.

def cmd_equip arg
item_equipped = false
self.inv.each do |item|
if item.name == arg
item.equip
item_equipped = true
break
end
end
if item_equipped == true
text_to_mobile "Equipped #{arg}"
else
text_to_mobile "Unable to equip #{arg}"
end
end


The characters inventory is nothing more than an Array containing instances of Item objects. I can't think of a better way of figuring out if an item is in their inventory! :P
07 Jan, 2009, The_Fury wrote in the 2nd comment:
Votes: 0
Hye good to see you back Chris, Its been a while.
07 Jan, 2009, Chris Bailey wrote in the 3rd comment:
Votes: 0
Thanks Fury! I had about a million and 7 crappy things happen at once + the holidays, so I've been out of the loop. I lost your email address, so I apologize about our agreement here. Forgive me? =)
07 Jan, 2009, Chris Bailey wrote in the 4th comment:
Votes: 0
I think I will be more specific with the question. Does anyone know of a good way to search an array of object instances and pluck the first one found out of it by matching the value of an instance variable in ruby? My method is working, but I think it needs to be better.
07 Jan, 2009, Stormy wrote in the 5th comment:
Votes: 0
That's the way I'd do it and I can't think of another way that's as reasonable. You need to access #name for each item, so not sure what else you could do, unless you plan on having potentially really expansive inventories.

In case that answer wasn't blah enough, you'll actually have to loop through in the same manner again to check against prefixes, or check for them in that same loop and determine the best candidate on a false find.

If your inventories could potentially be really large, you could throw the names into Tyche's ternarytrie if there are more than x number of items and assess that, though that's likely overkill and I'm not sure how large the set would have to be to benefit from that approach.
07 Jan, 2009, Chris Bailey wrote in the 6th comment:
Votes: 0
Ah, I hadn't considered using Tyche's ternarytrie (Haven't looked at it much actually), but inventories will be relatively small. I came across the detect method than enumerable mixes in, and it seems to be veeeeerrrryyyy handy for this. Check this out.

class Foo
def initialize(name)
@name = name
end
end

arr = Array.new
a = Foo.new 'wrong'
b = Foo.new 'right'

arr.push a,b

arr.detect {|item| item.name.include? 'rig'}


It would need some tweaking, but I just noticed it.

EDIT: I'm happy to see another Rubyist!! Woo! :)
07 Jan, 2009, Tyche wrote in the 7th comment:
Votes: 0
You probably want to do something more like..

arr.detect {|item| item.name=~/^rig/}

because "right".include? 'g' is also true

#detect is just a short hand method for something pretty close what you were originally doing…

arr.each {|item| break item if item=~/^rig/}

You'll probably find yourself reverting to it anyway to do something like Diku to find the nth item with the same name.

For example…

arr = ["sword", "sword of hobbit slaying", "sword of doom"]
count = 2
item = arr.each do |n|
if n =~ /^sword/
count -= 1
break n if count == 0
end
end
puts item










And WB, Chris :-)
07 Jan, 2009, Chris Bailey wrote in the 8th comment:
Votes: 0
Ahh. Thanks Tyche. Do you think it would be faster to use detect though, since it's written in C?
09 Jan, 2009, Stormy wrote in the 9th comment:
Votes: 0
Chris Bailey said:
Do you think it would be faster to use detect though, since it's written in C?


Actually looks the opposite on my machine:

Rehearsal ————————————————-
100 each: 0.000000 0.000000 0.000000 ( 0.000730)
1000 each: 0.010000 0.000000 0.010000 ( 0.007348)
10000 each: 0.060000 0.010000 0.070000 ( 0.072144)
100 detect: 0.000000 0.000000 0.000000 ( 0.001251)
1000 detect: 0.010000 0.010000 0.020000 ( 0.012152)
10000 detect: 0.100000 0.020000 0.120000 ( 0.120309)
—————————————- total: 0.220000sec

user system total real
100 each: 0.000000 0.000000 0.000000 ( 0.000696)
1000 each: 0.010000 0.000000 0.010000 ( 0.006433)
10000 each: 0.050000 0.020000 0.070000 ( 0.071875)
100 detect: 0.000000 0.000000 0.000000 ( 0.001138)
1000 detect: 0.010000 0.000000 0.010000 ( 0.011963)
10000 detect: 0.110000 0.020000 0.130000 ( 0.122819)
12 Jan, 2009, Chris Bailey wrote in the 10th comment:
Votes: 0
Very interesting. No more detect for me!
0.0/10