Merge pull request #822 from ennorehling/master

Bufix LERNE AUTO
This commit is contained in:
Enno Rehling 2018-12-01 10:45:36 +01:00 committed by GitHub
commit 0710fb796d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 99 additions and 25 deletions

View File

@ -46,7 +46,7 @@ int autostudy_init(scholar scholars[], int max_scholars, unit **units)
st->level = effskill_study(u, st->sk);
st->learn = 0;
st->u = u;
if (++nscholars == max_scholars) {
if (++nscholars > max_scholars) {
log_fatal("you must increase MAXSCHOLARS");
}
}
@ -59,7 +59,6 @@ int autostudy_init(scholar scholars[], int max_scholars, unit **units)
u = u->next;
}
*units = unext;
scholars[nscholars].u = NULL;
if (nscholars > 0) {
qsort(scholars, nscholars, sizeof(scholar), cmp_scholars);
}
@ -125,25 +124,20 @@ void autostudy_run(scholar scholars[], int nscholars)
n = scholars[s].u->number;
}
else {
/* s gets partial credit and we need a new teacher */
/* a part of s gets credited and we need a new teacher: */
teaching(scholars + s, i);
/* we are done with this teacher. any remaining people are regular learners: */
if (scholars[t].u->number > 1) {
/* remain = number - ceil(taught/10); */
int remain = (STUDENTS_PER_TEACHER * scholars[t].u->number - i + STUDENTS_PER_TEACHER - 1) / STUDENTS_PER_TEACHER;
learning(scholars + t, remain);
}
/* we still need to teach n students in this unit: */
n -= i;
i = 0;
/* we want a new teacher for s. if any exists, it's next in the sequence. */
if (++t == si) {
continue;
}
if (scholars[t].level - TEACHDIFFERENCE < scholars[s].level) {
/* next teacher cannot teach, we must skip students. */
/* no remaining teacher can teach this student, so we skip ahead */
do {
learning(scholars + s, (n - i));
i = 0;
/* remaining students learn without a teacher: */
learning(scholars + s, n);
if (++s == se) {
break;
}

View File

@ -62,13 +62,52 @@ static void test_autostudy_init(CuTest *tc) {
CuAssertIntEquals(tc, 0, scholars[0].level);
CuAssertIntEquals(tc, 0, scholars[0].learn);
CuAssertIntEquals(tc, SK_PERCEPTION, scholars[0].sk);
CuAssertPtrEquals(tc, NULL, scholars[1].u);
CuAssertPtrEquals(tc, NULL, ulist);
test_teardown();
}
/**
* Reproduce Bug 2520
*/
static void test_autostudy_run_twoteachers(CuTest *tc) {
scholar scholars[4];
int nscholars;
unit *u1, *u2, *u3, *u4, *ulist;
faction *f;
region *r;
test_setup();
r = test_create_plain(0, 0);
f = test_create_faction(NULL);
u1 = test_create_unit(f, r);
set_level(u1, SK_ENTERTAINMENT, 2);
u1->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
u2 = test_create_unit(f, r);
set_level(u2, SK_ENTERTAINMENT, 2);
u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
u3 = test_create_unit(f, r);
u3->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
set_number(u3, 8);
u4 = test_create_unit(f, r);
u4->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
set_number(u4, 12);
ulist = r->units;
CuAssertIntEquals(tc, 4, nscholars = autostudy_init(scholars, 4, &ulist));
CuAssertPtrEquals(tc, NULL, ulist);
autostudy_run(scholars, nscholars);
CuAssertIntEquals(tc, 0, scholars[0].learn);
CuAssertIntEquals(tc, 0, scholars[1].learn);
CuAssertIntEquals(tc, scholars[2].u->number * 2, scholars[2].learn);
CuAssertIntEquals(tc, scholars[3].u->number * 2, scholars[3].learn);
test_teardown();
}
static void test_autostudy_run(CuTest *tc) {
scholar scholars[4];
int nscholars;
unit *u1, *u2, *u3, *ulist;
faction *f;
region *r;
@ -88,9 +127,9 @@ static void test_autostudy_run(CuTest *tc) {
set_number(u3, 15);
scholars[3].u = NULL;
ulist = r->units;
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, &ulist));
CuAssertIntEquals(tc, 3, nscholars = autostudy_init(scholars, 4, &ulist));
CuAssertPtrEquals(tc, NULL, ulist);
autostudy_run(scholars, 3);
autostudy_run(scholars, nscholars);
CuAssertIntEquals(tc, 1, scholars[0].learn);
CuAssertIntEquals(tc, 20, scholars[1].learn);
CuAssertIntEquals(tc, 15, scholars[2].learn);
@ -99,6 +138,7 @@ static void test_autostudy_run(CuTest *tc) {
static void test_autostudy_run_noteachers(CuTest *tc) {
scholar scholars[4];
int nscholars;
unit *u1, *u2, *u3, *ulist;
faction *f;
region *r;
@ -118,20 +158,50 @@ static void test_autostudy_run_noteachers(CuTest *tc) {
set_number(u3, 15);
scholars[3].u = NULL;
ulist = r->units;
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, &ulist));
CuAssertIntEquals(tc, 3, nscholars = autostudy_init(scholars, 4, &ulist));
CuAssertPtrEquals(tc, NULL, ulist);
autostudy_run(scholars, 3);
autostudy_run(scholars, nscholars);
CuAssertIntEquals(tc, 2, scholars[0].learn);
CuAssertIntEquals(tc, 10, scholars[1].learn);
CuAssertIntEquals(tc, 15, scholars[2].learn);
test_teardown();
}
/**
* If a teacher unit doesn't have enough students, the remaining members study.
*/
static void test_autostudy_run_teachers_learn(CuTest *tc) {
scholar scholars[4];
int nscholars;
unit *u1, *u2, *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_ENTERTAINMENT]);
set_number(u1, 2);
set_level(u1, SK_ENTERTAINMENT, 2);
u2 = test_create_unit(f, r);
u2->thisorder = create_order(K_AUTOSTUDY, f->locale, skillnames[SK_ENTERTAINMENT]);
set_number(u2, 10);
ulist = r->units;
CuAssertIntEquals(tc, 2, nscholars = autostudy_init(scholars, 4, &ulist));
CuAssertPtrEquals(tc, NULL, ulist);
autostudy_run(scholars, nscholars);
CuAssertIntEquals(tc, 1, scholars[0].learn);
CuAssertIntEquals(tc, 20, scholars[1].learn);
test_teardown();
}
/**
* Reproduce Bug 2514
*/
static void test_autostudy_run_skilldiff(CuTest *tc) {
scholar scholars[4];
int nscholars;
unit *u1, *u2, *u3, *ulist;
faction *f;
region *r;
@ -152,9 +222,9 @@ static void test_autostudy_run_skilldiff(CuTest *tc) {
set_number(u3, 10);
scholars[3].u = NULL;
ulist = r->units;
CuAssertIntEquals(tc, 3, autostudy_init(scholars, 4, &ulist));
CuAssertIntEquals(tc, 3, nscholars = autostudy_init(scholars, 4, &ulist));
CuAssertPtrEquals(tc, NULL, ulist);
autostudy_run(scholars, 3);
autostudy_run(scholars, nscholars);
CuAssertIntEquals(tc, 0, scholars[0].learn);
CuAssertIntEquals(tc, 20, scholars[2].learn);
CuAssertIntEquals(tc, 10, scholars[1].learn);
@ -167,6 +237,8 @@ CuSuite *get_automate_suite(void)
SUITE_ADD_TEST(suite, test_autostudy_init);
SUITE_ADD_TEST(suite, test_autostudy_run);
SUITE_ADD_TEST(suite, test_autostudy_run_noteachers);
SUITE_ADD_TEST(suite, test_autostudy_run_teachers_learn);
SUITE_ADD_TEST(suite, test_autostudy_run_twoteachers);
SUITE_ADD_TEST(suite, test_autostudy_run_skilldiff);
return suite;
}

View File

@ -28,6 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <util/language.h>
#include <util/log.h>
#include <util/path.h>
#include <util/password.h>
#include "eressea.h"
#ifdef USE_CURSES
@ -231,6 +232,10 @@ static int parse_args(int argc, char **argv)
i = get_arg(argc, argv, 2, i, &arg, 0);
turn = atoi(arg);
break;
case 'w':
i = get_arg(argc, argv, 2, i, &arg, 0);
bcrypt_workfactor = arg ? atoi(arg) : 0xff;
break;
case 'q':
verbosity = 0;
break;

View File

@ -17,7 +17,7 @@ bool password_is_implemented(cryptalgo_t algo) {
}
const char * password_hash(const char * passwd, cryptalgo_t algo) {
if (algo == PASSWORD_BCRYPT) {
if (algo == PASSWORD_BCRYPT && bcrypt_workfactor != 0) {
char salt[BCRYPT_HASHSIZE];
static char hash[BCRYPT_HASHSIZE];
int ret;
@ -32,9 +32,12 @@ const char * password_hash(const char * passwd, cryptalgo_t algo) {
int password_verify(const char * pwhash, const char * passwd) {
if (pwhash[0] == '$') {
if (pwhash[1] == '2') {
int ret = bcrypt_checkpw(passwd, pwhash);
assert(ret != -1);
return (ret == 0) ? VERIFY_OK : VERIFY_FAIL;
if (bcrypt_workfactor > 0) {
int ret = bcrypt_checkpw(passwd, pwhash);
assert(ret != -1);
return (ret == 0) ? VERIFY_OK : VERIFY_FAIL;
}
return VERIFY_OK;
}
}
return (strcmp(passwd, pwhash) == 0) ? VERIFY_OK : VERIFY_FAIL;