From e6b84410b966934fa0fd96ad0924834e3ecc78ff Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 26 May 2019 20:13:02 +0200 Subject: [PATCH 1/3] start work on next major release --- src/kernel/version.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/version.c b/src/kernel/version.c index adbb78e18..e0eda3631 100644 --- a/src/kernel/version.c +++ b/src/kernel/version.c @@ -8,7 +8,7 @@ #ifndef ERESSEA_VERSION /* the version number, if it was not passed to make with -D */ -#define ERESSEA_VERSION "3.20.0" +#define ERESSEA_VERSION "3.21.0" #endif const char *eressea_version(void) { From 6e64d749b0cba90bc165d6a7bdcbbc0ca887076e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 24 Jun 2019 20:51:09 +0200 Subject: [PATCH 2/3] tricks to reduce sizeof(scholar) --- src/automate.c | 20 ++++++++++---------- src/automate.h | 4 ++-- src/automate.test.c | 8 ++++---- src/kernel/faction.c | 2 +- src/kernel/faction.test.c | 1 + src/study.c | 5 +++-- 6 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/automate.c b/src/automate.c index 7fd0c5d62..9f4d85b6c 100644 --- a/src/automate.c +++ b/src/automate.c @@ -20,12 +20,12 @@ static int cmp_scholars(const void *lhs, const void *rhs) { const scholar *a = (const scholar *)lhs; const scholar *b = (const scholar *)rhs; - if (a->sk == b->sk) { + if (a->skill == b->skill) { /* sort by level, descending: */ return b->level - a->level; } /* order by skill */ - return (int)a->sk - (int)b->sk; + return a->skill - b->skill; } int autostudy_init(scholar scholars[], int max_scholars, unit **units) @@ -42,8 +42,8 @@ int autostudy_init(scholar scholars[], int max_scholars, unit **units) scholar * st = scholars + nscholars; skill_t sk = getskill(u->faction->locale); if (check_student(u, u->thisorder, sk)) { - st->sk = sk; - st->level = effskill_study(u, st->sk); + st->skill = (short)sk; + st->level = (short)effskill_study(u, sk); st->learn = 0; st->u = u; if (++nscholars > max_scholars) { @@ -81,26 +81,26 @@ void autostudy_run(scholar scholars[], int nscholars) { int ti = 0; while (ti != nscholars) { - skill_t sk = scholars[ti].sk; + int skill = scholars[ti].skill; int t, se, ts = 0, tt = 0, si = ti; - for (se = ti; se != nscholars && scholars[se].sk == sk; ++se) { + for (se = ti; se != nscholars && scholars[se].skill == skill; ++se) { int mint; ts += scholars[se].u->number; /* count total scholars */ mint = (ts + 10) / 11; /* need a minimum of ceil(ts/11) teachers */ - for (; mint > tt && si != nscholars && scholars[si].sk == sk; ++si) { + for (; mint > tt && si != nscholars && scholars[si].skill == skill; ++si) { tt += scholars[si].u->number; } } /* now si splits the teachers and students 1:10 */ /* first student must be 2 levels below first teacher: */ - for (; si != se && scholars[si].sk == sk; ++si) { + for (; si != se && scholars[si].skill == skill; ++si) { if (scholars[si].level + TEACHDIFFERENCE <= scholars[ti].level) { break; } tt += scholars[si].u->number; } /* now si is the first unit we can teach, if we can teach any */ - if (si == se || scholars[si].sk != sk) { + if (si == se || scholars[si].skill != skill) { /* there are no students, so standard learning for everyone */ for (t = ti; t != se; ++t) { learning(scholars + t, scholars[t].u->number); @@ -177,7 +177,7 @@ void do_autostudy(region *r) autostudy_run(scholars, nscholars); for (i = 0; i != nscholars; ++i) { int days = STUDYDAYS * scholars[i].learn; - learn_skill(scholars[i].u, scholars[i].sk, days); + learn_skill(scholars[i].u, (skill_t)scholars[i].skill, days); } } } diff --git a/src/automate.h b/src/automate.h index 314791b8f..1a6e9638a 100644 --- a/src/automate.h +++ b/src/automate.h @@ -28,9 +28,9 @@ struct unit; typedef struct scholar { struct unit *u; - skill_t sk; - int level; int learn; + short skill; + short level; } scholar; #define STUDENTS_PER_TEACHER 10 diff --git a/src/automate.test.c b/src/automate.test.c index 698cda6be..732ee46a9 100644 --- a/src/automate.test.c +++ b/src/automate.test.c @@ -46,22 +46,22 @@ static void test_autostudy_init(CuTest *tc) { CuAssertPtrEquals(tc, u2, scholars[0].u); CuAssertIntEquals(tc, 2, scholars[0].level); CuAssertIntEquals(tc, 0, scholars[0].learn); - CuAssertIntEquals(tc, SK_ENTERTAINMENT, scholars[0].sk); + CuAssertIntEquals(tc, SK_ENTERTAINMENT, scholars[0].skill); CuAssertPtrEquals(tc, u1, scholars[1].u); CuAssertIntEquals(tc, 0, scholars[1].level); CuAssertIntEquals(tc, 0, scholars[1].learn); - CuAssertIntEquals(tc, SK_ENTERTAINMENT, scholars[1].sk); + CuAssertIntEquals(tc, SK_ENTERTAINMENT, scholars[1].skill); CuAssertPtrEquals(tc, u3, scholars[2].u); CuAssertIntEquals(tc, 0, scholars[2].level); CuAssertIntEquals(tc, 0, scholars[2].learn); - CuAssertIntEquals(tc, SK_PERCEPTION, scholars[2].sk); + CuAssertIntEquals(tc, SK_PERCEPTION, scholars[2].skill); CuAssertPtrEquals(tc, NULL, scholars[3].u); CuAssertPtrEquals(tc, u5, ulist); CuAssertIntEquals(tc, 1, autostudy_init(scholars, 4, &ulist)); CuAssertPtrEquals(tc, u5, scholars[0].u); CuAssertIntEquals(tc, 0, scholars[0].level); CuAssertIntEquals(tc, 0, scholars[0].learn); - CuAssertIntEquals(tc, SK_PERCEPTION, scholars[0].sk); + CuAssertIntEquals(tc, SK_PERCEPTION, scholars[0].skill); CuAssertPtrEquals(tc, NULL, ulist); test_teardown(); } diff --git a/src/kernel/faction.c b/src/kernel/faction.c index 86f74dc03..e3f53fd2c 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -300,7 +300,7 @@ unit *addplayer(region * r, faction * f) } while (rc == NULL || urc == RC_DAEMON || !playerrace(rc)); u->irace = rc; } - f->lastorders = 0; + f->lastorders = turn; return u; } diff --git a/src/kernel/faction.test.c b/src/kernel/faction.test.c index e572cf312..2b7d97a5a 100644 --- a/src/kernel/faction.test.c +++ b/src/kernel/faction.test.c @@ -344,6 +344,7 @@ static void test_addplayer(CuTest *tc) { CuAssertPtrNotNull(tc, u); CuAssertPtrEquals(tc, r, u->region); CuAssertPtrEquals(tc, f, u->faction); + CuAssertIntEquals(tc, turn, u->faction->lastorders); CuAssertIntEquals(tc, i_get(u->items, itype), 10); CuAssertPtrNotNull(tc, u->orders); CuAssertIntEquals(tc, K_WORK, getkeyword(u->orders)); diff --git a/src/study.c b/src/study.c index 8d39e5d5f..eed6a7290 100644 --- a/src/study.c +++ b/src/study.c @@ -860,8 +860,9 @@ void reduce_skill_days(unit *u, skill_t sk, int days) { } } -/** Talente von Daemonen verschieben sich. -*/ +/** + * Talente von Daemonen verschieben sich. + */ void demon_skillchange(unit *u) { skill *sv = u->skills; From 38ff25042b2206d80fe2379a60910de4d59d388a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 24 Jun 2019 21:41:04 +0200 Subject: [PATCH 3/3] Allow batching of too many students. Limit number of batched units to 128. --- src/automate.c | 17 ++++++++++++----- src/automate.h | 1 + src/automate.test.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/automate.c b/src/automate.c index 9f4d85b6c..0764381f2 100644 --- a/src/automate.c +++ b/src/automate.c @@ -1,5 +1,6 @@ #include +#include "kernel/config.h" #include "kernel/faction.h" #include "kernel/messages.h" #include "kernel/order.h" @@ -46,8 +47,10 @@ int autostudy_init(scholar scholars[], int max_scholars, unit **units) st->level = (short)effskill_study(u, sk); st->learn = 0; st->u = u; - if (++nscholars > max_scholars) { - log_fatal("you must increase MAXSCHOLARS"); + if (++nscholars >= max_scholars) { + log_warning("you must increase MAXSCHOLARS"); + *units = u->next; + return max_scholars; } } } @@ -161,15 +164,19 @@ void autostudy_run(scholar scholars[], int nscholars) } } -#define MAXSCHOLARS 512 - void do_autostudy(region *r) { static int max_scholars; unit *units = r->units; scholar scholars[MAXSCHOLARS]; + static int config; + static int batchsize = MAXSCHOLARS; + if (config_changed(&config)) { + batchsize = config_get_int("automate.batchsize", MAXSCHOLARS); + assert(batchsize <= MAXSCHOLARS); + } while (units) { - int i, nscholars = autostudy_init(scholars, MAXSCHOLARS, &units); + int i, nscholars = autostudy_init(scholars, batchsize, &units); if (nscholars > max_scholars) { stats_count("automate.max_scholars", nscholars - max_scholars); max_scholars = nscholars; diff --git a/src/automate.h b/src/automate.h index 1a6e9638a..1a7738363 100644 --- a/src/automate.h +++ b/src/automate.h @@ -33,6 +33,7 @@ typedef struct scholar { short level; } scholar; +#define MAXSCHOLARS 128 #define STUDENTS_PER_TEACHER 10 void do_autostudy(struct region *r); diff --git a/src/automate.test.c b/src/automate.test.c index 732ee46a9..d4e5650e6 100644 --- a/src/automate.test.c +++ b/src/automate.test.c @@ -4,6 +4,7 @@ #include "automate.h" +#include "kernel/config.h" #include "kernel/faction.h" #include "kernel/order.h" #include "kernel/region.h" @@ -231,9 +232,44 @@ static void test_autostudy_run_skilldiff(CuTest *tc) { test_teardown(); } +static void test_do_autostudy(CuTest *tc) { + scholar scholars[2]; + int nscholars; + unit *u1, *u2, *u3, *ulist; + faction *f; + region *r; + + test_setup(); + r = test_create_plain(0, 0); + f = test_create_faction(NULL); + u1 = test_create_unit(f, r); + u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]); + set_number(u1, 1); + set_level(u1, SK_PERCEPTION, 2); + u2 = test_create_unit(f, r); + u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]); + set_number(u2, 10); + u3 = test_create_unit(f, r); + u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]); + set_number(u3, 10); + scholars[1].u = NULL; + ulist = r->units; + config_set("automate.batchsize", "2"); + CuAssertIntEquals(tc, 2, nscholars = autostudy_init(scholars, 2, &ulist)); + CuAssertPtrEquals(tc, u3, ulist); + autostudy_run(scholars, nscholars); + CuAssertIntEquals(tc, 0, scholars[0].learn); + CuAssertIntEquals(tc, 20, scholars[1].learn); + CuAssertIntEquals(tc, 1, nscholars = autostudy_init(scholars, 2, &ulist)); + autostudy_run(scholars, nscholars); + CuAssertIntEquals(tc, 10, scholars[0].learn); + test_teardown(); +} + CuSuite *get_automate_suite(void) { CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_do_autostudy); SUITE_ADD_TEST(suite, test_autostudy_init); SUITE_ADD_TEST(suite, test_autostudy_run); SUITE_ADD_TEST(suite, test_autostudy_run_noteachers);