mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2025-09-27 14:59:09 +02:00
fix probability being unbounded
This commit is contained in:
@@ -14,19 +14,19 @@ class ProbabilityTest {
|
||||
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)
|
||||
Arguments.of(new ProbabilityImpl(.05), 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(.999), 99.9),
|
||||
Arguments.of(new ProbabilityImpl(0.0005), 0.05),
|
||||
Arguments.of(new ProbabilityImpl(0.001), 0.1),
|
||||
Arguments.of(new ProbabilityImpl(50.0), 100),
|
||||
Arguments.of(new ProbabilityImpl(100.0), 100)
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,22 @@
|
||||
package com.gmail.nossr50.util.random;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class ProbabilityTestUtils {
|
||||
public static void assertProbabilityExpectations(double expectedWinPercent, Probability probability) {
|
||||
double iterations = 2.0e7; //20 million
|
||||
double winCount = 0;
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
if(probability.evaluate()) {
|
||||
winCount++;
|
||||
}
|
||||
}
|
||||
|
||||
double successPercent = (winCount / iterations) * 100;
|
||||
System.out.println("Wins: " + winCount);
|
||||
System.out.println("Fails: " + (iterations - winCount));
|
||||
System.out.println("Percentage succeeded: " + successPercent + ", Expected: " + expectedWinPercent);
|
||||
assertEquals(expectedWinPercent, successPercent, 0.025D);
|
||||
System.out.println("Variance is within tolerance levels!");
|
||||
}
|
||||
}
|
@@ -1,39 +1,44 @@
|
||||
package com.gmail.nossr50.util.random;
|
||||
|
||||
import com.gmail.nossr50.config.AdvancedConfig;
|
||||
import com.gmail.nossr50.MMOTestEnvironment;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
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 java.util.logging.Logger;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.gmail.nossr50.datatypes.skills.SubSkillType.*;
|
||||
import static com.gmail.nossr50.util.random.ProbabilityTestUtils.assertProbabilityExpectations;
|
||||
import static com.gmail.nossr50.util.random.ProbabilityUtil.calculateCurrentSkillProbability;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class ProbabilityUtilTest {
|
||||
mcMMO mmoInstance;
|
||||
AdvancedConfig advancedConfig;
|
||||
class ProbabilityUtilTest extends MMOTestEnvironment {
|
||||
private static final Logger logger = getLogger(ProbabilityUtilTest.class.getName());
|
||||
|
||||
final static double impactChance = 11D;
|
||||
final static double greaterImpactChance = 0.007D;
|
||||
final static double fastFoodChance = 45.5D;
|
||||
|
||||
@BeforeEach
|
||||
public void setupMocks() throws NoSuchFieldException, IllegalAccessException {
|
||||
this.mmoInstance = mock(mcMMO.class);
|
||||
mcMMO.class.getField("p").set(null, mmoInstance);
|
||||
this.advancedConfig = mock(AdvancedConfig.class);
|
||||
when(mmoInstance.getAdvancedConfig()).thenReturn(advancedConfig);
|
||||
public void setupMocks() {
|
||||
mockBaseEnvironment(logger);
|
||||
when(advancedConfig.getImpactChance()).thenReturn(impactChance);
|
||||
when(advancedConfig.getGreaterImpactChance()).thenReturn(greaterImpactChance);
|
||||
when(advancedConfig.getFastFoodChance()).thenReturn(fastFoodChance);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
cleanupBaseEnvironment();
|
||||
}
|
||||
|
||||
private static Stream<Arguments> staticChanceSkills() {
|
||||
return Stream.of(
|
||||
// static probability, % of time for success
|
||||
@@ -45,22 +50,26 @@ class ProbabilityUtilTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("staticChanceSkills")
|
||||
void testStaticChanceSkills(SubSkillType subSkillType, double expectedWinPercent) throws InvalidStaticChance {
|
||||
void staticChanceSkillsShouldSucceedAsExpected(SubSkillType subSkillType, double expectedWinPercent)
|
||||
throws InvalidStaticChance {
|
||||
Probability staticRandomChance = ProbabilityUtil.getStaticRandomChance(subSkillType);
|
||||
assertProbabilityExpectations(expectedWinPercent, staticRandomChance);
|
||||
}
|
||||
|
||||
private static void assertProbabilityExpectations(double expectedWinPercent, Probability probability) {
|
||||
double iterations = 2.0e7;
|
||||
double winCount = 0;
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
if(probability.evaluate()) {
|
||||
winCount++;
|
||||
}
|
||||
}
|
||||
@Test
|
||||
public void isSkillRNGSuccessfulShouldBehaveAsExpected() {
|
||||
// Given
|
||||
when(advancedConfig.getMaximumProbability(UNARMED_ARROW_DEFLECT)).thenReturn(20D);
|
||||
when(advancedConfig.getMaxBonusLevel(UNARMED_ARROW_DEFLECT)).thenReturn(0);
|
||||
|
||||
double successPercent = (winCount / iterations) * 100;
|
||||
System.out.println(successPercent + ", " + expectedWinPercent);
|
||||
assertEquals(expectedWinPercent, successPercent, 0.05D);
|
||||
final Probability probability = ProbabilityUtil.getSkillProbability(UNARMED_ARROW_DEFLECT, player);
|
||||
assertEquals(0.2D, probability.getValue());
|
||||
assertProbabilityExpectations(20, probability);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void calculateCurrentSkillProbabilityShouldBeTwenty() {
|
||||
final Probability probability = calculateCurrentSkillProbability(1000, 0, 20, 1000);
|
||||
assertEquals(0.2D, probability.getValue());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user