Formula in JS to create experience goals for different branches in a game

两盒软妹~` 提交于 2020-08-10 22:11:25

问题


I'm creating a little game in Javascript, and I have trees that can hold a certain amount of max experience, and each tree have a varied amount of branches that also needs to be leveled up with experience, and they should total to the tree max experience.

If it was that easy, I would just divide them equally, like max / branches, but since it's for a game, I need to make a formula where the first branch needs no experience, and then each branch experience needed steadily increase (while still totalling to the tree max experience).

Branch 1              0 XP
Branch 2              100 XP
Branch 3              200 XP
Branch 4              300 XP

Total Tree Experience Capacity: 600 XP

The amount of branches can be anything from 2 to 10, to 20 and so on, so it must therefor scale with the tree max experience capacity, I believe. How much I want each level to increase with must also depend on how many branches there are, but there should be some kind of pattern across all trees, I think (correct me if it's a bad idea).

The variables that we know are:

  • The amount of branches we have per tree
  • Max experience capacity for each tree

The rest is unknown.

How can a formula solve this issue? I also do not mind any functional formulas for specifically JS.


回答1:


What you seem to want is arithmetic progression. It's a sequence of numbers where there is a common difference between each, for example 1, 4, 7, 10 would be an arithmetic progression where the difference is 3 between each subsequent members.

The more generalised view of arithmetic progression is

a, a + d, a + 2d, a + 3d, ..., a + nd`

Where a is your initial member, d is the difference, and n is the length of the series.

The formula for a sum of arithmetic series is as follows:

S = (n/2) * (2*a + (n - 1)*d)

Which looks complex let's just see it in action. Let's say we want to sum the series 1, 2, 3, 4, 5, 6, 7, 8, 9, 10. Or integers from 1 to 10. Substituting in the formula, we have a = 1, d = 1, n = 10 and we get

S = (10/2) * (2*1 + (10 - 1)*1)
  = 5 * (2 + 9*1)
  = 5 * (2 + 9)
  = 5 * 11
  = 55

And we can just write code to verify:

const sum = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10;

console.log(sum);

So, the formula works.

Now, we want to shuffle things - we have S, for the total tree experience capacity, we also have n the number of branches, and we have a which would be zero for the initial branch. We just need to find d in order to get all the things we need. So, here it goes:

S = (n/2) * (2*a + (n - 1)*d)
S / (n/2) = 2*a + (n - 1)*d
(S / (n/2)) - 2*a = (n - 1)*d
((S / (n/2)) - 2*a) / (n - 1) = d

We can actually eliminate 2*a since we know a = 0, so we can slightly simplify the formula:

(S / (n/2)) / (n - 1) = d

And done. We can just encode it in a function now:

// S = totalExperience
// n = branches

function findArithmeticStep(totalExperience, branches) {
  return (totalExperience / (branches/2)) / (branches - 1);
}

console.log(findArithmeticStep(600, 4));

You can even use a generator function that will supply you the next XP value:

// S = totalExperience
// n = branches

function findArithmeticStep(totalExperience, branches) {
  return (totalExperience / (branches/2)) / (branches - 1);
}

function* nextXPCost(totalExperience, branches) {
  const step = findArithmeticStep(totalExperience, branches);
  
  let currentXPCost = 0;
  for(let i = 0; i < branches; i++) {
    yield currentXPCost;
    currentXPCost += step;
  }
}

const gen = nextXPCost(600, 4);

//1 - 0
let next = gen.next();
console.log(next.value, next.done);
//2 - 100
next = gen.next();
console.log(next.value, next.done);
//3 - 200
next = gen.next();
console.log(next.value, next.done);
//4 - 300
next = gen.next();
console.log(next.value, next.done);
//5 - getting after the end
next = gen.next();
console.log(next.value, next.done);

//generate an array of all costs
const allCostsTree1 = [...nextXPCost(600, 4)];
console.log(allCostsTree1);


//generate a different tree with higher total cost
const allCostsTree2 = [...nextXPCost(2000, 5)];
console.log(allCostsTree2)



回答2:


This is what you seek.

Your "rate" increment for each level is based on the summation of all the numbers between "1" and the BRANCH_COUNT-1. There's probably a name in mathematics for this summatation, but I forget it....

It's easily computed with a simple function that takes the total number of branches and the total XP.

// A function that determines the rate by which each branch reward should increment by
function getRate(branch_count, total_xp) {
   if (branch_count <= 1) {
        return 0;
   }

   let R = 0;

   for (let i = 1; i < branch_count; i++) {
      R += i;
   }

   return total_xp / R;
}

And by recalling some high school match as explained here. The above is can be simplified to just this:

function getRate(branch_count, total_xp) {
   if (branch_count <= 1) {
        return 0;
   }

   let R = ((branch_count-1) * (branch_count))/2;
   return total_xp / R;
}

And then some sample code using that function to print out the reward structure for each branch

// sample function to print the reward count for each branch 
function dumpBranches(branch_count, total_xp) {

    let rate = getRate(branch_count, total_xp);
    let reward = 0;
    for (let i = 0; i < branch_count; i++) {
        console.log("Branch ", i, reward);
        reward += rate;
    }
}

Example:

> dumpBranches(4, 600)
Branch  0 0
Branch  1 100
Branch  2 200
Branch  3 300

> dumpBranches(9, 2700)
Branch  0 0
Branch  1 75
Branch  2 150
Branch  3 225
Branch  4 300
Branch  5 375
Branch  6 450
Branch  7 525
Branch  8 600


来源:https://stackoverflow.com/questions/60904585/formula-in-js-to-create-experience-goals-for-different-branches-in-a-game

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!