将获得的积分转换为游戏时间(与数学相关)

时间:2018-11-04 12:54:32

标签: javascript math data-conversion

我需要使用普通的JavaScript将一定数量的经验值转换成一定数量的固定费率。

例如:

玩家拥有1,129,518点经验值。

每小时获得的经验值的数量取决于一个人已经拥有的经验值。他们会被安排成这样:

0 xp以上:8,000 xp / h

2107 xp以上:20,000 xp / h

101,333 xp以上:45,000 xp / h

1,210,421 xp以上:68,500 xp / h

高于13,034,431 xp:每小时75,000 xp

我正在努力寻找一种方法来使用这些xp速率,以至少使用一些精美的Javascript将给定的经验值转换为播放的小时数。

我最终遇到了令人困惑的if / else语句,由于数学错误而最终以失败告终。

那里有任何数学向导可以帮助我吗?谢谢。

代码示例:我将从这里

 if(xp === 0){
    return 0;
}else if( 2107 >= xp > 0){
    const result = (xp/8000).toFixed(1);
    return result;
}else if(101333 >= xp > 2107){
    const result = ((2107/8000) + ((xp-2107)/20000)).toFixed(1);
    return result;
}else if(1210421 >= xp > 101333){
    ...
}

如您所见,如果存在许多不同的层,它将很快失去控制。

3 个答案:

答案 0 :(得分:1)

首先,您应该这样编写if语句:

if( 2107 >= xp && xp > 0){
    ...
}

接下来,尝试将XP视为XP的存储桶,每个存储桶具有不同的价值/价格。从最有价值的存储桶到最不有价值的存储桶,为每个存储桶计算小时数,并减去用于计算这些小时数的XP。

您可以在while循环中执行此操作:

let hours = 0;
while(XP > 0)
{
  // figure out bucket you are in, your if statements are fine for that.
  let value = 0;
  let lowerBoundary = 0;
  if( 101333 >= xp && xp > 2107){
    value = 20000;
    lowerBoundary = 2107;
    // you need lower boundary to figure out how many XP you used in this bucket.
  }
  // else if...
  const usedInBucket = XP - lowerBoundary;
  hours += usedInBucket / value; // simply calculate hours needed
  XP -= usedInBucket;
}

答案 1 :(得分:1)

这是我想出的:

const steps = [{
    min: 0,
    val: 8000
  },
  {
    min: 2107,
    val: 20000
  },
  {
    min: 101333,
    val: 45000
  },
  {
    min: 1210421,
    val: 68500
  },
  {
    min: 13034431,
    val: 75000
  },
].sort((a, b) => b.min - a.min);

//using for loop
function xpToHours(xp = 0) {
  let h = 0;
  steps.forEach(s => {
    let amt = Math.max(xp - s.min, 0);
    h += amt * s.val;
    xp -= amt;
  });
  return h;
}

//using reduce
function xpToHours2(xp = 0) {
  return steps.reduce((h, s) => {
    let amt = Math.max(xp - s.min, 0);
    xp -= amt;
    return h + amt * s.val;
  }, 0)
}


[0, 1000, 2000, 3000, 1000000].forEach(xp => console.log(xp, xpToHours(xp)));
[0, 1000, 2000, 3000, 1000000].forEach(xp => console.log(xp, xpToHours2(xp)));

说明:

steps只是一个包含您不同阶段的数组。按从最高到最低的最小xp排序。

然后,我们仅遍历此数组以计算amt,这是当前最高阶段使用的xp。因此,所需时间为amt * currentstep.val,xp减少了下一个阶段计算出的数量。

答案 2 :(得分:0)

最简单的方法是使用一系列范围和Array.prototype.find

// Make sure this is sorted desc
const expRanges = [{
    above: 101333,
    xph: 45000
  },
  {
    above: 2107,
    xph: 20000
  },
  {
    above: 0,
    xph: 8000
  }
];

function findExpPerHour(xp) {
  return expRanges.find(range => range.above < xp).xph;
}

// TESTS
const playerExpTests = [{
  name: "P1",
  xp: 12
}, {
  name: "P2",
  xp: 12000
}, {
  name: "P3",
  xp: 200000
}, {
  name: "P4",
  xp: 99999999
}];

playerExpTests.forEach(p => {
  console.log(p.name, "Exp per hour:", findExpPerHour(p.xp));
});