Refactor probability tests a little bit

This commit is contained in:
nossr50 2022-12-18 17:08:36 -08:00
parent 4a5e3542ef
commit 12fb4a3679
3 changed files with 37 additions and 36 deletions

View File

@ -33,6 +33,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.VisibleForTesting;
import java.util.Locale; import java.util.Locale;
@ -198,7 +199,8 @@ public class Roll extends AcrobaticsSubSkill {
* @param damage The amount of damage initially dealt by the event * @param damage The amount of damage initially dealt by the event
* @return the modified event damage if the ability was successful, the original event damage otherwise * @return the modified event damage if the ability was successful, the original event damage otherwise
*/ */
private double rollCheck(Player player, McMMOPlayer mcMMOPlayer, double damage) { @VisibleForTesting
public double rollCheck(Player player, McMMOPlayer mcMMOPlayer, double damage) {
int skillLevel = mcMMOPlayer.getSkillLevel(getPrimarySkill()); int skillLevel = mcMMOPlayer.getSkillLevel(getPrimarySkill());
@ -246,8 +248,7 @@ public class Roll extends AcrobaticsSubSkill {
private double gracefulRollCheck(Player player, McMMOPlayer mcMMOPlayer, double damage, int skillLevel) { private double gracefulRollCheck(Player player, McMMOPlayer mcMMOPlayer, double damage, int skillLevel) {
double modifiedDamage = calculateModifiedRollDamage(damage, mcMMO.p.getAdvancedConfig().getRollDamageThreshold() * 2); double modifiedDamage = calculateModifiedRollDamage(damage, mcMMO.p.getAdvancedConfig().getRollDamageThreshold() * 2);
double gracefulOdds = ProbabilityUtil.getSubSkillProbability(subSkillType, player).getValue() * 2; Probability gracefulProbability = getGracefulProbability(player);
Probability gracefulProbability = Probability.ofPercent(gracefulOdds);
if (!isFatal(player, modifiedDamage) if (!isFatal(player, modifiedDamage)
//TODO: Graceful isn't sending out an event //TODO: Graceful isn't sending out an event
@ -271,6 +272,12 @@ public class Roll extends AcrobaticsSubSkill {
return damage; return damage;
} }
@NotNull
public static Probability getGracefulProbability(Player player) {
double gracefulOdds = ProbabilityUtil.getSubSkillProbability(SubSkillType.ACROBATICS_ROLL, player).getValue() * 2;
return Probability.ofPercent(gracefulOdds);
}
/** /**
* Check if the player is "farming" Acrobatics XP using * Check if the player is "farming" Acrobatics XP using
* exploits in the game. * exploits in the game.

View File

@ -1,12 +1,9 @@
package com.gmail.nossr50.util.random; package com.gmail.nossr50.util.random;
import org.bukkit.entity.Player;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.Mockito;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -82,26 +79,17 @@ class ProbabilityTest {
@ParameterizedTest @ParameterizedTest
@MethodSource("provideProbabilitiesForWithinExpectations") @MethodSource("provideProbabilitiesForWithinExpectations")
void testOddsExpectationsImplConstructor(Probability probability, double expectedWinPercent) { void testOddsExpectationsImplConstructor(Probability probability, double expectedWinPercent) {
// Probabilities are tested 200,000,000 times with a margin of error of 0.01% assertExpectations(probability, expectedWinPercent);
int iterations = 200000000;
double winCount = 0;
for (int i = 0; i < iterations; i++) {
if(probability.evaluate()) {
winCount++;
}
}
double successPercent = (winCount / iterations) * 100;
System.out.println(successPercent + ", " + expectedWinPercent);
assertEquals(expectedWinPercent, successPercent, 0.01D);
} }
@ParameterizedTest @ParameterizedTest
@MethodSource("provideOfPercentageProbabilitiesForWithinExpectations") @MethodSource("provideOfPercentageProbabilitiesForWithinExpectations")
void testOddsExpectationsOfPercent(Probability probability, double expectedWinPercent) { void testOddsExpectationsOfPercent(Probability probability, double expectedWinPercent) {
// Probabilities are tested 2.0 x 10^9 with a margin of error of 0.01% assertExpectations(probability, expectedWinPercent);
double iterations = 2.0e9; }
private static void assertExpectations(Probability probability, double expectedWinPercent) {
double iterations = 2.0e7;
double winCount = 0; double winCount = 0;
for (int i = 0; i < iterations; i++) { for (int i = 0; i < iterations; i++) {
@ -112,6 +100,6 @@ class ProbabilityTest {
double successPercent = (winCount / iterations) * 100; double successPercent = (winCount / iterations) * 100;
System.out.println(successPercent + ", " + expectedWinPercent); System.out.println(successPercent + ", " + expectedWinPercent);
assertEquals(expectedWinPercent, successPercent, 0.01D); assertEquals(expectedWinPercent, successPercent, 0.05D);
} }
} }

View File

@ -1,18 +1,22 @@
package com.gmail.nossr50.util.random; package com.gmail.nossr50.util.random;
import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.SubSkillType; import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import org.bukkit.entity.Player;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.Mockito;
import java.util.stream.Stream; import java.util.stream.Stream;
import static com.gmail.nossr50.datatypes.skills.SubSkillType.*; import static com.gmail.nossr50.datatypes.skills.SubSkillType.*;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
class ProbabilityUtilTest { class ProbabilityUtilTest {
@ -25,13 +29,13 @@ class ProbabilityUtilTest {
@BeforeEach @BeforeEach
public void setupMocks() throws NoSuchFieldException, IllegalAccessException { public void setupMocks() throws NoSuchFieldException, IllegalAccessException {
this.mmoInstance = Mockito.mock(mcMMO.class); this.mmoInstance = mock(mcMMO.class);
mcMMO.class.getField("p").set(null, mmoInstance); mcMMO.class.getField("p").set(null, mmoInstance);
this.advancedConfig = Mockito.mock(AdvancedConfig.class); this.advancedConfig = mock(AdvancedConfig.class);
Mockito.when(mmoInstance.getAdvancedConfig()).thenReturn(advancedConfig); when(mmoInstance.getAdvancedConfig()).thenReturn(advancedConfig);
Mockito.when(advancedConfig.getImpactChance()).thenReturn(impactChance); when(advancedConfig.getImpactChance()).thenReturn(impactChance);
Mockito.when(advancedConfig.getGreaterImpactChance()).thenReturn(greaterImpactChance); when(advancedConfig.getGreaterImpactChance()).thenReturn(greaterImpactChance);
Mockito.when(advancedConfig.getFastFoodChance()).thenReturn(fastFoodChance); when(advancedConfig.getFastFoodChance()).thenReturn(fastFoodChance);
} }
private static Stream<Arguments> staticChanceSkills() { private static Stream<Arguments> staticChanceSkills() {
@ -46,19 +50,21 @@ class ProbabilityUtilTest {
@ParameterizedTest @ParameterizedTest
@MethodSource("staticChanceSkills") @MethodSource("staticChanceSkills")
void testStaticChanceSkills(SubSkillType subSkillType, double expectedWinPercent) throws InvalidStaticChance { 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); 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++) { for (int i = 0; i < iterations; i++) {
if(staticRandomChance.evaluate()) { if(probability.evaluate()) {
winCount++; winCount++;
} }
} }
double successPercent = (winCount / iterations) * 100; double successPercent = (winCount / iterations) * 100;
System.out.println(successPercent + ", " + expectedWinPercent); System.out.println(successPercent + ", " + expectedWinPercent);
assertEquals(expectedWinPercent, successPercent, 0.01D); assertEquals(expectedWinPercent, successPercent, 0.05D);
} }
} }