Формула в JS для создания целей опыта для различных веток в игре - PullRequest
0 голосов
/ 28 марта 2020

Я создаю небольшую игру в 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.

Ответы [ 2 ]

1 голос
/ 28 марта 2020

То, что вы, похоже, хотите, это арифмети c прогрессия . Это последовательность чисел, где между ними есть общая разница, например 1, 4, 7, 10 будет арифметической c последовательностью, где разница составляет 3 между каждым последующим элементом.

Более обобщенное представление арифметика c прогрессия

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

где a ваш начальный член , d это разница , а n это длина серии.

Формула для суммы арифметических рядов c выглядит следующим образом:

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

Что выглядит сложным, давайте просто посмотрим на это в действии. Допустим, мы хотим сложить серию 1, 2, 3, 4, 5, 6, 7, 8, 9, 10. Или целые числа от 1 до 10. Подставляя в формулу, мы имеем a = 1, d = 1, n = 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)
1 голос
/ 28 марта 2020

Это то, что вы ищете.

Ваш прирост "ставки" для каждого уровня основан на суммировании всех чисел между "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;
}

И, вспоминая какой-то школьный матч , как объяснено здесь . Вышесказанное можно упростить до следующего:

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
...