diff --git a/src/main/java/com/gmail/nossr50/util/random/ProbabilityUtil.java b/src/main/java/com/gmail/nossr50/util/random/ProbabilityUtil.java index a625260fd..55d6950b6 100644 --- a/src/main/java/com/gmail/nossr50/util/random/ProbabilityUtil.java +++ b/src/main/java/com/gmail/nossr50/util/random/ProbabilityUtil.java @@ -54,11 +54,11 @@ public class ProbabilityUtil { return percentageValue; } - static double getStaticRandomChance(@NotNull SubSkillType subSkillType) throws InvalidStaticChance { + static Probability getStaticRandomChance(@NotNull SubSkillType subSkillType) throws InvalidStaticChance { return switch (subSkillType) { - case AXES_ARMOR_IMPACT -> mcMMO.p.getAdvancedConfig().getImpactChance(); - case AXES_GREATER_IMPACT -> mcMMO.p.getAdvancedConfig().getGreaterImpactChance(); - case TAMING_FAST_FOOD_SERVICE -> mcMMO.p.getAdvancedConfig().getFastFoodChance(); + case AXES_ARMOR_IMPACT -> Probability.ofPercent(mcMMO.p.getAdvancedConfig().getImpactChance()); + case AXES_GREATER_IMPACT -> Probability.ofPercent(mcMMO.p.getAdvancedConfig().getGreaterImpactChance()); + case TAMING_FAST_FOOD_SERVICE -> Probability.ofPercent(mcMMO.p.getAdvancedConfig().getFastFoodChance()); default -> throw new InvalidStaticChance(); }; } @@ -99,7 +99,7 @@ public class ProbabilityUtil { return new ProbabilityImpl(xPos, xCeiling, probabilityCeiling); case STATIC_CONFIGURABLE: try { - return Probability.ofPercent(getStaticRandomChance(subSkillType)); + return getStaticRandomChance(subSkillType); } catch (InvalidStaticChance invalidStaticChance) { invalidStaticChance.printStackTrace(); } diff --git a/src/test/java/com/gmail/nossr50/util/random/ProbabilityTest.java b/src/test/java/com/gmail/nossr50/util/random/ProbabilityTest.java index ac551df40..a454d5b20 100644 --- a/src/test/java/com/gmail/nossr50/util/random/ProbabilityTest.java +++ b/src/test/java/com/gmail/nossr50/util/random/ProbabilityTest.java @@ -100,8 +100,8 @@ class ProbabilityTest { @ParameterizedTest @MethodSource("provideOfPercentageProbabilitiesForWithinExpectations") void testOddsExpectationsOfPercent(Probability probability, double expectedWinPercent) { - // Probabilities are tested 200,000,000 times with a margin of error of 0.01% - int iterations = 200000000; + // Probabilities are tested 2.0 x 10^9 with a margin of error of 0.01% + double iterations = 2.0e9; double winCount = 0; for (int i = 0; i < iterations; i++) { diff --git a/src/test/java/com/gmail/nossr50/util/random/ProbabilityUtilTest.java b/src/test/java/com/gmail/nossr50/util/random/ProbabilityUtilTest.java index 63844bb24..9bb78fcf0 100644 --- a/src/test/java/com/gmail/nossr50/util/random/ProbabilityUtilTest.java +++ b/src/test/java/com/gmail/nossr50/util/random/ProbabilityUtilTest.java @@ -1,22 +1,64 @@ package com.gmail.nossr50.util.random; -import org.bukkit.entity.Player; +import com.gmail.nossr50.config.AdvancedConfig; +import com.gmail.nossr50.datatypes.skills.SubSkillType; +import com.gmail.nossr50.mcMMO; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.mockito.Mockito; +import java.util.stream.Stream; + +import static com.gmail.nossr50.datatypes.skills.SubSkillType.*; +import static org.junit.jupiter.api.Assertions.assertEquals; + class ProbabilityUtilTest { - // Mocks - Player player; + mcMMO mmoInstance; + AdvancedConfig advancedConfig; + + final static double impactChance = 11D; + final static double greaterImpactChance = 0.007D; + final static double fastFoodChance = 45.5D; @BeforeEach - public void setupMocks() { - this.player = Mockito.mock(Player.class); + public void setupMocks() throws NoSuchFieldException, IllegalAccessException { + this.mmoInstance = Mockito.mock(mcMMO.class); + mcMMO.class.getField("p").set(null, mmoInstance); + this.advancedConfig = Mockito.mock(AdvancedConfig.class); + Mockito.when(mmoInstance.getAdvancedConfig()).thenReturn(advancedConfig); + Mockito.when(advancedConfig.getImpactChance()).thenReturn(impactChance); + Mockito.when(advancedConfig.getGreaterImpactChance()).thenReturn(greaterImpactChance); + Mockito.when(advancedConfig.getFastFoodChance()).thenReturn(fastFoodChance); } - @Test - public void testChanceOfSuccessPercentage() { + private static Stream staticChanceSkills() { + return Stream.of( + // static probability, % of time for success + Arguments.of(AXES_ARMOR_IMPACT, impactChance), + Arguments.of(AXES_GREATER_IMPACT, greaterImpactChance), + Arguments.of(TAMING_FAST_FOOD_SERVICE, fastFoodChance) + ); + } + @ParameterizedTest + @MethodSource("staticChanceSkills") + void testStaticChanceSkills(SubSkillType subSkillType, double expectedWinPercent) throws InvalidStaticChance { + // Probabilities are tested 2.0 x 10^9 with a margin of error of 0.01% + double iterations = 2.0e9; + double winCount = 0; + + Probability staticRandomChance = ProbabilityUtil.getStaticRandomChance(subSkillType); + for (int i = 0; i < iterations; i++) { + if(staticRandomChance.evaluate()) { + winCount++; + } + } + + double successPercent = (winCount / iterations) * 100; + System.out.println(successPercent + ", " + expectedWinPercent); + assertEquals(expectedWinPercent, successPercent, 0.01D); } } \ No newline at end of file