我有一个插件,我为我的世界做的。它用于大规模的龙族格斗,根据造成的伤害在每个人之间公平地分配经验。
它是有效的,但有一个小问题,使方程错过了经验。
代码如下:
private void divideExpAmongstPlayersBasedOnDamageDealt(int exp, Map<Player, Double> damageMap) {
double totalDamageDealt = 0.0d;
for (Double value : damageMap.values()) {
totalDamageDealt += value;
}
while (exp > 0 && !damageMap.isEmpty()) {
Player maxHitterInList = Collections.max(damageMap.entrySet(),
Comparator.comparingDouble(Map.Entry::getValue)).getKey();
double damageShare = damageMap.get(maxHitterInList) / totalDamageDealt;
int expShare = (int) Math.round(exp * damageShare);
if (expShare == 0)
break;
if (maxHitterInList.isOnline()) {
sendPlayerMessage(maxHitterInList, damageShare, expShare);
maxHitterInList.giveExp(expShare);
}
exp -= expShare;
damageMap.remove(maxHitterInList);
}
}
它会找到最大的点击率,奖励他们分享的EXP,并将他们从列表中删除,直到没有更多的EXP可给。
问题是它遗漏了点,迫使我将&& !damageMap.isEmpty()
添加到while条件以避免异常。它总是准确地打印百分比(总和为100)。
我认为这与Math.round函数有关,尽管我对如何调试它一无所知。当我用手做计算时,它们就会计算出来。
例子(这确实发生了):一群暴徒授予10
exp。Player1做了破坏的57%
,Player2做了43%
。百分比值打印正确,但Player1收到6
EXP,Player2收到2
??上次我检查0.57 * 10
等于5.7 = 6
,0.43 * 10
等于4.3 = 4
。
我遗漏了什么?这是和round函数或doubles的工作方式有关吗?
谢谢
发布于 2019-05-27 02:13:52
这不是舍入问题,但您在计算中使用了错误的值。
你写了“上次我检查0.57 * 10等于5.7 =6,0.43 * 10等于4.3 = 4”,但你使用的公式是
int expShare = (int) Math.round(exp * damageShare);
并为循环的每次迭代更新exp
exp -= expShare;
这意味着对于第二个玩家,exp
是针对4的,而不是您在示例中假设的10,因此实际计算是0.43 *2,四舍五入为2
因此,您需要将while
条件中使用的变量和计算中使用的变量分开。
https://stackoverflow.com/questions/56316115
复制相似问题