forked from github/server
Merge branch 'stm2-peasantgrowth_acceleration'
This commit is contained in:
commit
02f92f7932
|
@ -3658,6 +3658,13 @@
|
||||||
<text locale="fr">"$unit($unit): '$order($command)' - The unit already uses $resource($using,0)."</text>
|
<text locale="fr">"$unit($unit): '$order($command)' - The unit already uses $resource($using,0)."</text>
|
||||||
<text locale="en">"$unit($unit): '$order($command)' - The unit already uses $resource($using,0)."</text>
|
<text locale="en">"$unit($unit): '$order($command)' - The unit already uses $resource($using,0)."</text>
|
||||||
</message>
|
</message>
|
||||||
|
<message name="peasantluck_success" section="events">
|
||||||
|
<type>
|
||||||
|
<arg name="births" type="int"/>
|
||||||
|
</type>
|
||||||
|
<text locale="de">"$if($eq($births,1),"Einen Bauern","$int($births) Bauern") besucht unverhofft der Storch."</text>
|
||||||
|
<text locale="en">"The stork paid an unexpected visit to $if($eq($births,1),"a peasant","$int($births) peasants")."</text>
|
||||||
|
</message>
|
||||||
<message name="shipsink" section="events">
|
<message name="shipsink" section="events">
|
||||||
<type>
|
<type>
|
||||||
<arg name="ship" type="ship"/>
|
<arg name="ship" type="ship"/>
|
||||||
|
|
89
src/laws.c
89
src/laws.c
|
@ -258,7 +258,58 @@ static void calculate_emigration(region * r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Bauern vermehren sich */
|
|
||||||
|
static float peasant_growth_factor(void)
|
||||||
|
{
|
||||||
|
return get_param_flt(global.parameters, "rules.peasants.growth.factor", 0.0001F * PEASANTGROWTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SLOWLUCK
|
||||||
|
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() < factor) {
|
||||||
|
/* Only raise with 75% chance if peasants have
|
||||||
|
* reached 90% of maxpopulation */
|
||||||
|
if (peasants / (float)maxp < 0.9 || chance(PEASANTFORCE)) {
|
||||||
|
++births;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return births;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static float peasant_luck_factor(void)
|
||||||
|
{
|
||||||
|
return get_param_flt(global.parameters, "rules.peasants.peasantluck.factor", PEASANTLUCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 births;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void peasants(region * r)
|
static void peasants(region * r)
|
||||||
{
|
{
|
||||||
|
@ -268,42 +319,20 @@ static void peasants(region * r)
|
||||||
int n, satiated;
|
int n, satiated;
|
||||||
int dead = 0;
|
int dead = 0;
|
||||||
|
|
||||||
/* Bis zu 1000 Bauern können Zwillinge bekommen oder 1000 Bauern
|
|
||||||
* wollen nicht! */
|
|
||||||
|
|
||||||
if (peasants > 0 && get_param_int(global.parameters, "rules.peasants.growth", 1)) {
|
if (peasants > 0 && get_param_int(global.parameters, "rules.peasants.growth", 1)) {
|
||||||
int glueck = 0;
|
int luck = 0;
|
||||||
double fraction = peasants * 0.0001F * PEASANTGROWTH;
|
double fraction = peasants * peasant_growth_factor();
|
||||||
int births = (int)fraction;
|
int births = RAND_ROUND(fraction);
|
||||||
attrib *a = a_find(r->attribs, &at_peasantluck);
|
attrib *a = a_find(r->attribs, &at_peasantluck);
|
||||||
|
|
||||||
if (rng_double() < (fraction - births)) {
|
|
||||||
/* because we don't want regions that never grow pga. rounding. */
|
|
||||||
++births;
|
|
||||||
}
|
|
||||||
if (a != NULL) {
|
if (a != NULL) {
|
||||||
glueck = a->data.i * 1000;
|
luck = a->data.i * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (n = peasants; n; --n) {
|
luck = peasant_luck_effect(peasants, luck, maxp, .5);
|
||||||
int chances = 0;
|
ADDMSG(&r->msgs, msg_message("peasantluck_success", "births", luck));
|
||||||
|
|
||||||
if (glueck > 0) {
|
peasants += births + luck;
|
||||||
--glueck;
|
|
||||||
chances += PEASANTLUCK;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (chances--) {
|
|
||||||
if (rng_int() % 10000 < PEASANTGROWTH) {
|
|
||||||
/* Only raise with 75% chance if peasants have
|
|
||||||
* reached 90% of maxpopulation */
|
|
||||||
if (peasants / (float)maxp < 0.9 || chance(PEASANTFORCE)) {
|
|
||||||
++births;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
peasants += births;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Alle werden satt, oder halt soviele für die es auch Geld gibt */
|
/* Alle werden satt, oder halt soviele für die es auch Geld gibt */
|
||||||
|
|
|
@ -106,7 +106,7 @@ extern "C" {
|
||||||
const struct unit *u, int modifier);
|
const struct unit *u, int modifier);
|
||||||
int armedmen(const struct unit *u, bool siege_weapons);
|
int armedmen(const struct unit *u, bool siege_weapons);
|
||||||
void force_leave(struct region *r);
|
void force_leave(struct region *r);
|
||||||
|
int peasant_luck_effect(int peasants, int luck, int maxp, float variance);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <util/base36.h>
|
#include <util/base36.h>
|
||||||
#include <util/language.h>
|
#include <util/language.h>
|
||||||
#include <util/message.h>
|
#include <util/message.h>
|
||||||
|
#include <util/rand.h>
|
||||||
|
|
||||||
#include <CuTest.h>
|
#include <CuTest.h>
|
||||||
#include <tests.h>
|
#include <tests.h>
|
||||||
|
@ -691,6 +692,32 @@ static void test_reserve_self(CuTest *tc) {
|
||||||
test_cleanup();
|
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, (int)(400 * 10 * 0.001 * .75),
|
||||||
|
(int)(400 * 10 * 0.001 * .75));
|
||||||
|
statistic_test(tc, 1000, 1000, 2000, .5f, 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 *get_laws_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
@ -721,6 +748,7 @@ CuSuite *get_laws_suite(void)
|
||||||
SUITE_ADD_TEST(suite, test_force_leave_buildings);
|
SUITE_ADD_TEST(suite, test_force_leave_buildings);
|
||||||
SUITE_ADD_TEST(suite, test_force_leave_ships);
|
SUITE_ADD_TEST(suite, test_force_leave_ships);
|
||||||
SUITE_ADD_TEST(suite, test_force_leave_ships_on_ocean);
|
SUITE_ADD_TEST(suite, test_force_leave_ships_on_ocean);
|
||||||
|
SUITE_ADD_TEST(suite, test_peasant_luck_effect);
|
||||||
|
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
This program may not be used, modified or distributed
|
This program may not be used, modified or distributed
|
||||||
without prior permission by the authors of Eressea.
|
without prior permission by the authors of Eressea.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Contains defines for the "free" game (Eressea) .
|
* Contains defines for the "free" game (Eressea) .
|
||||||
|
@ -25,9 +25,9 @@
|
||||||
|
|
||||||
/* Vermehrungsrate Bauern in 1/10000.
|
/* Vermehrungsrate Bauern in 1/10000.
|
||||||
* TODO: Evt. Berechnungsfehler, reale Vermehrungsraten scheinen höher. */
|
* TODO: Evt. Berechnungsfehler, reale Vermehrungsraten scheinen höher. */
|
||||||
#define PEASANTGROWTH 10
|
#define PEASANTGROWTH 10
|
||||||
#define BATTLE_KILLS_PEASANTS 20
|
#define BATTLE_KILLS_PEASANTS 20
|
||||||
#define PEASANTLUCK 10
|
#define PEASANTLUCK 10
|
||||||
|
|
||||||
#define ROW_FACTOR 3 /* factor for combat row advancement rule */
|
#define ROW_FACTOR 3 /* factor for combat row advancement rule */
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ int RunAllTests(void)
|
||||||
RUN_TESTS(suite, umlaut);
|
RUN_TESTS(suite, umlaut);
|
||||||
RUN_TESTS(suite, unicode);
|
RUN_TESTS(suite, unicode);
|
||||||
RUN_TESTS(suite, strings);
|
RUN_TESTS(suite, strings);
|
||||||
|
RUN_TESTS(suite, rng);
|
||||||
/* kernel */
|
/* kernel */
|
||||||
RUN_TESTS(suite, alliance);
|
RUN_TESTS(suite, alliance);
|
||||||
RUN_TESTS(suite, unit);
|
RUN_TESTS(suite, unit);
|
||||||
|
|
|
@ -9,6 +9,7 @@ bsdstring.test.c
|
||||||
functions.test.c
|
functions.test.c
|
||||||
umlaut.test.c
|
umlaut.test.c
|
||||||
unicode.test.c
|
unicode.test.c
|
||||||
|
rng.test.c
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(_FILES
|
SET(_FILES
|
||||||
|
|
|
@ -39,6 +39,7 @@ extern "C" {
|
||||||
# define rng_double ((rand()%RAND_MAX)/(double)RAND_MAX)
|
# define rng_double ((rand()%RAND_MAX)/(double)RAND_MAX)
|
||||||
# define RNG_RAND_MAX RAND_MAX
|
# define RNG_RAND_MAX RAND_MAX
|
||||||
#endif
|
#endif
|
||||||
|
#define RAND_ROUND(fractional) ((rng_double() < fractional-(int)fractional)?((int)fractional+1):((int)fractional))
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#include <CuTest.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "rng.h"
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CuSuite *get_rng_suite(void)
|
||||||
|
{
|
||||||
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
SUITE_ADD_TEST(suite, test_rng_round);
|
||||||
|
return suite;
|
||||||
|
}
|
Loading…
Reference in New Issue