JS中的公式为游戏中的不同分支创建体验目标

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

我正在 Javascript 中创建一个小游戏,我的树可以容纳一定数量的最大经验,每棵树都有不同数量的树枝,这些树枝也需要升级经验,他们应该总计到树最大经验。

如果这么简单,我就平分了,比如max / branches,但是因为是游戏,所以我需要做一个公式,第一个分支不需要经验,然后每个分支需要的经验稳步增加(同时仍然总计树最大经验)。

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

Total Tree Experience Capacity: 600 XP

分支的数量可以是从 2 到 10,到 20 等等,所以它必须与树的最大经验容量成比例,我相信。我希望每个级别增加多少还必须取决于有多少分支,但我认为所有树应该有某种模式(如果这是个坏主意,请纠正我)。

我们知道的变量是:

其余未知。

公式如何解决这个问题?我也不介意专门针对 JS 的任何函数公式。

这就是你要找的。

每个级别的 "rate" 增量基于“1”和 BRANCH_COUNT-1 之间所有数字的总和。这个求和在数学上应该有一个名字,但是我忘记了....

它很容易用一个简单的函数计算出来,该函数获取分支总数和总 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;
}

并通过回忆一些高中比赛 as explained here。以上可以简化为:

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

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

然后是一些使用该函数打印出每个分支的奖励结构的示例代码

// 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;
    }
}

示例:

> 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

您似乎想要的是arithmetic progression。这是一个数字序列,其中每个数字之间存在共同差异,例如 1, 4, 7, 10 将是等差级数,其中每个后续成员之间的差异为 3

等差级数更广义的观点是

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

其中 a 是您的 初始成员 d 差异 n是系列的长度

等差级数求和的公式如下:

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

这看起来很复杂,让我们看看它的实际应用。假设我们要对序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 求和。或从 1 到 10 的整数。代入公式,我们有 a = 1d = 1n = 10,我们得到

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

我们可以写代码来验证:

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

console.log(sum);

所以,公式有效。

现在,我们想要洗牌 - 我们有 S,对于 树的总经验容量 ,我们还有 n 分支数,我们有a,这对于初始分支来说是零。我们只需要找到 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
((S / (n/2)) - 2*a) / (n - 1) = d

我们其实可以消去2*a,因为我们知道a = 0,所以我们可以稍微简化一下公式:

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

完成了。我们现在可以将它编码在一个函数中:

// S = totalExperience
// n = branches

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

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

您甚至可以使用生成器函数为您提供下一个 XP 值:

// 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)