forked from github/server
fix stork message (mantis 2027), add tests
This commit is contained in:
parent
0955dd7f05
commit
d288c74aaf
|
@ -942,8 +942,8 @@
|
||||||
<type>
|
<type>
|
||||||
<arg name="faction" type="faction"/>
|
<arg name="faction" type="faction"/>
|
||||||
</type>
|
</type>
|
||||||
<text locale="de">"Die Region ist im Besitz von $faction($faction)."</text>
|
<text locale="de">" Die Region ist im Besitz von $faction($faction)."</text>
|
||||||
<text locale="en">"The region is owned by $faction($faction)."</text>
|
<text locale="en">" The region is owned by $faction($faction)."</text>
|
||||||
</message>
|
</message>
|
||||||
<message name="nr_borderlist_postfix" section="nr">
|
<message name="nr_borderlist_postfix" section="nr">
|
||||||
<type>
|
<type>
|
||||||
|
|
19
src/laws.c
19
src/laws.c
|
@ -97,8 +97,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#include <tests.h>
|
|
||||||
|
|
||||||
/* chance that a peasant dies of starvation: */
|
/* chance that a peasant dies of starvation: */
|
||||||
#define PEASANT_STARVATION_CHANCE 0.9F
|
#define PEASANT_STARVATION_CHANCE 0.9F
|
||||||
/* Pferdevermehrung */
|
/* Pferdevermehrung */
|
||||||
|
@ -240,7 +238,7 @@ static void calculate_emigration(region * r)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; max_immigrants > 0 && i != MAXDIRECTIONS; i++) {
|
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);
|
region *rc = rconnect(r, (direction_t)dir);
|
||||||
|
|
||||||
if (rc != NULL && fval(rc->terrain, LAND_REGION)) {
|
if (rc != NULL && fval(rc->terrain, LAND_REGION)) {
|
||||||
|
@ -265,7 +263,7 @@ static float peasant_growth_factor(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SLOWLUCK
|
#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;
|
int n, births=0;
|
||||||
float factor = peasant_growth_factor();
|
float factor = peasant_growth_factor();
|
||||||
for (n = peasants; n && luck; --n) {
|
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);
|
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;
|
int births = 0;
|
||||||
double mean = _min(luck, peasants) * peasant_luck_factor()
|
double mean;
|
||||||
* peasant_growth_factor() * ((peasants / (float)maxp < .9) ? 1 :
|
|
||||||
|
if (luck == 0) return 0;
|
||||||
|
|
||||||
|
mean = _min(luck, peasants) * peasant_luck_factor()
|
||||||
|
* peasant_growth_factor() * ((peasants / (double)maxp < .9) ? 1 :
|
||||||
PEASANTFORCE);
|
PEASANTFORCE);
|
||||||
|
|
||||||
births = RAND_ROUND(normalvariate(mean, variance * mean));
|
births = RAND_ROUND(normalvariate(mean, variance * mean));
|
||||||
|
@ -330,9 +332,8 @@ static void peasants(region * r)
|
||||||
}
|
}
|
||||||
|
|
||||||
luck = peasant_luck_effect(peasants, luck, maxp, .5);
|
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));
|
ADDMSG(&r->msgs, msg_message("peasantluck_success", "births", luck));
|
||||||
#endif
|
|
||||||
peasants += births + luck;
|
peasants += births + luck;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
int peasant_luck_effect(int peasants, int luck, int maxp, double variance);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <kernel/building.h>
|
#include <kernel/building.h>
|
||||||
#include <kernel/faction.h>
|
#include <kernel/faction.h>
|
||||||
#include <kernel/item.h>
|
#include <kernel/item.h>
|
||||||
|
#include <kernel/messages.h>
|
||||||
#include <kernel/order.h>
|
#include <kernel/order.h>
|
||||||
#include <kernel/race.h>
|
#include <kernel/race.h>
|
||||||
#include <kernel/region.h>
|
#include <kernel/region.h>
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
#include <kernel/terrain.h>
|
#include <kernel/terrain.h>
|
||||||
#include <kernel/unit.h>
|
#include <kernel/unit.h>
|
||||||
|
|
||||||
|
#include <util/attrib.h>
|
||||||
#include <util/base36.h>
|
#include <util/base36.h>
|
||||||
#include <util/language.h>
|
#include <util/language.h>
|
||||||
#include <util/message.h>
|
#include <util/message.h>
|
||||||
|
@ -457,7 +459,7 @@ struct pay_fixture {
|
||||||
};
|
};
|
||||||
|
|
||||||
static double level_taxes(const building * b, int level) {
|
static double level_taxes(const building * b, int level) {
|
||||||
return b->size*level*2.0;
|
return b->size * level * 2.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_pay_cmd(struct pay_fixture *fix) {
|
static void setup_pay_cmd(struct pay_fixture *fix) {
|
||||||
|
@ -693,8 +695,7 @@ static void test_reserve_self(CuTest *tc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void statistic_test(CuTest *tc, int peasants, int luck, int maxp,
|
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;
|
int effect, i;
|
||||||
for (i = 0; i < 1000; ++i) {
|
for (i = 0; i < 1000; ++i) {
|
||||||
effect = peasant_luck_effect(peasants, luck, maxp, variance);
|
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.peasantluck.factor", "10");
|
||||||
set_param(&global.parameters, "rules.peasants.growth.factor", "0.001");
|
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, 100, 2, 1000, 0, 1, 1);
|
||||||
statistic_test(tc, 1000, 400, 1000, 0, (int)(400 * 10 * 0.001 * .75),
|
statistic_test(tc, 1000, 400, 1000, 0, (int)(400 * 10 * 0.001 * .75),
|
||||||
(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");
|
set_param(&global.parameters, "rules.peasants.growth.factor", "1");
|
||||||
statistic_test(tc, 1000, 1000, 1000, 0, 501, 501);
|
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)
|
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);
|
||||||
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);
|
SUITE_ADD_TEST(suite, test_peasant_luck_effect);
|
||||||
|
SUITE_ADD_TEST(suite, test_luck_message);
|
||||||
|
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
61
src/tests.c
61
src/tests.c
|
@ -20,6 +20,8 @@
|
||||||
#include <util/message.h>
|
#include <util/message.h>
|
||||||
#include <util/log.h>
|
#include <util/log.h>
|
||||||
|
|
||||||
|
#include <CuTest.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.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)
|
struct region *test_create_region(int x, int y, const terrain_type *terrain)
|
||||||
{
|
{
|
||||||
region *r = new_region(x, y, NULL, 0);
|
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, 0, 0);
|
||||||
rsettrees(r, 1, 0);
|
rsettrees(r, 1, 0);
|
||||||
rsettrees(r, 2, 0);
|
rsettrees(r, 2, 0);
|
||||||
|
@ -213,3 +221,54 @@ const char * test_get_messagetype(const message *msg) {
|
||||||
return name;
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -15,11 +15,14 @@ extern "C" {
|
||||||
struct ship;
|
struct ship;
|
||||||
struct message;
|
struct message;
|
||||||
struct message_list;
|
struct message_list;
|
||||||
|
struct mlist;
|
||||||
struct item_type;
|
struct item_type;
|
||||||
struct building_type;
|
struct building_type;
|
||||||
struct ship_type;
|
struct ship_type;
|
||||||
struct terrain_type;
|
struct terrain_type;
|
||||||
|
|
||||||
|
struct CuTest;
|
||||||
|
|
||||||
void test_cleanup(void);
|
void test_cleanup(void);
|
||||||
|
|
||||||
struct terrain_type * test_create_terrain(const char * name, unsigned int flags);
|
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);
|
const char * test_get_messagetype(const struct message *msg);
|
||||||
struct message * test_get_last_message(struct message_list *mlist);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue