Add a test for the effect of buildings in battles, and a file to test pieces of the combat code from C in the future.

Add some testing support for terrains and buildings.
This commit is contained in:
Enno Rehling 2011-03-12 17:01:20 -08:00
parent 31edf06d05
commit 89b3b3161f
8 changed files with 122 additions and 33 deletions

View file

@ -29,10 +29,7 @@ static void market_curse(CuTest * tc)
btype->_name = "market"; btype->_name = "market";
bt_register(btype); bt_register(btype);
terrain = calloc(1, sizeof(terrain_type)); terrain = test_create_terrain("plain", LAND_REGION | WALK_INTO);
terrain->_name = strdup("plain");
register_terrain(terrain);
terrain->flags = LAND_REGION | WALK_INTO;
for (x = 0; x != 3; ++x) { for (x = 0; x != 3; ++x) {
for (y = 0; y != 3; ++y) { for (y = 0; y != 3; ++y) {

View file

@ -90,6 +90,7 @@
<ClCompile Include="kernel\alchemy.c" /> <ClCompile Include="kernel\alchemy.c" />
<ClCompile Include="kernel\alliance.c" /> <ClCompile Include="kernel\alliance.c" />
<ClCompile Include="kernel\battle.c" /> <ClCompile Include="kernel\battle.c" />
<ClCompile Include="kernel\battle_test.c" />
<ClCompile Include="kernel\binarystore.c" /> <ClCompile Include="kernel\binarystore.c" />
<ClCompile Include="kernel\build.c" /> <ClCompile Include="kernel\build.c" />
<ClCompile Include="kernel\building.c" /> <ClCompile Include="kernel\building.c" />

View file

@ -295,6 +295,9 @@
<ClCompile Include="kernel\move_test.c"> <ClCompile Include="kernel\move_test.c">
<Filter>kernel</Filter> <Filter>kernel</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="kernel\battle_test.c">
<Filter>kernel</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="kernel\alchemy.h"> <ClInclude Include="kernel\alchemy.h">

View file

@ -1892,7 +1892,7 @@ static void do_extra_spell(troop at, const att * a)
} }
} }
static int skilldiff(troop at, troop dt, int dist) int skilldiff(troop at, troop dt, int dist)
{ {
fighter *af = at.fighter, *df = dt.fighter; fighter *af = at.fighter, *df = dt.fighter;
unit *au = af->unit, *du = df->unit; unit *au = af->unit, *du = df->unit;
@ -2442,7 +2442,7 @@ double fleechance(unit * u)
/** add a new army to the conflict /** add a new army to the conflict
* beware: armies need to be added _at the beginning_ of the list because * beware: armies need to be added _at the beginning_ of the list because
* otherwise join_allies() will get into trouble */ * otherwise join_allies() will get into trouble */
static side *make_side(battle * b, const faction * f, const group * g, side *make_side(battle * b, const faction * f, const group * g,
unsigned int flags, const faction * stealthfaction) unsigned int flags, const faction * stealthfaction)
{ {
side *s1 = b->sides + b->nsides; side *s1 = b->sides + b->nsides;
@ -3656,13 +3656,18 @@ static const char *simplename(region * r)
return name; return name;
} }
static battle *make_battle(region * r) battle *make_battle(region * r)
{ {
battle *b = calloc(1, sizeof(struct battle)); battle *b = (battle *)calloc(1, sizeof(battle));
unit *u; unit *u;
bfaction *bf; bfaction *bf;
building * bld;
static int max_fac_no = 0; /* need this only once */ static int max_fac_no = 0; /* need this only once */
/* Alle Mann raus aus der Burg! */
for (bld = r->buildings; bld != NULL; bld = bld->next)
bld->sizeleft = bld->size;
if (battledebug) { if (battledebug) {
char zText[MAX_PATH]; char zText[MAX_PATH];
char zFilename[MAX_PATH]; char zFilename[MAX_PATH];
@ -3693,7 +3698,7 @@ static battle *make_battle(region * r)
break; break;
} }
if (!bf) { if (!bf) {
bf = calloc(sizeof(bfaction), 1); bf = (bfaction *)calloc(sizeof(bfaction), 1);
++b->nfactions; ++b->nfactions;
bf->faction = u->faction; bf->faction = u->faction;
bf->next = b->factions; bf->next = b->factions;
@ -4062,11 +4067,6 @@ static boolean init_battle(region * r, battle ** bp)
battle *b = NULL; battle *b = NULL;
unit *u; unit *u;
boolean fighting = false; boolean fighting = false;
building *bu;
/* Alle Mann raus aus der Burg! */
for (bu = r->buildings; bu != NULL; bu = bu->next)
bu->sizeleft = bu->size;
/* list_foreach geht nicht, wegen flucht */ /* list_foreach geht nicht, wegen flucht */
for (u = r->units; u != NULL; u = u->next) { for (u = r->units; u != NULL; u = u->next) {

View file

@ -261,14 +261,20 @@ extern "C" {
extern struct region *fleeregion(const struct unit *u); extern struct region *fleeregion(const struct unit *u);
#endif #endif
extern struct fighter *select_corpse(struct battle *b, struct fighter *af); extern struct fighter *select_corpse(struct battle *b, struct fighter *af);
extern fighter *make_fighter(struct battle *b, struct unit *u, side * s,
boolean attack);
extern int statusrow(int status); extern int statusrow(int status);
extern void drain_exp(struct unit *u, int d); extern void drain_exp(struct unit *u, int d);
extern void kill_troop(troop dt); extern void kill_troop(troop dt);
extern void remove_troop(troop dt); /* not the same as the badly named rmtroop */ extern void remove_troop(troop dt); /* not the same as the badly named rmtroop */
extern boolean is_attacker(const fighter * fig); extern boolean is_attacker(const fighter * fig);
extern struct battle *make_battle(struct region * r);
extern fighter *make_fighter(struct battle *b, struct unit *u, side * s,
boolean attack);
extern struct side *make_side(struct battle * b, const struct faction * f,
const struct group * g, unsigned int flags,
const struct faction * stealthfaction);
extern int skilldiff(troop at, troop dt, int dist);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

64
src/kernel/battle_test.c Normal file
View file

@ -0,0 +1,64 @@
#include <kernel/types.h>
#include <platform.h>
#include "battle.h"
#include "building.h"
#include "faction.h"
#include "race.h"
#include "region.h"
#include "unit.h"
#include "tests.h"
#include <cutest/CuTest.h>
static int add_two(building * b, unit * u) {
return 2;
}
static void test_building_bonus(CuTest * tc)
{
unit *du, *au;
region *r;
building * bld;
fighter *df, *af;
battle *b;
side *ds, *as;
int diff;
troop dt, at;
building_type * btype;
test_cleanup();
test_create_world();
r = findregion(0, 0);
btype = bt_find("castle");
btype->protection = &add_two;
bld = test_create_building(r, btype);
bld->size = 10;
du = test_create_unit(test_create_faction(rc_find("human")), r);
du->building = bld;
au = test_create_unit(test_create_faction(rc_find("human")), r);
b = make_battle(r);
ds = make_side(b, du->faction, 0, 0, 0);
df = make_fighter(b, du, ds, false);
CuAssertPtrEquals(tc, bld, df->building);
as = make_side(b, au->faction, 0, 0, 0);
af = make_fighter(b, au, as, true);
CuAssertPtrEquals(tc, 0, af->building);
dt.fighter = df;
dt.index = 0;
at.fighter = af;
at.index = 0;
diff = skilldiff(at, dt, 0);
CuAssertIntEquals(tc, -2, diff);
}
CuSuite *get_battle_suite(void)
{
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_building_bonus);
return suite;
}

View file

@ -8,6 +8,7 @@
#include <util/quicklist_test.c> #include <util/quicklist_test.c>
#include <kernel/move_test.c> #include <kernel/move_test.c>
#include <kernel/curse_test.c> #include <kernel/curse_test.c>
#include <kernel/battle_test.c>
#include <gamecode/laws_test.c> #include <gamecode/laws_test.c>
CuSuite *get_market_suite(void); CuSuite *get_market_suite(void);
@ -20,6 +21,8 @@ CuSuite *get_market_suite(void);
#include <kernel/faction.h> #include <kernel/faction.h>
#include <kernel/building.h> #include <kernel/building.h>
#include <kernel/ship.h> #include <kernel/ship.h>
#include <kernel/terrain.h>
#include <util/functions.h>
#include <util/language.h> #include <util/language.h>
int RunAllTests(void) int RunAllTests(void)
@ -37,6 +40,7 @@ int RunAllTests(void)
CuSuiteAddSuite(suite, get_market_suite()); CuSuiteAddSuite(suite, get_market_suite());
CuSuiteAddSuite(suite, get_move_suite()); CuSuiteAddSuite(suite, get_move_suite());
CuSuiteAddSuite(suite, get_laws_suite()); CuSuiteAddSuite(suite, get_laws_suite());
CuSuiteAddSuite(suite, get_battle_suite());
CuSuiteRun(suite); CuSuiteRun(suite);
CuSuiteSummary(suite, output); CuSuiteSummary(suite, output);
@ -49,12 +53,13 @@ int RunAllTests(void)
struct race *test_create_race(const char *name) struct race *test_create_race(const char *name)
{ {
race *rc = rc_add(rc_new("human")); race *rc = rc_add(rc_new(name));
rc->flags |= RCF_PLAYERRACE;
rc->maintenance = 10;
return rc; return rc;
} }
struct region *test_create_region(int x, int y, struct region *test_create_region(int x, int y, const terrain_type *terrain)
const struct terrain_type *terrain)
{ {
region *r = new_region(x, y, NULL, 0); region *r = new_region(x, y, NULL, 0);
terraform_region(r, terrain); terraform_region(r, terrain);
@ -80,11 +85,31 @@ struct unit *test_create_unit(struct faction *f, struct region *r)
void test_cleanup(void) void test_cleanup(void)
{ {
test_clear_terrains();
global.functions.maintenance = NULL; global.functions.maintenance = NULL;
global.functions.wage = NULL; global.functions.wage = NULL;
free_gamedata(); free_gamedata();
} }
terrain_type *
test_create_terrain(const char * name, unsigned int flags)
{
terrain_type * t;
assert(!get_terrain(name));
t = (terrain_type*)calloc(1, sizeof(terrain_type));
t->_name = strdup(name);
t->flags = flags;
register_terrain(t);
return t;
}
building * test_create_building(region * r, const building_type * btype)
{
building * b = new_building(btype, r, default_locale);
b->size = btype->maxsize>0?btype->maxsize:1;
return b;
}
/** creates a small world and some stuff in it. /** creates a small world and some stuff in it.
* two terrains: 'plain' and 'ocean' * two terrains: 'plain' and 'ocean'
* one race: 'human' * one race: 'human'
@ -101,15 +126,8 @@ void test_create_world(void)
building_type *btype; building_type *btype;
ship_type *stype; ship_type *stype;
t_plain = (terrain_type*)calloc(1, sizeof(terrain_type)); t_plain = test_create_terrain("plain", LAND_REGION | FOREST_REGION | WALK_INTO);
t_plain->_name = strdup("plain"); t_ocean = test_create_terrain("ocean", SEA_REGION | SAIL_INTO | SWIM_INTO);
t_plain->flags = LAND_REGION | FOREST_REGION | WALK_INTO;
register_terrain(t_plain);
t_ocean = (terrain_type*)calloc(1, sizeof(terrain_type));
t_ocean->_name = strdup("ocean");
t_ocean->flags = SEA_REGION | SAIL_INTO | SWIM_INTO;
register_terrain(t_ocean);
island[0] = test_create_region(0, 0, t_plain); island[0] = test_create_region(0, 0, t_plain);
island[1] = test_create_region(1, 0, t_plain); island[1] = test_create_region(1, 0, t_plain);
@ -124,17 +142,15 @@ void test_create_world(void)
} }
} }
rc_human = rc_add(rc_new("human")); rc_human = test_create_race("human");
rc_human->maintenance = 10;
btype = calloc(sizeof(building_type), 1); btype = (building_type*)calloc(sizeof(building_type), 1);
btype->flags = BTF_NAMECHANGE; btype->flags = BTF_NAMECHANGE;
btype->_name = strdup("castle"); btype->_name = strdup("castle");
bt_register(btype); bt_register(btype);
stype = calloc(sizeof(ship_type), 1); stype = (ship_type*)calloc(sizeof(ship_type), 1);
stype->name[0] = strdup("boat"); stype->name[0] = strdup("boat");
stype->name[1] = strdup("boat_p"); stype->name[1] = strdup("boat_p");
st_register(stype); st_register(stype);
} }

View file

@ -5,12 +5,14 @@ extern "C" {
#ifndef DISABLE_TESTS #ifndef DISABLE_TESTS
void test_cleanup(void); void test_cleanup(void);
struct terrain_type * test_create_terrain(const char * name, unsigned int flags);
struct race *test_create_race(const char *name); struct race *test_create_race(const char *name);
struct region *test_create_region(int x, int y, struct region *test_create_region(int x, int y,
const struct terrain_type *terrain); const struct terrain_type *terrain);
struct faction *test_create_faction(const struct race *rc); struct faction *test_create_faction(const struct race *rc);
struct unit *test_create_unit(struct faction *f, struct region *r); struct unit *test_create_unit(struct faction *f, struct region *r);
void test_create_world(void); void test_create_world(void);
struct building * test_create_building(struct region * r, const struct building_type * btype);
int RunAllTests(void); int RunAllTests(void);
#else #else