# Get algorithm (Chance-to-Hit) from Input and Output

I am currently working on a chance-to-hit formula for an rpg. It consists of the following parts:

• AttackSkill: The used Attribute of the Attacker (Range: 1-10)
• AttackBonus: A Modifier from Skillbonuses (Range 0.5 - 3)

• DefenseSkill: The used Attribute of the Defender (Range: 1-10)

• DefenseFitness: How suitable is this defense against the attack? (Range: 0.1 - 5)
• DefenseBonus: A Modifier from Skillbonuses (Range 0.5 - 3)

This is the Input. I am looking for a way to map this to the following Output:

• Difficulty: How hard it is for the Attacker to hit (Range 0-10 float, later round to int)

What could I do to get the algorithm out of the value pairs? If possible, the output should be biased in direction of Difficulty 6 (like a normal distribution).

• Well generally you would divide the attack power by the defense stats of the attacked player. But if he uses defense abilities you would add that too.. – zoran404 Jun 2 '15 at 8:57

You are constructing a function from several inputs to meet a desired output. This function should factor the amount of each attribute in conjunction with the importance. Your use of value pairs for such a function also coheres excellently with a documented decision model. I believe that a weighted sum is in order.

The weighted sum model takes in each attribute's value and their weight and proceeds by multiplying the former by the latter. If an attribute carries great importance in the hit chance, then the weight should reflect this by carrying a higher value as well. For example, the AttackSkill attribute seems an important determinant, so it will be assigned a weight of 1.5. Conversely, AttackBonus impacts the positive chances much less, and is assigned 0.8. We are left with.

(AttackSkill*1.5)+(AttackBonus*0.8) = ATTACKPOWER


The same will be done on the defender's behalf accounting for an additional attribute.

(DefenseSkill*1.5)+(DefenseFitness*2.0)+(DefenseBonus*0.8) = DEFENSEPOWER


Weighted sum equations carry the advantage of modularity, allowing them to be scaled to any extent without breaking down. After the sums are obtained, they need to be referenced with each other to map these "forces" to a 0-10 chance. Here's a simple method.

We first measure the difference between the power of the attack and defense. If positive, the attack has 50% or greater of following through and vice versa. The difference is passed to a sigmoid function which presents a rather convenient chance curve.

The curve is mapped from 0-10 and voila.

(sigmoid(ATTACKPOWER-DEFENSEPOWER)+1.0)*5.0 = HITCHANCE


This may not be ideal, but I've found an answer on another Q/A-site.

1. Multiply all AttackerValues (lets call it AttackRating)
2. Multiply DefenderValues [Without DefenseFitness, see top] (lets call it DefenseRating)
3. Divide AttackRating with DefenseRating (lets call it Rating)
4. Divide Rating with DefenseFitness (lets call it RawDifficulty)

Raw Difficulty is a Value between 0,00333 and 600 (from the ranges in the question) This value now needs to be mapped to the range of 0-10.

1. Create a table in Excel with RawDifficulty and the required Result, for instance:

600 (easiest) needs to be mapped to 0.1, 0,0033 (hardest) needs to be mapped to 9.9. Add some values in between into the table, 1 (medium) needs to be mapped to 5 for example.

1. Get the square root of RawDifficulty (this was to dimnish extreme values somewhat)

2. Create a point diagram within excel, add a trendline (in this case logarithmic) and show the formula. Bang!

In my case the following formula does work:

EndDifficulty = -1,6395Ln(SquareRoot(RawDifficulty)) + 5,0963

What I usually do is just add more defense and more damage to the enemy as the difficulty increase. Since I'm no mathemagician, I just pick how much the rating it'll increase by difficulty. For example, Add 1000 to defense and 500 to damage each time they increase the difficulty. Sorta how they used to do it on classic games. But, that's just me lol

• Well thats something I want to avoid :) – user60245 Jun 6 '15 at 9:47