diff --git a/src/reports.c b/src/reports.c index c23809a32..1e4e43061 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1133,7 +1133,48 @@ void reports_done(void) { } } -static selist *get_regions_distance(region * root, int radius) +int get_regions_distance_arr(region *rc, int radius, region *result[], int size) +{ + int n = 0, i; + + if (size>n) { + result[n++] = rc; + fset(rc, RF_MARK); + } + for (i = 0; i != n; ++i) { + region *r; + int dist; + + r = result[i]; + dist = distance(rc, r); + if (dist n) { + if (!fval(r, RF_MARK) && dist < distance(rc, r)) { + result[n++] = r; + fset(r, RF_MARK); + } + } + else { + return -1; + } + } + } + } + } + for (i = 0; i != n; ++i) { + freset(result[i], RF_MARK); + } + return n; +} + +selist *get_regions_distance(region * root, int radius) { selist *ql, *rlist = NULL; int qi = 0; @@ -1191,9 +1232,8 @@ static void add_seen_nb(faction *f, region *r, seen_mode mode) { /** mark all regions seen by the lighthouse. */ -static void prepare_lighthouse(faction *f, region *r, int range) -{ - selist *ql, *rlist = get_regions_distance(r, range); +static void prepare_lighthouse_ql(faction *f, selist *rlist) { + selist *ql; int qi; for (ql = rlist, qi = 0; ql; selist_advance(&ql, &qi, 1)) { @@ -1205,6 +1245,28 @@ static void prepare_lighthouse(faction *f, region *r, int range) selist_free(rlist); } +static void prepare_lighthouse(faction *f, region *r, int range) +{ + if (range > 3) { + selist *rlist = get_regions_distance(r, range); + prepare_lighthouse_ql(f, rlist); + selist_free(rlist); + } + else { + region *result[64]; + int n, i; + + n = get_regions_distance_arr(r, range, result, 64); + assert(n > 0 && n <= 64); + for (i = 0; i != n; ++i) { + region *rl = result[i]; + if (!fval(rl->terrain, FORBIDDEN_REGION)) { + add_seen_nb(f, rl, seen_lighthouse); + } + } + } +} + void reorder_units(region * r) { unit **unext = &r->units; diff --git a/src/reports.h b/src/reports.h index 6ce14e775..083248fd9 100644 --- a/src/reports.h +++ b/src/reports.h @@ -52,7 +52,8 @@ extern "C" { struct unit *can_find(struct faction *, struct faction *); bool omniscient(const struct faction *f); - + struct selist *get_regions_distance(struct region * root, int radius); + int get_regions_distance_arr(struct region *r, int radius, struct region *result[], int size); /* funktionen zum schreiben eines reports */ void sparagraph(struct strlist **SP, const char *s, unsigned int indent, char mark); void lparagraph(struct strlist **SP, char *s, unsigned int indent, char mark); diff --git a/src/reports.test.c b/src/reports.test.c index f66d94684..fb3bd9c95 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -644,9 +644,68 @@ static void test_seen_travelthru(CuTest *tc) { test_cleanup(); } +static void test_region_distance_max(CuTest *tc) { + region *r; + region *result[64]; + int x, y; + test_setup(); + r = test_create_region(0, 0, 0); + for (x=-3;x<=3;++x) { + for (y = -3; y <= 3; ++y) { + if (x != 0 || y != 0) { + test_create_region(x, y, 0); + } + } + } + CuAssertIntEquals(tc, 1, get_regions_distance_arr(r, 0, result, 64)); + CuAssertIntEquals(tc, 7, get_regions_distance_arr(r, 1, result, 64)); + CuAssertIntEquals(tc, 19, get_regions_distance_arr(r, 2, result, 64)); + CuAssertIntEquals(tc, 37, get_regions_distance_arr(r, 3, result, 64)); + test_cleanup(); +} + +static void test_region_distance(CuTest *tc) { + region *r; + region *result[8]; + test_setup(); + r = test_create_region(0, 0, 0); + CuAssertIntEquals(tc, 1, get_regions_distance_arr(r, 0, result, 8)); + CuAssertPtrEquals(tc, r, result[0]); + CuAssertIntEquals(tc, 1, get_regions_distance_arr(r, 1, result, 8)); + test_create_region(1, 0, 0); + test_create_region(0, 1, 0); + CuAssertIntEquals(tc, 1, get_regions_distance_arr(r, 0, result, 8)); + CuAssertIntEquals(tc, 3, get_regions_distance_arr(r, 1, result, 8)); + CuAssertIntEquals(tc, 3, get_regions_distance_arr(r, 2, result, 8)); + test_cleanup(); +} + +static void test_region_distance_ql(CuTest *tc) { + region *r; + selist *ql; + test_setup(); + r = test_create_region(0, 0, 0); + ql = get_regions_distance(r, 0); + CuAssertIntEquals(tc, 1, selist_length(ql)); + CuAssertPtrEquals(tc, r, selist_get(ql, 0)); + selist_free(ql); + test_create_region(1, 0, 0); + test_create_region(0, 1, 0); + ql = get_regions_distance(r, 1); + CuAssertIntEquals(tc, 3, selist_length(ql)); + selist_free(ql); + ql = get_regions_distance(r, 2); + CuAssertIntEquals(tc, 3, selist_length(ql)); + selist_free(ql); + test_cleanup(); +} + CuSuite *get_reports_suite(void) { CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_region_distance); + SUITE_ADD_TEST(suite, test_region_distance_max); + SUITE_ADD_TEST(suite, test_region_distance_ql); SUITE_ADD_TEST(suite, test_newbie_password_message); SUITE_ADD_TEST(suite, test_prepare_report); SUITE_ADD_TEST(suite, test_seen_neighbours); diff --git a/src/util/crmessage.c b/src/util/crmessage.c index 47bb6bf7d..dd400bf3d 100644 --- a/src/util/crmessage.c +++ b/src/util/crmessage.c @@ -81,7 +81,7 @@ static crmessage_type *crtypes[CRMAXHASH]; static crmessage_type *crt_find(const struct message_type *mtype) { - unsigned int hash = hashstring(mtype->name) % CRMAXHASH; + unsigned int hash = mtype->key % CRMAXHASH; crmessage_type *found = NULL; crmessage_type *type = crtypes[hash]; while (type) { @@ -94,7 +94,7 @@ static crmessage_type *crt_find(const struct message_type *mtype) void crt_register(const struct message_type *mtype) { - unsigned int hash = hashstring(mtype->name) % CRMAXHASH; + unsigned int hash = mtype->key % CRMAXHASH; crmessage_type *crt = crtypes[hash]; while (crt && crt->mtype != mtype) { crt = crt->next; diff --git a/src/util/nrmessage.c b/src/util/nrmessage.c index 717c4dc1f..4b7c5ea75 100644 --- a/src/util/nrmessage.c +++ b/src/util/nrmessage.c @@ -40,7 +40,7 @@ nrmessage_type *nrt_find(const struct locale * lang, const struct message_type * mtype) { nrmessage_type *found = NULL; - unsigned int hash = hashstring(mtype->name) % NRT_MAXHASH; + unsigned int hash = mtype->key % NRT_MAXHASH; nrmessage_type *type = nrtypes[hash]; while (type) { if (type->mtype == mtype) { @@ -101,7 +101,7 @@ void nrt_register(const struct message_type *mtype, const struct locale *lang, const char *string, int level, const char *section) { - unsigned int hash = hashstring(mtype->name) % NRT_MAXHASH; + unsigned int hash = mtype->key % NRT_MAXHASH; nrmessage_type *nrt = nrtypes[hash]; while (nrt && (nrt->lang != lang || nrt->mtype != mtype)) { nrt = nrt->next; diff --git a/tests/runtests.bat b/tests/runtests.bat index 7a58e5762..41b5f8056 100644 --- a/tests/runtests.bat +++ b/tests/runtests.bat @@ -3,7 +3,6 @@ IF EXIST ..\build-vs10 SET BUILD=..\build-vs10\eressea\Debug IF EXIST ..\build-vs11 SET BUILD=..\build-vs11\eressea\Debug IF EXIST ..\build-vs12 SET BUILD=..\build-vs12\eressea\Debug IF EXIST ..\build-vs14 SET BUILD=..\build-vs14\eressea\Debug -IF EXIST ..\build-vs15 SET BUILD=..\build-vs15\eressea\Debug SET SERVER=%BUILD%\eressea.exe %BUILD%\test_eressea.exe %SERVER% ..\scripts\run-tests.lua