# Brute force a formula based on numbers and the result?

I have thought of a very funny thing. In World of Warcraft, all weapons have some Damage Per Second variable specified. I want to know how they calculate that result, based on the result and some numbers. Here is what can affect it:

Speed: 1.90 //It swings every 1.9 seconds
Damage: 36 - 68 //Hits between 36 and 68 damage
Damage Per Second: 27.59 //This is what I want to calculate


There are some key things to consider when entering these numbers into the "calculator" I am looking for. They could be calculating this from "swings per minute" (speed/60) and the average damage ((36+68)/2).

Have you heard or seen these brute forcers before? It would basically go over all numbers and find a formula, which will always equal the result I input (27.59 in this case). Or at least approximately that number, because of floats et cetera.

Thanks for reading. Hopefully this gave you something to think about, because I think it is pretty cool.

• Well...it is awfully close to Average Damage/$1.9$. That comes out to $27.368$ . Hard to believe it's coincidental. – lulu Nov 28 '15 at 0:33
• @lulu You are completely right, but I honestly doubt that's the real equation. Just checked some others, and they all hit the same first whole number, but the decimals are wrong. – MortenMoulder Nov 28 '15 at 0:41
• And, intuitively, that's what "Damage per second" ought to mean, right? You take the amount of damage you expect over the given time period, and then divide by the length of time to get the expected damage per second. Is it possible the "36" and "68" are rounded figures? Is the error in my formula unbiased? That is, is it sometimes slightly greater than the stated answer and sometimes slightly less or is it always on one side or the other? – lulu Nov 28 '15 at 0:48
• Why shouldn't it be though? The units match up: $\rm \frac{Damage / Hit}{Seconds / Hit} = \frac{Damage}{Hit} \frac{Hit}{Second} = \frac{Damage}{Second}$. I suspect the discrepancy is that damage per hit isn't symmetrically distributed, so its average is probably not $\rm \frac{max + min}{2}$, but a bit higher (people don't like true randomness, in which you can get very unlucky not infrequently. Most games have mechanisms in place so that this doesn't happen). – pjs36 Nov 28 '15 at 0:49
• @lulu That could be very true. It might be true that the damage numbers are rounded. Or maybe Blizzard is approximating the average damage, based on the speed and damage.. like they have some constant they multiply the average damage with? pjs36: Yes I think the numbers are rounded perhaps, but I am not sure. – MortenMoulder Nov 28 '15 at 0:51

I would suggest to do your brute force a bit more methodical by minimizing the cost of appropriate functions over speed $$s$$ and damage $$d_{min}$$ and $$d_{max}$$ towards the given dps value $$dps$$.

I would start with linear combinations of different functions $$f_1(s,d_{min},d_{max})$$ to $$f_n(s,d_{min},d_{max})$$ .

Then you want to find the paramers $$a_1,\cdots,a_n$$ s.t. $$\sum_{i=1}^n a_i f_i(s_j,d_{j,min},d_{j,max}) = (dps)_j$$ for all indices $$j=1,\cdots,m$$ (that is over all your given data rows).

We can rewrite that in matrix form as $$\begin{pmatrix} f_1(s_1,d_{1,min},d_{1,max}) & \cdots & f_N(s_1,d_{1,min},d_{1,max})\\ \vdots & \ddots & \vdots\\ f_1(s_m,d_{m,min},d_{m,max}) & \cdots & f_N(s_m,d_{m,min},d_{m,max}) \end{pmatrix} \begin{pmatrix} a_1\\\vdots\\ a_N \end{pmatrix} = \begin{pmatrix} (dps)_1\\\vdots\\ (dps)_m \end{pmatrix}$$

Solving this in the least squares sense will lead you to the optimal parameters $$a_1,\cdots,a_N$$ for the given functions. But more importantly, it also allows you to compute

$$||\begin{pmatrix} f_1(s_1,d_{1,min},d_{1,max}) & \cdots & f_N(s_1,d_{1,min},d_{1,max})\\ \vdots & \ddots & \vdots\\ f_1(s_m,d_{m,min},d_{m,max}) & \cdots & f_N(s_m,d_{m,min},d_{m,max}) \end{pmatrix} \begin{pmatrix} a_1\\\vdots\\ a_N \end{pmatrix} - \begin{pmatrix} (dps)_1\\\vdots\\ (dps)_m \end{pmatrix}||$$

to see how well your functions fit the current data.

Try that out with different functions, e.g. f_1=s/(d_max-d_min), f_2=2s/(d_max+d_min) and so on and look at the values a_1 and a_2.

This is really fast to evaluate and hopefully give you a feel for which function works well with a lot of code reusability for different prototypes.