avoid fix_demand hitting an endless loop, kill bad use of static variables.

This commit is contained in:
Enno Rehling 2014-12-31 20:01:01 +01:00
parent 5e10bc4093
commit db083389c7
4 changed files with 56 additions and 83 deletions

View File

@ -1191,7 +1191,11 @@ void free_resources(void)
int i;
memset((void *)oldpotiontype, 0, sizeof(oldpotiontype));
while (luxurytypes) {
luxury_type * next = luxurytypes->next;
free(luxurytypes);
luxurytypes = next;
}
cb_foreach(&cb_resources, "", 0, free_rtype_cb, 0);
cb_clear(&cb_resources);
++num_resources;

View File

@ -2,6 +2,8 @@
#include <kernel/item.h>
#include <kernel/pool.h>
#include <kernel/region.h>
#include <kernel/terrain.h>
#include <kernel/unit.h>
#include <util/language.h>
#include <util/functions.h>
@ -116,6 +118,32 @@ void test_findresourcetype(CuTest * tc)
CuAssertPtrNotNull(tc, findresourcetype("Bauer", lang));
}
#include <modules/autoseed.h>
static void test_fix_demand(CuTest *tc) {
region *r;
terrain_type *tplain;
item_type *ltype;
luxury_type *lux;
test_cleanup();
ltype = test_create_itemtype("balm");
ltype->rtype->flags |= (RTF_ITEM | RTF_POOLED);
lux = new_luxurytype(ltype, 0);
ltype = test_create_itemtype("oint");
ltype->rtype->flags |= (RTF_ITEM | RTF_POOLED);
lux = new_luxurytype(ltype, 0);
tplain = test_create_terrain("plain", LAND_REGION);
r = new_region(0, 0, NULL, 0);
CuAssertPtrNotNull(tc, r);
terraform_region(r, tplain);
CuAssertPtrNotNull(tc, r->land);
CuAssertIntEquals(tc, 0, fix_demand(r));
CuAssertPtrNotNull(tc, r->land->demands);
CuAssertPtrNotNull(tc, r->land->demands->next);
CuAssertPtrNotNull(tc, r_luxury(r));
test_cleanup();
}
CuSuite *get_item_suite(void)
{
CuSuite *suite = CuSuiteNew();
@ -125,5 +153,6 @@ CuSuite *get_item_suite(void)
SUITE_ADD_TEST(suite, test_resource_type);
SUITE_ADD_TEST(suite, test_finditemtype);
SUITE_ADD_TEST(suite, test_findresourcetype);
SUITE_ADD_TEST(suite, test_fix_demand);
return suite;
}

View File

@ -69,11 +69,9 @@ region *regions;
int get_maxluxuries(void)
{
static int maxluxuries = -1;
if (maxluxuries == -1) {
const luxury_type *ltype;
maxluxuries = 0;
for (ltype = luxurytypes; ltype; ltype = ltype->next)
int maxluxuries = 0;
for (ltype = luxurytypes; ltype; ltype = ltype->next) {
++maxluxuries;
}
return maxluxuries;

View File

@ -127,90 +127,32 @@ bool(*fun) (const region * r))
static bool f_nolux(const region * r)
{
if (r->land && count_demand(r) != get_maxluxuries())
return true;
return false;
return (r->land && count_demand(r) != get_maxluxuries());
}
int fix_demand(region * rd)
{
region_list *rl, *rlist = NULL;
static const luxury_type *mlux[MAXLUXURIES];
const luxury_type *ltypes[MAXLUXURIES];
const luxury_type *sale = NULL;
int maxlux = 0;
static int maxluxuries = -1;
int fix_demand(region * rd) {
luxury_type * ltype;
int maxluxuries = get_maxluxuries();
if (maxluxuries > 0) {
int sale = rng_int() % maxluxuries;
for (ltype = luxurytypes; sale != 0 && ltype; ltype = ltype->next) {
--sale;
}
setluxuries(rd, ltype);
return 0;
}
return -1;
}
// TODO: this entire function is impossible to understand
int fix_all_demand(region *rd) {
region_list *rl, *rlist = NULL;
recurse_regions(rd, &rlist, f_nolux);
if (maxluxuries < 0) {
int i = 0;
for (sale = luxurytypes; sale; sale = sale->next) {
ltypes[i++] = sale;
}
maxluxuries = i;
}
if (maxluxuries == 0) {
for (rl = rlist; rl; rl = rl->next) {
region *r = rl->data;
freset(r, RF_MARK); /* undo recursive marker */
if (!fix_demand(r)) {
return -1;
}
else {
int i;
for (i = 0; i != maxluxuries; ++i) {
mlux[i] = 0;
}
}
for (rl = rlist; rl; rl = rl->next) {
region *r = rl->data;
direction_t d;
for (d = 0; d != MAXDIRECTIONS; ++d) {
region *nr = rconnect(r, d);
if (nr && nr->land && nr->land->demands) {
struct demand *dmd;
for (dmd = nr->land->demands; dmd; dmd = dmd->next) {
if (dmd->value == 0) {
int i;
for (i = 0; i != maxluxuries; ++i) {
if (mlux[i] == NULL) {
maxlux = i;
mlux[i] = dmd->type;
break;
}
else if (mlux[i] == dmd->type) {
break;
}
}
break;
}
}
}
}
freset(r, RF_MARK); /* undo recursive marker */
}
if (maxlux < 2) {
int i;
for (i = maxlux; i != 2; ++i) {
int j;
do {
int k = rng_int() % maxluxuries;
mlux[i] = ltypes[k];
for (j = 0; j != i; ++j) {
if (mlux[j] == mlux[i])
break;
}
} while (j != i);
}
maxlux = 2;
}
for (rl = rlist; rl; rl = rl->next) {
region *r = rl->data;
sale = mlux[rng_int() % maxlux];
if (sale)
setluxuries(r, sale);
}
while (rlist) {
rl = rlist->next;
free(rlist);
rlist = rl;
}
return 0;
}