请看一下这段代码:
fighter = [:str => 2, :dex => 3, :mag => 3, :acc => 2, :hp => 2]
ranger = [:str => 3, :dex => 2, :mag => 3, :acc => 2, :hp => 2]
magician = [:str => 3, :dex => 3, :mag => 2, :acc => 2, :hp => 2]
rate = Hash.new
if user.first_class == 'Fighter' then rate = fighter end
if user.first_class == 'Ranger' then rate = magician end
if user.first_class == 'Magician' then rate = ranger end
cost = Hash.new
cost[:str] = (user.strength_points + 1) * rate[:str]
cost[:dex] = (user.dexterity_points + 1) * rate[:dex]
cost[:mag] = (user.magic_points + 1) * rate[:mag]
cost[:acc] = (user.accuracy_points + 1) * rate[:acc]
cost[:hp] = (user.health_points + 1) * rate[:hp]
cost
这驻留在我已经创建的函数中,当我在Rails中执行它时,我得到一个“符号作为数组索引”。我猜这是因为率=战士,率=魔术师或率=游侠的可能性。也许我必须使用克隆。
我的问题是,基于if比较选择哈希的更好方法是什么,做上述事情?
答案 0 :(得分:5)
您正在创建一个Array
,其中一个条目是Hash
:
fighter = [:str => 2, :dex => 3, :mag => 3, :acc => 2, :hp => 2]
=> [{:str=>2, :dex=>3, :mag=>3, :acc=>2, :hp=>2}]
您打算做的只是创建一个Hash
:
fighter = {:str => 2, :dex => 3, :mag => 3, :acc => 2, :hp => 2}
=> {:str=>2, :dex=>3, :mag=>3, :acc=>2, :hp=>2}
此外,使用if
语句代替三个case
语句:
rate = case user.first_class
when "ranger"
ranger
when "magician"
magician
when "fighter"
fighter
end
答案 1 :(得分:3)
这可能不是整理代码的最佳方式。我建议将用户的第一个类存储为执行计算的对象。这是一种更面向对象的方法:
class User
def first_class= klass
@first_class = klass.new(self)
end
def first_class
@first_class
end
end
class FirstClass
attr_accessor :user
def initialize user
@user = user
end
def cost
{ :str => (user.strength_points + 1)*rate[:str],
:dex => (user.dexterity_points + 1) * rate[:dex],
:mag => (user.magic_points + 1) * rate[:mag],
:acc => (user.accuracy_points + 1) * rate[:acc],
:hp => (user.health_points + 1) * rate[:hp] }
end
end
然后,您可以定义第一类类型:
class Fighter < FirstClass
def rate
{:str => 2, :dex => 3, :mag => 3, :acc => 2, :hp => 2}
end
end
class Magician < FirstClass
def rate
{:str => 3, :dex => 3, :mag => 2, :acc => 2, :hp => 2}
end
end
class Ranger < FirstClass
def rate
{:str => 3, :dex => 2, :mag => 3, :acc => 2, :hp => 2}
end
end
然后你可以调整你的功能:
user.first_class.cost
请记住,您还必须将第一个类设置为对象:
user.first_class = Fighter
但我认为这看起来更干净,更面向对象并大大降低了代码的复杂性。
答案 2 :(得分:1)
您遇到问题,因为您将战斗机/游侠/魔术师设置为单个元素哈希列表。
你想:
fighter = {:str => 2, :dex => 3, :mag => 3, :acc => 2, :hp => 2}
ranger = {:str => 3, :dex => 2, :mag => 3, :acc => 2, :hp => 2}
magician = {:str => 3, :dex => 3, :mag => 2, :acc => 2, :hp => 2}
答案 3 :(得分:1)
将汇率放入哈希值
rates = {
"fighter" => { :str => 2, :dex => 3, :mag => 3, :acc => 2, :hp => 2 },
"ranger" => { :str => 3, :dex => 2, :mag => 3, :acc => 2, :hp => 2 },
"magician" => { :str => 3, :dex => 3, :mag => 2, :acc => 2, :hp => 2 }
}
rate = rates[user.first_class.downcase]
你也使用了方形而不是花括号,这使得数组而不是散列。
(另一个提示,你可以像以下那样更容易地执行单行if语句:my_number = 10 if my_number > 10
)