forked from github/server
Merge pull request #859 from ennorehling/develop
more intelligent batching of automated students.
This commit is contained in:
commit
7ca5b269b3
107
src/automate.c
107
src/automate.c
|
@ -17,50 +17,57 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
static int cmp_scholars(const void *lhs, const void *rhs)
|
static int cmp_scholars(const void *lhs, const void *rhs) {
|
||||||
{
|
|
||||||
const scholar *a = (const scholar *)lhs;
|
const scholar *a = (const scholar *)lhs;
|
||||||
const scholar *b = (const scholar *)rhs;
|
const scholar *b = (const scholar *)rhs;
|
||||||
if (a->skill == b->skill) {
|
return b->level - a->level;
|
||||||
/* sort by level, descending: */
|
|
||||||
return b->level - a->level;
|
|
||||||
}
|
|
||||||
/* order by skill */
|
|
||||||
return a->skill - b->skill;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int autostudy_init(scholar scholars[], int max_scholars, unit **units)
|
int autostudy_init(scholar scholars[], int max_scholars, unit **units, skill_t *o_skill)
|
||||||
{
|
{
|
||||||
unit *unext = NULL, *u = *units;
|
unit *unext = NULL, *u = *units;
|
||||||
faction *f = u->faction;
|
faction *f = u->faction;
|
||||||
int nscholars = 0;
|
int nscholars = 0;
|
||||||
|
skill_t skill = NOSKILL;
|
||||||
while (u) {
|
while (u) {
|
||||||
keyword_t kwd = init_order(u->thisorder, u->faction->locale);
|
if (!fval(u, UFL_MARK)) {
|
||||||
if (kwd == K_AUTOSTUDY) {
|
keyword_t kwd = init_order(u->thisorder, u->faction->locale);
|
||||||
if (long_order_allowed(u)) {
|
if (kwd == K_AUTOSTUDY) {
|
||||||
if (f == u->faction) {
|
if (f == u->faction) {
|
||||||
scholar * st = scholars + nscholars;
|
unext = u->next;
|
||||||
skill_t sk = getskill(u->faction->locale);
|
if (long_order_allowed(u)) {
|
||||||
if (check_student(u, u->thisorder, sk)) {
|
scholar * st = scholars + nscholars;
|
||||||
st->skill = (short)sk;
|
skill_t sk = getskill(u->faction->locale);
|
||||||
st->level = (short)effskill_study(u, sk);
|
if (skill == NOSKILL && sk != NOSKILL) {
|
||||||
st->learn = 0;
|
skill = sk;
|
||||||
st->u = u;
|
if (o_skill) {
|
||||||
if (++nscholars >= max_scholars) {
|
*o_skill = skill;
|
||||||
log_warning("you must increase MAXSCHOLARS");
|
}
|
||||||
*units = u->next;
|
}
|
||||||
return max_scholars;
|
if (check_student(u, u->thisorder, sk)) {
|
||||||
|
if (sk == skill) {
|
||||||
|
fset(u, UFL_MARK);
|
||||||
|
st->level = (short)effskill_study(u, sk);
|
||||||
|
st->learn = 0;
|
||||||
|
st->u = u;
|
||||||
|
if (++nscholars >= max_scholars) {
|
||||||
|
log_warning("you must increase MAXSCHOLARS");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fset(u, UFL_MARK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!unext) {
|
|
||||||
unext = u;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
u = u->next;
|
u = u->next;
|
||||||
}
|
}
|
||||||
|
while (unext && unext->faction != f) {
|
||||||
|
unext = unext->next;
|
||||||
|
}
|
||||||
*units = unext;
|
*units = unext;
|
||||||
if (nscholars > 0) {
|
if (nscholars > 0) {
|
||||||
qsort(scholars, nscholars, sizeof(scholar), cmp_scholars);
|
qsort(scholars, nscholars, sizeof(scholar), cmp_scholars);
|
||||||
|
@ -84,26 +91,25 @@ void autostudy_run(scholar scholars[], int nscholars)
|
||||||
{
|
{
|
||||||
int ti = 0;
|
int ti = 0;
|
||||||
while (ti != nscholars) {
|
while (ti != nscholars) {
|
||||||
int skill = scholars[ti].skill;
|
|
||||||
int t, se, ts = 0, tt = 0, si = ti;
|
int t, se, ts = 0, tt = 0, si = ti;
|
||||||
for (se = ti; se != nscholars && scholars[se].skill == skill; ++se) {
|
for (se = ti; se != nscholars; ++se) {
|
||||||
int mint;
|
int mint;
|
||||||
ts += scholars[se].u->number; /* count total scholars */
|
ts += scholars[se].u->number; /* count total scholars */
|
||||||
mint = (ts + 10) / 11; /* need a minimum of ceil(ts/11) teachers */
|
mint = (ts + 10) / 11; /* need a minimum of ceil(ts/11) teachers */
|
||||||
for (; mint > tt && si != nscholars && scholars[si].skill == skill; ++si) {
|
for (; mint > tt && si != nscholars; ++si) {
|
||||||
tt += scholars[si].u->number;
|
tt += scholars[si].u->number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* now si splits the teachers and students 1:10 */
|
/* now si splits the teachers and students 1:10 */
|
||||||
/* first student must be 2 levels below first teacher: */
|
/* first student must be 2 levels below first teacher: */
|
||||||
for (; si != se && scholars[si].skill == skill; ++si) {
|
for (; si != se; ++si) {
|
||||||
if (scholars[si].level + TEACHDIFFERENCE <= scholars[ti].level) {
|
if (scholars[si].level + TEACHDIFFERENCE <= scholars[ti].level) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tt += scholars[si].u->number;
|
tt += scholars[si].u->number;
|
||||||
}
|
}
|
||||||
/* now si is the first unit we can teach, if we can teach any */
|
/* now si is the first unit we can teach, if we can teach any */
|
||||||
if (si == se || scholars[si].skill != skill) {
|
if (si == se) {
|
||||||
/* there are no students, so standard learning for everyone */
|
/* there are no students, so standard learning for everyone */
|
||||||
for (t = ti; t != se; ++t) {
|
for (t = ti; t != se; ++t) {
|
||||||
learning(scholars + t, scholars[t].u->number);
|
learning(scholars + t, scholars[t].u->number);
|
||||||
|
@ -166,25 +172,36 @@ void autostudy_run(scholar scholars[], int nscholars)
|
||||||
|
|
||||||
void do_autostudy(region *r)
|
void do_autostudy(region *r)
|
||||||
{
|
{
|
||||||
static int max_scholars;
|
|
||||||
unit *units = r->units;
|
|
||||||
scholar scholars[MAXSCHOLARS];
|
|
||||||
static int config;
|
static int config;
|
||||||
static int batchsize = MAXSCHOLARS;
|
static int batchsize = MAXSCHOLARS;
|
||||||
|
static int max_scholars;
|
||||||
|
scholar scholars[MAXSCHOLARS];
|
||||||
|
unit *u;
|
||||||
|
|
||||||
if (config_changed(&config)) {
|
if (config_changed(&config)) {
|
||||||
batchsize = config_get_int("automate.batchsize", MAXSCHOLARS);
|
batchsize = config_get_int("automate.batchsize", MAXSCHOLARS);
|
||||||
assert(batchsize <= MAXSCHOLARS);
|
assert(batchsize <= MAXSCHOLARS);
|
||||||
}
|
}
|
||||||
while (units) {
|
for (u = r->units; u; u = u->next) {
|
||||||
int i, nscholars = autostudy_init(scholars, batchsize, &units);
|
if (!fval(u, UFL_MARK)) {
|
||||||
if (nscholars > max_scholars) {
|
unit *ulist = u;
|
||||||
stats_count("automate.max_scholars", nscholars - max_scholars);
|
int sum_scholars = 0;
|
||||||
max_scholars = nscholars;
|
while (ulist) {
|
||||||
}
|
skill_t skill = NOSKILL;
|
||||||
autostudy_run(scholars, nscholars);
|
int i, nscholars = autostudy_init(scholars, batchsize, &ulist, &skill);
|
||||||
for (i = 0; i != nscholars; ++i) {
|
assert(ulist == NULL || ulist->faction == u->faction);
|
||||||
int days = STUDYDAYS * scholars[i].learn;
|
sum_scholars += nscholars;
|
||||||
learn_skill(scholars[i].u, (skill_t)scholars[i].skill, days);
|
if (sum_scholars > max_scholars) {
|
||||||
|
stats_count("automate.max_scholars", sum_scholars - max_scholars);
|
||||||
|
max_scholars = sum_scholars;
|
||||||
|
}
|
||||||
|
autostudy_run(scholars, nscholars);
|
||||||
|
for (i = 0; i != nscholars; ++i) {
|
||||||
|
int days = STUDYDAYS * scholars[i].learn;
|
||||||
|
learn_skill(scholars[i].u, skill, days);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
freset(u, UFL_MARK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ struct unit;
|
||||||
typedef struct scholar {
|
typedef struct scholar {
|
||||||
struct unit *u;
|
struct unit *u;
|
||||||
int learn;
|
int learn;
|
||||||
short skill;
|
|
||||||
short level;
|
short level;
|
||||||
} scholar;
|
} scholar;
|
||||||
|
|
||||||
|
@ -38,7 +37,7 @@ typedef struct scholar {
|
||||||
|
|
||||||
void do_autostudy(struct region *r);
|
void do_autostudy(struct region *r);
|
||||||
|
|
||||||
int autostudy_init(scholar scholars[], int max_scholars, struct unit **units);
|
int autostudy_init(scholar scholars[], int max_scholars, struct unit **units, skill_t *o_skill);
|
||||||
void autostudy_run(scholar scholars[], int nscholars);
|
void autostudy_run(scholar scholars[], int nscholars);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,6 +21,8 @@ static void test_autostudy_init(CuTest *tc) {
|
||||||
unit *u1, *u2, *u3, *u4, *u5, *ulist;
|
unit *u1, *u2, *u3, *u4, *u5, *ulist;
|
||||||
faction *f;
|
faction *f;
|
||||||
region *r;
|
region *r;
|
||||||
|
message *msg;
|
||||||
|
skill_t skill = NOSKILL;
|
||||||
|
|
||||||
test_setup();
|
test_setup();
|
||||||
mt_create_error(77);
|
mt_create_error(77);
|
||||||
|
@ -34,36 +36,36 @@ static void test_autostudy_init(CuTest *tc) {
|
||||||
u2 = test_create_unit(f, r);
|
u2 = test_create_unit(f, r);
|
||||||
u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
||||||
set_level(u2, SK_ENTERTAINMENT, 2);
|
set_level(u2, SK_ENTERTAINMENT, 2);
|
||||||
u3 = test_create_unit(f, r);
|
|
||||||
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
|
|
||||||
u4 = test_create_unit(f, r);
|
u4 = test_create_unit(f, r);
|
||||||
u4->thisorder = create_order(K_AUTOSTUDY, f->locale, "Dudelidu");
|
u4->thisorder = create_order(K_AUTOSTUDY, f->locale, "Dudelidu");
|
||||||
|
u3 = test_create_unit(f, r);
|
||||||
|
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
|
||||||
u5 = test_create_unit(test_create_faction(NULL), r);
|
u5 = test_create_unit(test_create_faction(NULL), r);
|
||||||
u5->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
|
u5->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
|
||||||
scholars[3].u = NULL;
|
scholars[2].u = NULL;
|
||||||
|
|
||||||
ulist = r->units;
|
ulist = r->units;
|
||||||
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, &ulist));
|
CuAssertIntEquals(tc, 2, autostudy_init(scholars, 4, &ulist, &skill));
|
||||||
CuAssertPtrNotNull(tc, test_find_messagetype(u4->faction->msgs, "error77"));
|
CuAssertIntEquals(tc, SK_ENTERTAINMENT, skill);
|
||||||
CuAssertPtrEquals(tc, u2, scholars[0].u);
|
CuAssertPtrEquals(tc, u2, scholars[0].u);
|
||||||
CuAssertIntEquals(tc, 2, scholars[0].level);
|
CuAssertIntEquals(tc, 2, scholars[0].level);
|
||||||
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
||||||
CuAssertIntEquals(tc, SK_ENTERTAINMENT, scholars[0].skill);
|
|
||||||
CuAssertPtrEquals(tc, u1, scholars[1].u);
|
CuAssertPtrEquals(tc, u1, scholars[1].u);
|
||||||
CuAssertIntEquals(tc, 0, scholars[1].level);
|
CuAssertIntEquals(tc, 0, scholars[1].level);
|
||||||
CuAssertIntEquals(tc, 0, scholars[1].learn);
|
CuAssertIntEquals(tc, 0, scholars[1].learn);
|
||||||
CuAssertIntEquals(tc, SK_ENTERTAINMENT, scholars[1].skill);
|
CuAssertPtrEquals(tc, NULL, scholars[2].u);
|
||||||
CuAssertPtrEquals(tc, u3, scholars[2].u);
|
CuAssertPtrEquals(tc, NULL, ulist);
|
||||||
CuAssertIntEquals(tc, 0, scholars[2].level);
|
|
||||||
CuAssertIntEquals(tc, 0, scholars[2].learn);
|
ulist = u3;
|
||||||
CuAssertIntEquals(tc, SK_PERCEPTION, scholars[2].skill);
|
CuAssertIntEquals(tc, 1, autostudy_init(scholars, 4, &ulist, &skill));
|
||||||
CuAssertPtrEquals(tc, NULL, scholars[3].u);
|
CuAssertIntEquals(tc, SK_PERCEPTION, skill);
|
||||||
CuAssertPtrEquals(tc, u5, ulist);
|
CuAssertPtrEquals(tc, u3, scholars[0].u);
|
||||||
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].level);
|
||||||
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
||||||
CuAssertIntEquals(tc, SK_PERCEPTION, scholars[0].skill);
|
|
||||||
CuAssertPtrEquals(tc, NULL, ulist);
|
CuAssertPtrEquals(tc, NULL, ulist);
|
||||||
|
|
||||||
|
CuAssertPtrNotNull(tc, msg = test_find_messagetype(f->msgs, "error77"));
|
||||||
|
CuAssertPtrEquals(tc, NULL, test_find_messagetype_ex(f->msgs, "error77", msg));
|
||||||
test_teardown();
|
test_teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +78,7 @@ static void test_autostudy_run_twoteachers(CuTest *tc) {
|
||||||
unit *u1, *u2, *u3, *u4, *ulist;
|
unit *u1, *u2, *u3, *u4, *ulist;
|
||||||
faction *f;
|
faction *f;
|
||||||
region *r;
|
region *r;
|
||||||
|
skill_t skill;
|
||||||
|
|
||||||
test_setup();
|
test_setup();
|
||||||
r = test_create_plain(0, 0);
|
r = test_create_plain(0, 0);
|
||||||
|
@ -95,9 +98,10 @@ static void test_autostudy_run_twoteachers(CuTest *tc) {
|
||||||
set_number(u4, 12);
|
set_number(u4, 12);
|
||||||
|
|
||||||
ulist = r->units;
|
ulist = r->units;
|
||||||
CuAssertIntEquals(tc, 4, nscholars = autostudy_init(scholars, 4, &ulist));
|
CuAssertIntEquals(tc, 4, nscholars = autostudy_init(scholars, 4, &ulist, &skill));
|
||||||
CuAssertPtrEquals(tc, NULL, ulist);
|
CuAssertPtrEquals(tc, NULL, ulist);
|
||||||
autostudy_run(scholars, nscholars);
|
autostudy_run(scholars, nscholars);
|
||||||
|
CuAssertIntEquals(tc, SK_ENTERTAINMENT, skill);
|
||||||
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
||||||
CuAssertIntEquals(tc, 0, scholars[1].learn);
|
CuAssertIntEquals(tc, 0, scholars[1].learn);
|
||||||
CuAssertIntEquals(tc, scholars[2].u->number * 2, scholars[2].learn);
|
CuAssertIntEquals(tc, scholars[2].u->number * 2, scholars[2].learn);
|
||||||
|
@ -126,21 +130,34 @@ static void test_autostudy_run(CuTest *tc) {
|
||||||
u3 = test_create_unit(f, r);
|
u3 = test_create_unit(f, r);
|
||||||
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
|
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
|
||||||
set_number(u3, 15);
|
set_number(u3, 15);
|
||||||
scholars[3].u = NULL;
|
|
||||||
|
scholars[2].u = NULL;
|
||||||
ulist = r->units;
|
ulist = r->units;
|
||||||
CuAssertIntEquals(tc, 3, nscholars = autostudy_init(scholars, 4, &ulist));
|
CuAssertIntEquals(tc, 2, nscholars = autostudy_init(scholars, 4, &ulist, NULL));
|
||||||
|
CuAssertIntEquals(tc, UFL_MARK, u1->flags & UFL_MARK);
|
||||||
|
CuAssertIntEquals(tc, UFL_MARK, u2->flags & UFL_MARK);
|
||||||
|
CuAssertIntEquals(tc, 0, u3->flags & UFL_MARK);
|
||||||
CuAssertPtrEquals(tc, NULL, ulist);
|
CuAssertPtrEquals(tc, NULL, ulist);
|
||||||
autostudy_run(scholars, nscholars);
|
autostudy_run(scholars, nscholars);
|
||||||
CuAssertIntEquals(tc, 1, scholars[0].learn);
|
CuAssertIntEquals(tc, 1, scholars[0].learn);
|
||||||
CuAssertIntEquals(tc, 20, scholars[1].learn);
|
CuAssertIntEquals(tc, 20, scholars[1].learn);
|
||||||
CuAssertIntEquals(tc, 15, scholars[2].learn);
|
CuAssertPtrEquals(tc, NULL, scholars[2].u);
|
||||||
|
|
||||||
|
scholars[1].u = NULL;
|
||||||
|
ulist = u3;
|
||||||
|
CuAssertIntEquals(tc, 1, nscholars = autostudy_init(scholars, 4, &ulist, NULL));
|
||||||
|
CuAssertPtrEquals(tc, NULL, ulist);
|
||||||
|
autostudy_run(scholars, nscholars);
|
||||||
|
CuAssertIntEquals(tc, 15, scholars[0].learn);
|
||||||
|
CuAssertPtrEquals(tc, NULL, scholars[1].u);
|
||||||
|
|
||||||
test_teardown();
|
test_teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_autostudy_run_noteachers(CuTest *tc) {
|
static void test_autostudy_run_noteachers(CuTest *tc) {
|
||||||
scholar scholars[4];
|
scholar scholars[4];
|
||||||
int nscholars;
|
int nscholars;
|
||||||
unit *u1, *u2, *u3, *ulist;
|
unit *u1, *u2, *ulist;
|
||||||
faction *f;
|
faction *f;
|
||||||
region *r;
|
region *r;
|
||||||
|
|
||||||
|
@ -148,23 +165,24 @@ static void test_autostudy_run_noteachers(CuTest *tc) {
|
||||||
r = test_create_plain(0, 0);
|
r = test_create_plain(0, 0);
|
||||||
f = test_create_faction(NULL);
|
f = test_create_faction(NULL);
|
||||||
u1 = test_create_unit(f, r);
|
u1 = test_create_unit(f, r);
|
||||||
u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_LUMBERJACK]);
|
u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
||||||
set_number(u1, 2);
|
set_number(u1, 5);
|
||||||
set_level(u1, SK_ENTERTAINMENT, 2);
|
set_level(u1, SK_ENTERTAINMENT, 2);
|
||||||
|
|
||||||
u2 = test_create_unit(f, r);
|
u2 = test_create_unit(f, r);
|
||||||
u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
||||||
set_number(u2, 10);
|
set_number(u2, 7);
|
||||||
u3 = test_create_unit(f, r);
|
set_level(u2, SK_ENTERTAINMENT, 2);
|
||||||
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_PERCEPTION]);
|
|
||||||
set_number(u3, 15);
|
scholars[2].u = NULL;
|
||||||
scholars[3].u = NULL;
|
|
||||||
ulist = r->units;
|
ulist = r->units;
|
||||||
CuAssertIntEquals(tc, 3, nscholars = autostudy_init(scholars, 4, &ulist));
|
CuAssertIntEquals(tc, 2, nscholars = autostudy_init(scholars, 4, &ulist, NULL));
|
||||||
CuAssertPtrEquals(tc, NULL, ulist);
|
CuAssertPtrEquals(tc, NULL, ulist);
|
||||||
autostudy_run(scholars, nscholars);
|
autostudy_run(scholars, nscholars);
|
||||||
CuAssertIntEquals(tc, 2, scholars[0].learn);
|
/* stupid qsort is unstable: */
|
||||||
CuAssertIntEquals(tc, 10, scholars[1].learn);
|
CuAssertIntEquals(tc, 12, scholars[0].learn + scholars[1].learn);
|
||||||
CuAssertIntEquals(tc, 15, scholars[2].learn);
|
CuAssertIntEquals(tc, 35, scholars[0].learn * scholars[1].learn);
|
||||||
|
CuAssertPtrEquals(tc, NULL, scholars[2].u);
|
||||||
test_teardown();
|
test_teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +207,7 @@ static void test_autostudy_run_teachers_learn(CuTest *tc) {
|
||||||
u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
||||||
set_number(u2, 10);
|
set_number(u2, 10);
|
||||||
ulist = r->units;
|
ulist = r->units;
|
||||||
CuAssertIntEquals(tc, 2, nscholars = autostudy_init(scholars, 4, &ulist));
|
CuAssertIntEquals(tc, 2, nscholars = autostudy_init(scholars, 4, &ulist, NULL));
|
||||||
CuAssertPtrEquals(tc, NULL, ulist);
|
CuAssertPtrEquals(tc, NULL, ulist);
|
||||||
autostudy_run(scholars, nscholars);
|
autostudy_run(scholars, nscholars);
|
||||||
CuAssertIntEquals(tc, 1, scholars[0].learn);
|
CuAssertIntEquals(tc, 1, scholars[0].learn);
|
||||||
|
@ -223,7 +241,7 @@ static void test_autostudy_run_skilldiff(CuTest *tc) {
|
||||||
set_number(u3, 10);
|
set_number(u3, 10);
|
||||||
scholars[3].u = NULL;
|
scholars[3].u = NULL;
|
||||||
ulist = r->units;
|
ulist = r->units;
|
||||||
CuAssertIntEquals(tc, 3, nscholars = autostudy_init(scholars, 4, &ulist));
|
CuAssertIntEquals(tc, 3, nscholars = autostudy_init(scholars, 4, &ulist, NULL));
|
||||||
CuAssertPtrEquals(tc, NULL, ulist);
|
CuAssertPtrEquals(tc, NULL, ulist);
|
||||||
autostudy_run(scholars, nscholars);
|
autostudy_run(scholars, nscholars);
|
||||||
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
||||||
|
@ -232,7 +250,7 @@ static void test_autostudy_run_skilldiff(CuTest *tc) {
|
||||||
test_teardown();
|
test_teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_do_autostudy(CuTest *tc) {
|
static void test_autostudy_batches(CuTest *tc) {
|
||||||
scholar scholars[2];
|
scholar scholars[2];
|
||||||
int nscholars;
|
int nscholars;
|
||||||
unit *u1, *u2, *u3, *ulist;
|
unit *u1, *u2, *u3, *ulist;
|
||||||
|
@ -255,23 +273,55 @@ static void test_do_autostudy(CuTest *tc) {
|
||||||
scholars[1].u = NULL;
|
scholars[1].u = NULL;
|
||||||
ulist = r->units;
|
ulist = r->units;
|
||||||
config_set("automate.batchsize", "2");
|
config_set("automate.batchsize", "2");
|
||||||
CuAssertIntEquals(tc, 2, nscholars = autostudy_init(scholars, 2, &ulist));
|
CuAssertIntEquals(tc, 2, nscholars = autostudy_init(scholars, 2, &ulist, NULL));
|
||||||
CuAssertPtrEquals(tc, u3, ulist);
|
CuAssertPtrEquals(tc, u3, ulist);
|
||||||
autostudy_run(scholars, nscholars);
|
autostudy_run(scholars, nscholars);
|
||||||
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
CuAssertIntEquals(tc, 0, scholars[0].learn);
|
||||||
CuAssertIntEquals(tc, 20, scholars[1].learn);
|
CuAssertIntEquals(tc, 20, scholars[1].learn);
|
||||||
CuAssertIntEquals(tc, 1, nscholars = autostudy_init(scholars, 2, &ulist));
|
CuAssertIntEquals(tc, 1, nscholars = autostudy_init(scholars, 2, &ulist, NULL));
|
||||||
autostudy_run(scholars, nscholars);
|
autostudy_run(scholars, nscholars);
|
||||||
CuAssertIntEquals(tc, 10, scholars[0].learn);
|
CuAssertIntEquals(tc, 10, scholars[0].learn);
|
||||||
test_teardown();
|
test_teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_do_autostudy(CuTest *tc) {
|
||||||
|
unit *u1, *u2, *u3, *u4;
|
||||||
|
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_ENTERTAINMENT]);
|
||||||
|
u4 = test_create_unit(test_create_faction(NULL), r);
|
||||||
|
u4->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
|
||||||
|
do_autostudy(r);
|
||||||
|
CuAssertIntEquals(tc, 2, get_level(u1, SK_PERCEPTION));
|
||||||
|
/* impossible to say if u2 is T1 or T2 now */
|
||||||
|
CuAssertIntEquals(tc, 1, get_level(u3, SK_ENTERTAINMENT));
|
||||||
|
CuAssertIntEquals(tc, 1, get_level(u4, SK_ENTERTAINMENT));
|
||||||
|
CuAssertIntEquals(tc, 0, u1->flags & UFL_MARK);
|
||||||
|
CuAssertIntEquals(tc, 0, u2->flags & UFL_MARK);
|
||||||
|
CuAssertIntEquals(tc, 0, u3->flags & UFL_MARK);
|
||||||
|
CuAssertIntEquals(tc, 0, u4->flags & UFL_MARK);
|
||||||
|
test_teardown();
|
||||||
|
}
|
||||||
|
|
||||||
CuSuite *get_automate_suite(void)
|
CuSuite *get_automate_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
SUITE_ADD_TEST(suite, test_do_autostudy);
|
|
||||||
SUITE_ADD_TEST(suite, test_autostudy_init);
|
SUITE_ADD_TEST(suite, test_autostudy_init);
|
||||||
SUITE_ADD_TEST(suite, test_autostudy_run);
|
SUITE_ADD_TEST(suite, test_autostudy_run);
|
||||||
|
SUITE_ADD_TEST(suite, test_do_autostudy);
|
||||||
|
SUITE_ADD_TEST(suite, test_autostudy_batches);
|
||||||
SUITE_ADD_TEST(suite, test_autostudy_run_noteachers);
|
SUITE_ADD_TEST(suite, test_autostudy_run_noteachers);
|
||||||
SUITE_ADD_TEST(suite, test_autostudy_run_teachers_learn);
|
SUITE_ADD_TEST(suite, test_autostudy_run_teachers_learn);
|
||||||
SUITE_ADD_TEST(suite, test_autostudy_run_twoteachers);
|
SUITE_ADD_TEST(suite, test_autostudy_run_twoteachers);
|
||||||
|
|
14
src/tests.c
14
src/tests.c
|
@ -576,15 +576,11 @@ struct message * test_find_messagetype_ex(struct message_list *msgs, const char
|
||||||
struct mlist *ml;
|
struct mlist *ml;
|
||||||
if (!msgs) return 0;
|
if (!msgs) return 0;
|
||||||
for (ml = msgs->begin; ml; ml = ml->next) {
|
for (ml = msgs->begin; ml; ml = ml->next) {
|
||||||
if (strcmp(name, test_get_messagetype(ml->msg)) == 0) {
|
if (prev && ml->msg == prev) {
|
||||||
if (prev) {
|
prev = NULL;
|
||||||
if (ml->msg == prev) {
|
}
|
||||||
prev = NULL;
|
else if (strcmp(name, test_get_messagetype(ml->msg)) == 0) {
|
||||||
}
|
return ml->msg;
|
||||||
}
|
|
||||||
else {
|
|
||||||
return ml->msg;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue