From 6ecd172ff415d77bb0aef18d200a49d6b247b605 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 25 Feb 2020 20:35:55 +0100 Subject: [PATCH 1/3] LERNE AUTO: fix tests and logic some more. still haven't fixed the actual bug, algorithm is wrong. --- src/automate.c | 14 ++++++++++---- src/automate.test.c | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/automate.c b/src/automate.c index 960c67a4c..86deda3c0 100644 --- a/src/automate.c +++ b/src/automate.c @@ -77,7 +77,8 @@ int autostudy_init(scholar scholars[], int max_scholars, unit **units, skill_t * static void teaching(scholar *s, int n) { assert(n <= s->u->number); - s->learn += n; + // doppelter Effekt mit Lehrer: + s->learn += n * 2; s->u->flags |= UFL_LONGACTION; } @@ -96,7 +97,7 @@ void autostudy_run(scholar scholars[], int nscholars) 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 - 1; ++si) { + for (; mint > tt && si != nscholars; ++si) { tt += scholars[si].u->number; } } @@ -125,10 +126,10 @@ void autostudy_run(scholar scholars[], int nscholars) /* t has more than enough teaching capacity for s */ i -= n; teaching(scholars + s, n); - learning(scholars + s, scholars[s].u->number); /* next student, please: */ if (++s == se) { - continue; + /* no more students */ + break; } n = scholars[s].u->number; } @@ -163,8 +164,13 @@ void autostudy_run(scholar scholars[], int nscholars) } ++t; for (; t < si; ++t) { + /* teachers that did not teach */ learning(scholars + t, scholars[t].u->number); } + for (; s < se; ++s) { + /* students that were not taught */ + learning(scholars + s, scholars[s].u->number); + } } ti = se; } diff --git a/src/automate.test.c b/src/automate.test.c index adb4c1da7..963cea4cd 100644 --- a/src/automate.test.c +++ b/src/automate.test.c @@ -139,7 +139,43 @@ static void test_autostudy_run_bigunit(CuTest *tc) { autostudy_run(scholars, nscholars); CuAssertIntEquals(tc, SK_ENTERTAINMENT, skill); CuAssertIntEquals(tc, 0, scholars[0].learn); - CuAssertIntEquals(tc, 200, scholars[1].learn); + CuAssertIntEquals(tc, 1200, scholars[1].learn); + + test_teardown(); +} + +static void test_autostudy_run_few_teachers(CuTest *tc) { + scholar scholars[4]; + int nscholars; + unit *u1, *u2, *u3, *ulist; + faction *f; + region *r; + skill_t skill; + + test_setup(); + r = test_create_plain(0, 0); + f = test_create_faction(NULL); + u1 = test_create_unit(f, r); + set_number(u1, 20); + set_level(u1, SK_ENTERTAINMENT, 16); + u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]); + u2 = test_create_unit(f, r); + set_number(u2, 500); + set_level(u2, SK_ENTERTAINMENT, 10); + u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]); + u3 = test_create_unit(f, r); + set_number(u3, 100); + set_level(u3, SK_ENTERTAINMENT, 10); + u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]); + + ulist = r->units; + CuAssertIntEquals(tc, 3, nscholars = autostudy_init(scholars, 4, &ulist, &skill)); + CuAssertPtrEquals(tc, NULL, ulist); + autostudy_run(scholars, nscholars); + CuAssertIntEquals(tc, SK_ENTERTAINMENT, skill); + CuAssertIntEquals(tc, 0, scholars[0].learn); + CuAssertIntEquals(tc, 100, scholars[1].learn); + CuAssertIntEquals(tc, 700, scholars[2].learn); test_teardown(); } @@ -360,6 +396,7 @@ CuSuite *get_automate_suite(void) SUITE_ADD_TEST(suite, test_autostudy_run_teachers_learn); SUITE_ADD_TEST(suite, test_autostudy_run_twoteachers); SUITE_ADD_TEST(suite, test_autostudy_run_bigunit); + SUITE_ADD_TEST(suite, test_autostudy_run_few_teachers); SUITE_ADD_TEST(suite, test_autostudy_run_skilldiff); return suite; } From 41cf41120f087214483c49a079969c772ec1fe74 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 1 Mar 2020 14:24:21 +0100 Subject: [PATCH 2/3] Bug 2640: Fehler in LERNE AUTO bei teilweisen Lehrern. --- src/automate.c | 38 ++++++++++++++++++++++---------------- src/automate.test.c | 42 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 19 deletions(-) diff --git a/src/automate.c b/src/automate.c index 86deda3c0..ecb130fff 100644 --- a/src/automate.c +++ b/src/automate.c @@ -20,7 +20,8 @@ static int cmp_scholars(const void *lhs, const void *rhs) { const scholar *a = (const scholar *)lhs; const scholar *b = (const scholar *)rhs; - return b->level - a->level; + int diff = b->level - a->level; + return (diff != 0) ? diff : b->u->number - a->u->number; } int autostudy_init(scholar scholars[], int max_scholars, unit **units, skill_t *o_skill) @@ -78,7 +79,7 @@ int autostudy_init(scholar scholars[], int max_scholars, unit **units, skill_t * static void teaching(scholar *s, int n) { assert(n <= s->u->number); // doppelter Effekt mit Lehrer: - s->learn += n * 2; + s->learn += n; s->u->flags |= UFL_LONGACTION; } @@ -92,27 +93,31 @@ void autostudy_run(scholar scholars[], int nscholars) { int ti = 0; while (ti != nscholars) { - int t, se, ts = 0, tt = 0, si = ti; - for (se = ti; se != nscholars; ++se) { - int mint; - ts += scholars[se].u->number; /* count total scholars */ + int t, ts = 0, tt = 0, si = ti, mint = 0, ns = 0; + for (t = ti; t != nscholars; ++t) { + ts += scholars[t].u->number; /* count total scholars */ mint = (ts + 10) / 11; /* need a minimum of ceil(ts/11) teachers */ for (; mint > tt && si != nscholars; ++si) { tt += scholars[si].u->number; } } + if (mint < tt) { + /* die Einheit si-1 hat einen Mix aus Lehrer und Schüler */ + --si; + ns = tt - mint; + } /* now si splits the teachers and students 1:10 */ /* first student must be 2 levels below first teacher: */ - for (; si != se; ++si) { + for (; si != nscholars; ++si) { if (scholars[si].level + TEACHDIFFERENCE <= scholars[ti].level) { break; } - tt += scholars[si].u->number; + ns = 0; } /* now si is the first unit we can teach, if we can teach any */ - if (si == se) { + if (si == nscholars) { /* there are no students, so standard learning for everyone */ - for (t = ti; t != se; ++t) { + for (t = ti; t != nscholars; ++t) { learning(scholars + t, scholars[t].u->number); } } @@ -120,14 +125,15 @@ void autostudy_run(scholar scholars[], int nscholars) /* invariant: unit ti can still teach i students */ int i = scholars[ti].u->number * STUDENTS_PER_TEACHER; /* invariant: unit si has n students that can still be taught */ - int s, n = scholars[si].u->number; - for (t = ti, s = si; t != si && s != se; ) { + int s, n = (ns > 0) ? ns : scholars[si].u->number; + for (t = ti, s = si; t != si && s != nscholars; ) { if (i >= n) { /* t has more than enough teaching capacity for s */ i -= n; teaching(scholars + s, n); + learning(scholars + s, scholars[s].u->number); /* next student, please: */ - if (++s == se) { + if (++s == nscholars) { /* no more students */ break; } @@ -148,7 +154,7 @@ void autostudy_run(scholar scholars[], int nscholars) do { /* remaining students learn without a teacher: */ learning(scholars + s, n); - if (++s == se) { + if (++s == nscholars) { break; } n = scholars[s].u->number; @@ -167,12 +173,12 @@ void autostudy_run(scholar scholars[], int nscholars) /* teachers that did not teach */ learning(scholars + t, scholars[t].u->number); } - for (; s < se; ++s) { + for (; s < nscholars; ++s) { /* students that were not taught */ learning(scholars + s, scholars[s].u->number); } } - ti = se; + ti = nscholars; } } diff --git a/src/automate.test.c b/src/automate.test.c index 963cea4cd..1e38a7605 100644 --- a/src/automate.test.c +++ b/src/automate.test.c @@ -165,7 +165,7 @@ static void test_autostudy_run_few_teachers(CuTest *tc) { u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]); u3 = test_create_unit(f, r); set_number(u3, 100); - set_level(u3, SK_ENTERTAINMENT, 10); + set_level(u3, SK_ENTERTAINMENT, 9); u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]); ulist = r->units; @@ -174,8 +174,43 @@ static void test_autostudy_run_few_teachers(CuTest *tc) { autostudy_run(scholars, nscholars); CuAssertIntEquals(tc, SK_ENTERTAINMENT, skill); CuAssertIntEquals(tc, 0, scholars[0].learn); - CuAssertIntEquals(tc, 100, scholars[1].learn); - CuAssertIntEquals(tc, 700, scholars[2].learn); + CuAssertIntEquals(tc, 700, scholars[1].learn); + CuAssertIntEquals(tc, 100, scholars[2].learn); + + test_teardown(); +} + +static void test_autostudy_run_few_teachers_reverse(CuTest *tc) { + scholar scholars[4]; + int nscholars; + unit *u1, *u2, *u3, *ulist; + faction *f; + region *r; + skill_t skill; + + test_setup(); + r = test_create_plain(0, 0); + f = test_create_faction(NULL); + u1 = test_create_unit(f, r); + set_number(u1, 20); + set_level(u1, SK_ENTERTAINMENT, 16); + u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]); + u2 = test_create_unit(f, r); + set_number(u2, 100); + set_level(u2, SK_ENTERTAINMENT, 10); + u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]); + u3 = test_create_unit(f, r); + set_number(u3, 500); + set_level(u3, SK_ENTERTAINMENT, 9); + u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]); + + ulist = r->units; + CuAssertIntEquals(tc, 3, nscholars = autostudy_init(scholars, 4, &ulist, &skill)); + CuAssertPtrEquals(tc, NULL, ulist); + autostudy_run(scholars, nscholars); + CuAssertIntEquals(tc, SK_ENTERTAINMENT, skill); + CuAssertIntEquals(tc, 0, scholars[0].learn); + CuAssertIntEquals(tc, 800, scholars[1].learn + scholars[2].learn); test_teardown(); } @@ -397,6 +432,7 @@ CuSuite *get_automate_suite(void) SUITE_ADD_TEST(suite, test_autostudy_run_twoteachers); SUITE_ADD_TEST(suite, test_autostudy_run_bigunit); SUITE_ADD_TEST(suite, test_autostudy_run_few_teachers); + SUITE_ADD_TEST(suite, test_autostudy_run_few_teachers_reverse); SUITE_ADD_TEST(suite, test_autostudy_run_skilldiff); return suite; } From eb16d7bf4765013d79b15a7d682c9119b6b419bd Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 1 Mar 2020 17:55:07 +0100 Subject: [PATCH 3/3] =?UTF-8?q?Bug=202645=20TARNE=20[Stufe]=20reagiert=20a?= =?UTF-8?q?uf=20Talent=C3=A4nderungen.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/attributes/stealth.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/attributes/stealth.c b/src/attributes/stealth.c index ae00e8721..4a9b6f044 100644 --- a/src/attributes/stealth.c +++ b/src/attributes/stealth.c @@ -37,8 +37,13 @@ int u_geteffstealth(const unit *u) if (skill_enabled(SK_STEALTH)) { if (u->flags & UFL_STEALTH) { attrib *a = a_find(u->attribs, &at_stealth); - if (a != NULL) + if (a != NULL) { + int eff = effskill(u, SK_STEALTH, u->region); + if (eff < a->data.i) { + return eff; + } return a->data.i; + } } } return -1;