fix stork message (mantis 2027), add tests

This commit is contained in:
Steffen Mecke 2015-02-01 19:14:06 +01:00 committed by Enno Rehling
parent 0955dd7f05
commit d288c74aaf
6 changed files with 120 additions and 20 deletions

View File

@ -97,8 +97,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <ctype.h>
#include <limits.h>
#include <tests.h>
/* chance that a peasant dies of starvation: */
#define PEASANT_STARVATION_CHANCE 0.9F
/* Pferdevermehrung */
@ -240,7 +238,7 @@ static void calculate_emigration(region * r)
}
for (i = 0; max_immigrants > 0 && i != MAXDIRECTIONS; i++) {
int dir = (turn + i) % MAXDIRECTIONS;
int dir = (turn + 1 + i) % MAXDIRECTIONS;
region *rc = rconnect(r, (direction_t)dir);
if (rc != NULL && fval(rc->terrain, LAND_REGION)) {
@ -265,7 +263,7 @@ static float peasant_growth_factor(void)
}
#ifdef SLOWLUCK
int peasant_luck_effect(int peasants, int luck, int maxp, float variance) {
int peasant_luck_effect(int peasants, int luck, int maxp, double variance) {
int n, births=0;
float factor = peasant_growth_factor();
for (n = peasants; n && luck; --n) {
@ -294,11 +292,15 @@ 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 peasant_luck_effect(int peasants, int luck, int maxp, double variance)
{
int births = 0;
double mean = _min(luck, peasants) * peasant_luck_factor()
* peasant_growth_factor() * ((peasants / (float)maxp < .9) ? 1 :
double mean;
if (luck == 0) return 0;
mean = _min(luck, peasants) * peasant_luck_factor()
* peasant_growth_factor() * ((peasants / (double)maxp < .9) ? 1 :
PEASANTFORCE);
births = RAND_ROUND(normalvariate(mean, variance * mean));
@ -330,9 +332,8 @@ static void peasants(region * r)
}
luck = peasant_luck_effect(peasants, luck, maxp, .5);
#ifdef STORCH_SPAM_BUG_2072
if (luck > 0)
ADDMSG(&r->msgs, msg_message("peasantluck_success", "births", luck));
#endif
peasants += births + luck;
}

View File

@ -106,7 +106,7 @@ extern "C" {
const struct unit *u, int modifier);
int armedmen(const struct unit *u, bool siege_weapons);
void force_leave(struct region *r);
int peasant_luck_effect(int peasants, int luck, int maxp, float variance);
int peasant_luck_effect(int peasants, int luck, int maxp, double variance);
#ifdef __cplusplus
}

View File

@ -6,6 +6,7 @@
#include <kernel/building.h>
#include <kernel/faction.h>
#include <kernel/item.h>
#include <kernel/messages.h>
#include <kernel/order.h>
#include <kernel/race.h>
#include <kernel/region.h>
@ -13,6 +14,7 @@
#include <kernel/terrain.h>
#include <kernel/unit.h>
#include <util/attrib.h>
#include <util/base36.h>
#include <util/language.h>
#include <util/message.h>
@ -693,8 +695,7 @@ static void test_reserve_self(CuTest *tc) {
}
static void statistic_test(CuTest *tc, int peasants, int luck, int maxp,
float variance, int min_value, int max_value)
{
double variance, int min_value, int max_value) {
int effect, i;
for (i = 0; i < 1000; ++i) {
effect = peasant_luck_effect(peasants, luck, maxp, variance);
@ -703,19 +704,50 @@ static void statistic_test(CuTest *tc, int peasants, int luck, int maxp,
}
}
static void test_peasant_luck_effect(CuTest *tc)
{
static void test_peasant_luck_effect(CuTest *tc) {
const char *plf = get_param(global.parameters, "rules.peasants.peasantluck.factor");
const char *gf = get_param(global.parameters, "rules.peasants.growth.factor");
set_param(&global.parameters, "rules.peasants.peasantluck.factor", "10");
set_param(&global.parameters, "rules.peasants.growth.factor", "0.001");
statistic_test(tc, 100, 0, 1000, 0, 0, 0);
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);
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);
set_param(&global.parameters, "rules.peasants.peasantluck.factor", plf);
set_param(&global.parameters, "rules.peasants.growth.factor", gf);
}
static void test_luck_message(CuTest *tc) {
region* r;
const message_type *msg_types[1];
test_cleanup();
r = test_create_region(0, 0, NULL);
rsetpeasants(r, 1);
msg_types[0] = register_msg("peasantluck_success", 1, "births:int");
demographics();
CuAssertPtrEquals_Msg(tc, "unexpected message", (void *)NULL, r->msgs);
attrib *a = (attrib *)a_find(r->attribs, &at_peasantluck);
if (!a)
a = a_add(&r->attribs, a_new(&at_peasantluck));
a->data.i += 10;
demographics();
assert_messages(tc, r->msgs->begin, msg_types, 1, true, 0);
test_cleanup();
}
CuSuite *get_laws_suite(void)
@ -749,6 +781,7 @@ CuSuite *get_laws_suite(void)
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);
SUITE_ADD_TEST(suite, test_luck_message);
return suite;
}

View File

@ -20,6 +20,8 @@
#include <util/message.h>
#include <util/log.h>
#include <CuTest.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
@ -35,7 +37,13 @@ struct race *test_create_race(const char *name)
struct region *test_create_region(int x, int y, const terrain_type *terrain)
{
region *r = new_region(x, y, NULL, 0);
terraform_region(r, terrain ? terrain : get_or_create_terrain("plain"));
if (!terrain) {
terrain_type *t = get_or_create_terrain("plain");
t->size = 1000;
fset(t, LAND_REGION);
terraform_region(r, t);
} else
terraform_region(r, terrain);
rsettrees(r, 0, 0);
rsettrees(r, 1, 0);
rsettrees(r, 2, 0);
@ -213,3 +221,54 @@ const char * test_get_messagetype(const message *msg) {
return name;
}
const message_type *register_msg(const char *type, int n_param, ...) {
char **argv;
va_list args;
int i;
va_start(args, n_param);
argv = malloc(sizeof(char *) * (n_param + 1));
for (i = 0; i < n_param; ++i) {
argv[i] = va_arg(args, char *);
}
argv[n_param] = 0;
va_end(args);
return mt_register(mt_new(type, (const char **)argv));
}
void assert_messages(struct CuTest * tc, struct mlist *msglist, const message_type **types,
int num_msgs, bool exact_match, ...) {
va_list args;
int found, argc;
struct message *msg;
bool match = true;
va_start(args, exact_match);
found = 0;
while (msglist) {
if (found >= num_msgs) {
if (exact_match) {
CuFail(tc, "too many messages");
} else {
break;
}
}
msg = msglist->msg;
if (exact_match || match)
argc = va_arg(args, int);
match = strcmp(types[argc]->name, msg->type->name) == 0;
if (match)
++found;
else if (exact_match)
CuAssertStrEquals(tc, types[argc]->name, msg->type->name);
msglist = msglist->next;
}
CuAssertIntEquals_Msg(tc, "not enough messages", num_msgs, found);
va_end(args);
}

View File

@ -15,11 +15,14 @@ extern "C" {
struct ship;
struct message;
struct message_list;
struct mlist;
struct item_type;
struct building_type;
struct ship_type;
struct terrain_type;
struct CuTest;
void test_cleanup(void);
struct terrain_type * test_create_terrain(const char * name, unsigned int flags);
@ -40,6 +43,10 @@ extern "C" {
const char * test_get_messagetype(const struct message *msg);
struct message * test_get_last_message(struct message_list *mlist);
const struct message_type *register_msg(const char *type, int n_param, ...);
void assert_messages(struct CuTest * tc, struct mlist *msglist, const struct message_type **types,
int num_msgs, bool exact_match, ...);
#ifdef __cplusplus
}
#endif