浏览代码

Add some unit tests for new RNG dice rolls

nossr50 2 年之前
父节点
当前提交
05c86f1125

+ 1 - 1
pom.xml

@@ -2,7 +2,7 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.gmail.nossr50.mcMMO</groupId>
     <artifactId>mcMMO</artifactId>
-    <version>2.1.218</version>
+    <version>2.2.000-BETA-SNAPSHOT</version>
     <name>mcMMO</name>
     <url>https://github.com/mcMMO-Dev/mcMMO</url>
     <scm>

+ 5 - 5
src/main/java/com/gmail/nossr50/util/random/RandomChanceUtil.java

@@ -4,12 +4,11 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.util.skills.SkillUtils;
 import org.bukkit.entity.Player;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.VisibleForTesting;
 
 import java.text.DecimalFormat;
 import java.util.concurrent.ThreadLocalRandom;
 
-//TODO: Normalize chance values
-//TODO: Update calls to this class and its members
 public class RandomChanceUtil {
     public static final @NotNull DecimalFormat percent = new DecimalFormat("##0.00%");
     public static final double LUCKY_MODIFIER = 1.333D;
@@ -43,8 +42,9 @@ public class RandomChanceUtil {
      * @param probabilityValue probability value
      * @return true for succeeding, false for failing
      */
-    private static boolean isSuccessfulRoll(double probabilityValue) {
-        return probabilityValue >= ThreadLocalRandom.current().nextDouble(1.0D);
+    @VisibleForTesting
+    static boolean isSuccessfulRoll(double probabilityValue) {
+        return probabilityValue >= ThreadLocalRandom.current().nextDouble(100D);
     }
 
     /**
@@ -52,7 +52,7 @@ public class RandomChanceUtil {
      *
      * @param player target player
      * @param subSkillType target subskill
-     * @param isLucky whether or not to apply luck modifiers
+     * @param isLucky whether to apply luck modifiers
      *
      * @return "percentage" representation of success
      */

+ 3 - 19
src/test/java/com/gmail/nossr50/util/random/RandomChanceTest.java

@@ -85,25 +85,9 @@
 ////        }
 ////    }
 //
-//    @Test
-//    public void testFailsAboutExpected() {
-//        System.out.println(testASCIIHeader);
-//        System.out.println("Test - Player with 800 skill should fail about 20% of the time (100,000 iterations)");
-//        double ratioDivisor = 1000; //1000 because we run the test 100,000 times
-//        double expectedFailRate = 100.0D - 2.15D;
-//
-//        double win = 0, loss = 0;
-//        for(int x = 0; x < 100000; x++) {
-//            if(RandomChanceUtil.checkRandomChanceExecutionSuccess(normalPlayer, SubSkillType.MINING_MOTHER_LODE, true)) {
-//                win++;
-//            } else {
-//                loss++;
-//            }
-//        }
-//
-//        double lossRatio = (loss / ratioDivisor);
-//        Assert.assertEquals(lossRatio, expectedFailRate, 0.01D);
-//    }
+//
+//
+//
 //
 //    private double getSuccessChance(@NotNull McMMOPlayer mmoPlayer) {
 //        RandomChanceSkill randomChanceSkill = new RandomChanceSkill(mmoPlayer.getPlayer(), subSkillType, true);

+ 76 - 0
src/test/java/com/gmail/nossr50/util/random/RandomChanceUtilTest.java

@@ -0,0 +1,76 @@
+package com.gmail.nossr50.util.random;
+
+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 java.util.stream.Stream;
+
+import static com.gmail.nossr50.util.random.RandomChanceUtil.processProbability;
+import static org.junit.jupiter.api.Assertions.*;
+
+class RandomChanceUtilTest {
+
+    private static Stream<Arguments> provideProbabilitiesForWithinExpectations() {
+        return Stream.of(
+                // static probability, % of time for success
+                Arguments.of(new ProbabilityImpl(5), 5),
+                Arguments.of(new ProbabilityImpl(10), 10),
+                Arguments.of(new ProbabilityImpl(15), 15),
+                Arguments.of(new ProbabilityImpl(20), 20),
+                Arguments.of(new ProbabilityImpl(25), 25),
+                Arguments.of(new ProbabilityImpl(50), 50),
+                Arguments.of(new ProbabilityImpl(75), 75),
+                Arguments.of(new ProbabilityImpl(90), 90),
+                Arguments.of(new ProbabilityImpl(99.9), 99.9),
+                Arguments.of(new ProbabilityImpl(0.05), 0.05),
+                Arguments.of(new ProbabilityImpl(0.1), 0.1),
+                Arguments.of(new ProbabilityImpl(500), 100),
+                Arguments.of(new ProbabilityImpl(1000), 100)
+        );
+    }
+    @Test
+    void testIsSuccessfulRollSucceeds() {
+        Probability probability = new ProbabilityImpl(100);
+
+        for (int i = 0; i < 100000; i++) {
+            assertTrue(processProbability(probability));
+        }
+    }
+
+    @Test
+    void testIsSuccessfulRollFails() {
+        Probability probability = new ProbabilityImpl(0);
+
+        for (int i = 0; i < 100000; i++) {
+            assertFalse(processProbability(probability));
+        }
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideProbabilitiesForWithinExpectations")
+    void testProcessProbabilityWithinExpectations(Probability probability, double expectedWinPercent) {
+        // Probabilities are tested 200,000,000 times with a margin of error of 0.01%
+        int iterations = 200000000;
+        double winCount = 0;
+
+        for (int i = 0; i < iterations; i++) {
+            if(processProbability(probability)) {
+                winCount++;
+            }
+        }
+
+        double successPercent = (winCount / iterations) * 100;
+        System.out.println(successPercent + ", " + expectedWinPercent);
+        assertEquals(expectedWinPercent, successPercent, 0.01D);
+    }
+
+    @Test
+    void chanceOfSuccessPercentage() {
+    }
+
+    @Test
+    void testChanceOfSuccessPercentage() {
+    }
+}