From f08957b513e4957857a1e03cd2e4f327a4a43b86 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 10 Jun 2016 18:24:18 +0200 Subject: [PATCH] test target selection rules for drifting ships. --- src/move.c | 32 +++++++++++++++++++------------- src/move.h | 1 + src/move.test.c | 19 +++++++++++++++++++ src/tests.c | 5 +++-- 4 files changed, 42 insertions(+), 15 deletions(-) diff --git a/src/move.c b/src/move.c index 98ed138fb..34490b9f6 100644 --- a/src/move.c +++ b/src/move.c @@ -783,9 +783,26 @@ static void msg_to_ship_inmates(ship *sh, unit **firstu, unit **lastu, message * msg_release(msg); } +region * drift_target(ship *sh) { + int d, d_offset = rng_int() % MAXDIRECTIONS; + region *rnext = NULL; + for (d = 0; d != MAXDIRECTIONS; ++d) { + region *rn; + direction_t dir = (direction_t)((d + d_offset) % MAXDIRECTIONS); + rn = rconnect(sh->region, dir); + if (rn != NULL && fval(rn->terrain, SAIL_INTO) && check_ship_allowed(sh, rn) >= 0) { + rnext = rn; + if (!fval(rnext->terrain, SEA_REGION)) { + // prefer drifting towards non-ocean regions + break; + } + } + } + return rnext; +} + static void drifting_ships(region * r) { - direction_t d; bool drift = config_get_int("rules.ship.drifting", 1) != 0; double damage_drift = config_get_flt("rules.ship.damage_drift", 0.02); @@ -796,7 +813,6 @@ static void drifting_ships(region * r) region *rnext = NULL; region_list *route = NULL; unit *firstu = r->units, *lastu = NULL, *captain; - int d_offset; direction_t dir = 0; double ovl; @@ -831,17 +847,7 @@ static void drifting_ships(region * r) } else { /* Auswahl einer Richtung: Zuerst auf Land, dann * zufällig. Falls unmögliches Resultat: vergiß es. */ - d_offset = rng_int () % MAXDIRECTIONS; - for (d = 0; d != MAXDIRECTIONS; ++d) { - region *rn; - dir = (direction_t)((d + d_offset) % MAXDIRECTIONS); - rn = rconnect(r, dir); - if (rn != NULL && fval(rn->terrain, SAIL_INTO) && check_ship_allowed(sh, rn) >= 0) { - rnext = rn; - if (!fval(rnext->terrain, SEA_REGION)) - break; - } - } + rnext = drift_target(sh); } if (rnext != NULL) { diff --git a/src/move.h b/src/move.h index bdb4f61c7..9c5893629 100644 --- a/src/move.h +++ b/src/move.h @@ -83,6 +83,7 @@ extern "C" { #define SA_NO_COAST -2 int check_ship_allowed(struct ship *sh, const struct region * r); + struct region * drift_target(struct ship *sh); #ifdef __cplusplus } #endif diff --git a/src/move.test.c b/src/move.test.c index 4c0a07bc5..df12778f3 100644 --- a/src/move.test.c +++ b/src/move.test.c @@ -498,6 +498,24 @@ static void test_follow_ship_msg(CuTest * tc) { test_cleanup(); } +static void test_drifting_ships(CuTest *tc) { + ship *sh; + region *r1, *r2, *r3; + terrain_type *t_ocean, *t_plain; + ship_type *st_boat; + test_cleanup(); + t_ocean = test_create_terrain("ocean", SEA_REGION|SAIL_INTO); + t_plain = test_create_terrain("plain", LAND_REGION|SAIL_INTO); + r1 = test_create_region(0, 0, t_ocean); + r2 = test_create_region(1, 0, t_ocean); + st_boat = test_create_shiptype("boat"); + sh = test_create_ship(r1, st_boat); + CuAssertPtrEquals(tc, r2, drift_target(sh)); + r3 = test_create_region(-1, 0, t_plain); + CuAssertPtrEquals(tc, r3, drift_target(sh)); + test_cleanup(); +} + CuSuite *get_move_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -521,5 +539,6 @@ CuSuite *get_move_suite(void) SUITE_ADD_TEST(suite, test_ship_ridiculous_overload_no_captain); SUITE_ADD_TEST(suite, test_ship_damage_overload); SUITE_ADD_TEST(suite, test_follow_ship_msg); + SUITE_ADD_TEST(suite, test_drifting_ships); return suite; } diff --git a/src/tests.c b/src/tests.c index a0d54a4cc..25e82d578 100644 --- a/src/tests.c +++ b/src/tests.c @@ -196,9 +196,10 @@ ship_type * test_create_shiptype(const char * name) free(stype->coasts); } stype->coasts = - (terrain_type **)malloc(sizeof(terrain_type *) * 2); + (terrain_type **)malloc(sizeof(terrain_type *) * 3); stype->coasts[0] = test_create_terrain("plain", LAND_REGION | FOREST_REGION | WALK_INTO | CAVALRY_REGION | SAIL_INTO | FLY_INTO); - stype->coasts[1] = NULL; + stype->coasts[1] = test_create_terrain("ocean", SEA_REGION | SWIM_INTO | SAIL_INTO | FLY_INTO); + stype->coasts[2] = NULL; if (default_locale) { locale_setstring(default_locale, name, name); }