Выбор хеша в ruby, основанный на сравнении - PullRequest
1 голос
/ 13 марта 2011

Посмотрите на этот код, пожалуйста:

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, выполнив вышеуказанные действия?

Ответы [ 4 ]

5 голосов
/ 13 марта 2011

Вы создаете 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
3 голосов
/ 13 марта 2011

Вероятно, это не лучший способ организовать ваш код. Я бы порекомендовал хранить первый класс пользователя как объект, который выполняет вычисления самостоятельно. Это более объектно-ориентированный подход:

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

Но я думаю, что это выглядит чище, более объектно-ориентировано и значительно снижает сложность вашего кода.

1 голос
/ 13 марта 2011

Положите цены в хэш

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]

Вы также использовали квадратные вместо фигурных скобок, в которых вместо хеша был массив.

(Еще один совет, вы можете сделать одну строку, если операторы более читабельны, например: my_number = 10 if my_number > 10)

1 голос
/ 13 марта 2011

У вас проблемы, потому что вы устанавливаете истребителя / рейнджера / мага как список хэшей из одного элемента.

Вы хотите:

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}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...