class LifePex::Level LEVEL_BY_XP = -> (xp) { ((xp / 100.0)**(1.0 / 1.1)).floor + 1 } XP_BY_LEVEL = -> (level) { (level - 1)**(1.1) * 100.0 } SERIALIZABLE_ATTRIBUTES = [:current_xp, :current_level, :next_xp, :next_level, :xp_from_current_level, :xp_to_next_level, :xp_for_complete_level, :progress] attr_reader *SERIALIZABLE_ATTRIBUTES def initialize(current_xp = 0) @current_xp = current_xp @current_level = LEVEL_BY_XP.call(@current_xp) @next_level = @current_level + 1 @next_xp = XP_BY_LEVEL.call(next_level) @xp_for_complete_level = XP_BY_LEVEL.call(@next_level) - XP_BY_LEVEL.call(@current_level) @xp_to_next_level = XP_BY_LEVEL.call(@next_level) - @current_xp @xp_from_current_level = @xp_for_complete_level - @xp_to_next_level @progress = @xp_from_current_level / @xp_for_complete_level end def to_h SERIALIZABLE_ATTRIBUTES.map { |attr| [attr, self.send(attr)] }.to_h end end