diff --git a/src/laws.c b/src/laws.c index 56abb724f..2e5aafc78 100755 --- a/src/laws.c +++ b/src/laws.c @@ -259,62 +259,58 @@ static void calculate_emigration(region * r) } -static float peasant_luck_factor(void) { - static float factor = -1; - - if (factor < 0) - get_param_int(global.parameters, "rules.peasants.peasantluck.factor", PEASANTLUCK); - return factor; +static float peasant_growth_factor(void) +{ + return get_param_flt(global.parameters, "rules.peasants.growth.factor", + 0.0001F * PEASANTGROWTH); } -static float peasant_growth_factor(void) { - static float factor = -1; - - if (factor < 0) - factor = get_param_flt(global.parameters, "rules.peasants.growth.factor", - 0.0001F * PEASANTGROWTH); - return factor; -} - -/** Bauern vermehren sich */ #ifndef SLOWLUCK -int peasant_luck_effect(int peasants, int luck, int maxp) { - int births=0; - double mean = _min(luck, peasants) - * peasant_luck_factor() - * peasant_growth_factor() - * ((peasants/(float)maxp < .9)?1:PEASANTFORCE); - - births = RAND_ROUND(normalvariate(mean, mean/2+1)); - if (births <= 0) - births = 1; - if (births>peasants/2) - births=peasants/2+1; - return (int)births; +static float peasant_luck_factor(void) +{ + return get_param_int(global.parameters, "rules.peasants.peasantluck.factor", + PEASANTLUCK); +} + +static +int peasant_luck_effect(int peasants, int luck, int maxp, float variance) +{ + int births = 0; + double mean = _min(luck, peasants) * peasant_luck_factor() + * peasant_growth_factor() * ((peasants / (float)maxp < .9) ? 1 : + PEASANTFORCE); + + births = RAND_ROUND(normalvariate(mean, variance * mean)); + if (births <= 0) + births = 1; + if (births > peasants / 2) + births = peasants / 2 + 1; + return (int)births; } #else -int peasant_luck_effect(int peasants, int luck, int maxp) { - int n, births=0; - for (n = peasants; n && luck; --n) { - int chances = 0; +int peasant_luck_effect(int peasants, int luck, int maxp, float variance) { + int n, births=0; + float factor = peasant_growth_factor(); + for (n = peasants; n && luck; --n) { + int chances = 0; - if (luck > 0) { - --luck; - chances += PEASANTLUCK; - } - - while (chances--) { - if (rng_double() < peasant_growth_factor()) { - /* Only raise with 75% chance if peasants have - * reached 90% of maxpopulation */ - if (peasants / (float)maxp < 0.9 || chance(PEASANTFORCE)) { - ++births; - } - } - } + if (luck > 0) { + --luck; + chances += PEASANTLUCK; } - return births; + + while (chances--) { + if (rng_double() < factor) { + /* Only raise with 75% chance if peasants have + * reached 90% of maxpopulation */ + if (peasants / (float)maxp < 0.9 || chance(PEASANTFORCE)) { + ++births; + } + } + } + } + return births; } #endif @@ -336,8 +332,8 @@ static void peasants(region * r) luck = a->data.i * 1000; } - luck = peasant_luck_effect(peasants, luck, maxp); - ADDMSG(&r->msgs, msg_message("peasantluck_success", "births", luck)); + luck = peasant_luck_effect(peasants, luck, maxp, .5); + ADDMSG(&r->msgs, msg_message("peasantluck_success", "births", luck)); peasants += births + luck; } diff --git a/src/laws.test.c b/src/laws.test.c index 117e1fb3c..c6f6fb276 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -1,5 +1,5 @@ #include -#include "laws.h" +#include "laws.c" #include #include @@ -692,6 +692,32 @@ static void test_reserve_self(CuTest *tc) { test_cleanup(); } +static void statistic_test(CuTest *tc, int peasants, int luck, int maxp, + float variance, int min_value, int max_value) +{ + int effect, i; + for (i = 0; i < 1000; ++i) { + effect = peasant_luck_effect(peasants, luck, maxp, variance); + CuAssertTrue(tc, min_value <= effect); + CuAssertTrue(tc, max_value >= effect); + } +} + +static void test_peasant_luck_effect(CuTest *tc) +{ + + set_param(&global.parameters, "rules.peasants.peasantluck.factor", "10"); + set_param(&global.parameters, "rules.peasants.growth.factor", "0.001"); + + statistic_test(tc, 100, 2, 1000, 0, 1, 1); + statistic_test(tc, 1000, 400, 1000, 0, 400 * 10 * 0.001 * .75, + 400 * 10 * 0.001 * .75); + statistic_test(tc, 1000, 1000, 2000, .5, 1, 501); + + set_param(&global.parameters, "rules.peasants.growth.factor", "1"); + statistic_test(tc, 1000, 1000, 1000, 0, 501, 501); +} + CuSuite *get_laws_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -722,6 +748,7 @@ CuSuite *get_laws_suite(void) SUITE_ADD_TEST(suite, test_force_leave_buildings); SUITE_ADD_TEST(suite, test_force_leave_ships); SUITE_ADD_TEST(suite, test_force_leave_ships_on_ocean); + SUITE_ADD_TEST(suite, test_peasant_luck_effect); return suite; } diff --git a/src/util/rng.test.c b/src/util/rng.test.c index d73c23ef4..1740368fb 100644 --- a/src/util/rng.test.c +++ b/src/util/rng.test.c @@ -5,17 +5,17 @@ static void test_rng_round(CuTest * tc) { - double f; - int i,r; - for (i=0; i<1000; ++i) { - f = rng_double(); - r = RAND_ROUND(f); - CuAssertTrue(tc, f >= 0); - CuAssertTrue(tc, r <= (int) f+1); - CuAssertTrue(tc, r >= (int) f); - CuAssertTrue(tc, r == (int) r); - CuAssertTrue(tc, r == RAND_ROUND(r)); - } + double f; + int i, r; + for (i = 0; i < 1000; ++i) { + f = rng_double(); + r = RAND_ROUND(f); + CuAssertTrue(tc, f >= 0); + CuAssertTrue(tc, r <= (int ) f + 1); + CuAssertTrue(tc, r >= (int ) f); + CuAssertTrue(tc, r == (int ) r); + CuAssertTrue(tc, r == RAND_ROUND(r)); + } } CuSuite *get_rng_suite(void)