Signifikanter CR/NR-Unterschied 

- das Regionsintervall wurde in write_plaintext() nicht korrekt benutzt.
This commit is contained in:
Enno Rehling 2006-01-21 08:34:01 +00:00
parent 6df45d2a93
commit 55b9af27c2
9 changed files with 43 additions and 122 deletions

View file

@ -1085,7 +1085,6 @@ report_computer(const char * filename, report_context * ctx)
ship *sh; ship *sh;
unit *u; unit *u;
const char * mailto = locale_string(f->locale, "mailto"); const char * mailto = locale_string(f->locale, "mailto");
region * first = firstregion(f), * last = lastregion(f);
const attrib * a; const attrib * a;
#ifdef SCORE_MODULE #ifdef SCORE_MODULE
int score = 0, avgscore = 0; int score = 0, avgscore = 0;
@ -1097,7 +1096,6 @@ report_computer(const char * filename, report_context * ctx)
} }
/* must call this to get all the neighbour regions */ /* must call this to get all the neighbour regions */
get_seen_interval(ctx->seen, &first, &last);
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* initialisations, header and lists */ /* initialisations, header and lists */
@ -1234,7 +1232,7 @@ report_computer(const char * filename, report_context * ctx)
} }
/* traverse all regions */ /* traverse all regions */
for (r=first;r!=last;r=r->next) { for (r=ctx->first;r!=ctx->last;r=r->next) {
int modifier = 0; int modifier = 0;
const char * tname; const char * tname;
const seen_region * sd = find_seen(ctx->seen, r); const seen_region * sd = find_seen(ctx->seen, r);

View file

@ -1902,7 +1902,6 @@ report_plaintext(const char * filename, report_context * ctx)
attrib *a; attrib *a;
message * m; message * m;
unsigned char op; unsigned char op;
region * last = lastregion(f);
int ix = Pow(O_STATISTICS); int ix = Pow(O_STATISTICS);
int wants_stats = (f->options & ix); int wants_stats = (f->options & ix);
FILE * F = fopen(filename, "wt"); FILE * F = fopen(filename, "wt");
@ -2074,10 +2073,8 @@ report_plaintext(const char * filename, report_context * ctx)
rnl(F); rnl(F);
centre(F, buf, true); centre(F, buf, true);
} }
/* Der Report soll später einmal durch einen Makroprozessor laufen.
* (enno) was? wer hat das geschrieben? rp_messages(F, f->msgs, f, 0, true, true);
* Momentan ist das wegen der der Mailverschickmimik schwierig. */
rp_messages(F, f->msgs, f, 0, true, true);
rp_battles(F, f); rp_battles(F, f);
a = a_find(f->attribs, &at_reportspell); a = a_find(f->attribs, &at_reportspell);
if (a) { if (a) {
@ -2137,7 +2134,7 @@ report_plaintext(const char * filename, report_context * ctx)
anyunits = 0; anyunits = 0;
for (r=firstregion(f);r!=last;r=r->next) { for (r=ctx->first;r!=ctx->last;r=r->next) {
boolean unit_in_region = false; boolean unit_in_region = false;
boolean durchgezogen_in_region = false; boolean durchgezogen_in_region = false;
int turm_sieht_region = false; int turm_sieht_region = false;

View file

@ -148,13 +148,12 @@ report_xml(const char * filename, report_context * ctx)
xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0"); xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
xmlNodePtr xmlReport = xmlNewNode(NULL, BAD_CAST "report"); xmlNodePtr xmlReport = xmlNewNode(NULL, BAD_CAST "report");
const faction_list * address; const faction_list * address;
region * r = firstregion(ctx->f), * rend = lastregion(ctx->f); region * r = ctx->first, * rend = ctx->last;
for (address=ctx->addresses;address;address=address->next) { for (address=ctx->addresses;address;address=address->next) {
xmlAddChild(xmlReport, report_faction(ctx, address->data)); xmlAddChild(xmlReport, report_faction(ctx, address->data));
} }
get_seen_interval(ctx->seen, &r, &rend);
for (;r!=rend;r=r->next) { for (;r!=rend;r=r->next) {
seen_region * sr = find_seen(ctx->seen, r); seen_region * sr = find_seen(ctx->seen, r);
if (sr!=NULL) xmlAddChild(xmlReport, report_region(ctx, sr)); if (sr!=NULL) xmlAddChild(xmlReport, report_region(ctx, sr));

View file

@ -2117,28 +2117,17 @@ lastregion (faction * f)
/* it is safe to start in the region of the first unit. */ /* it is safe to start in the region of the first unit. */
f->last = u->region; f->last = u->region;
#ifdef ENUM_REGIONS
/* if regions have indices, we can skip ahead: */ /* if regions have indices, we can skip ahead: */
for (u=u->nextF; u!=NULL; u=u->nextF) { for (u=u->nextF; u!=NULL; u=u->nextF) {
r = u->region; r = u->region;
if (r->index > f->last->index) f->last = r; if (r->index > f->last->index) f->last = r;
} }
#endif
/* we continue from the best region and look for travelthru etc. */ /* we continue from the best region and look for travelthru etc. */
for (r = f->last->next; r; r = r->next) { for (r = f->last->next; r; r = r->next) {
plane * p = rplane(r); plane * p = rplane(r);
attrib *ru; attrib *ru;
#ifndef ENUM_REGIONS
/* for index-regions we don't need this, we already did it earlier */
for (u = r->units; u; u = u->next) {
if (u->faction == f) {
f->last = r;
break;
}
}
if (f->last == r) continue;
#endif
/* search the region for travelthru-attributes: */ /* search the region for travelthru-attributes: */
if (fval(r, RF_TRAVELUNIT)) { if (fval(r, RF_TRAVELUNIT)) {
for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) { for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) {
@ -2171,34 +2160,6 @@ firstregion (faction * f)
if (f->units==NULL) return NULL; if (f->units==NULL) return NULL;
if (r!=NULL) return r; if (r!=NULL) return r;
#ifndef ENUM_REGIONS
for (r = regions; r; r = r->next) {
attrib *ru;
unit *u;
plane * p = rplane(r);
for (u = r->units; u; u = u->next) {
if (u->faction == f) {
return f->first = r;
}
}
if (f->first == r->next)
continue;
if (fval(r, RF_TRAVELUNIT)) {
for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) {
u = (unit*)ru->data.v;
if (u->faction == f) {
return f->first = r;
}
}
}
if (check_leuchtturm(r, f)) {
return f->first = r;
}
if (p && is_watcher(p, f)) {
return f->first = r;
}
}
#endif
return f->first = regions; return f->first = regions;
#else #else
return regions; return regions;

View file

@ -328,17 +328,12 @@ void
update_interval(struct faction * f, struct region * r) update_interval(struct faction * f, struct region * r)
{ {
if (r==NULL || f==NULL) return; if (r==NULL || f==NULL) return;
#ifdef ENUM_REGIONS
if (f->first==NULL || f->first->index>r->index) { if (f->first==NULL || f->first->index>r->index) {
f->first = r; f->first = r;
} }
if (f->last==NULL || f->last->index<=r->index) { if (f->last==NULL || f->last->index<=r->index) {
f->last = r; f->last = r;
} }
#else
f->first = 0;
f->last = 0;
#endif
} }
#endif #endif

View file

@ -718,9 +718,8 @@ rsettrees(const region *r, int ageclass, int value)
static region *last; static region *last;
#ifdef ENUM_REGIONS
static unsigned int max_index = 0; static unsigned int max_index = 0;
#endif
region * region *
new_region(short x, short y) new_region(short x, short y)
{ {
@ -744,10 +743,8 @@ new_region(short x, short y)
else else
addlist(&regions, r); addlist(&regions, r);
last = r; last = r;
#ifdef ENUM_REGIONS
assert(r->next==NULL); assert(r->next==NULL);
r->index = ++max_index; r->index = ++max_index;
#endif
return r; return r;
} }

View file

@ -25,11 +25,6 @@ extern "C" {
a hash-access each time a neighbour is needed */ a hash-access each time a neighbour is needed */
#define FAST_CONNECT #define FAST_CONNECT
/* ENUM_REGIONS: regions have an ascending number, to improve the speed of
determining the interval in which a faction has its units. See the
implementations of firstregion and lastregion */
#define ENUM_REGIONS
#define RF_CHAOTIC (1<<0) #define RF_CHAOTIC (1<<0)
#define RF_MALLORN (1<<1) #define RF_MALLORN (1<<1)
#define RF_BLOCKED (1<<2) #define RF_BLOCKED (1<<2)
@ -91,6 +86,10 @@ typedef struct region {
struct unit *units; struct unit *units;
struct ship *ships; struct ship *ships;
struct building *buildings; struct building *buildings;
unsigned int index;
/* an ascending number, to improve the speed of determining the interval in
which a faction has its units. See the implementations of firstregion
and lastregion */
short x, y; short x, y;
struct plane *planep; struct plane *planep;
char *display; char *display;
@ -113,9 +112,6 @@ typedef struct region {
#ifdef FAST_CONNECT #ifdef FAST_CONNECT
struct region * connect[MAXDIRECTIONS]; struct region * connect[MAXDIRECTIONS];
#endif #endif
#ifdef ENUM_REGIONS
unsigned int index;
#endif
} region; } region;
typedef struct region_list { typedef struct region_list {
@ -138,13 +134,8 @@ typedef struct {
direction_t dir; direction_t dir;
} moveblock; } moveblock;
#ifdef ENUM_REGIONS #define reg_hashkey(r) (r->index)
# define reg_hashkey(r) (r->index) #define coor_hashkey(x, y) (abs(x + 0x100 * y))
# define coor_hashkey(x, y) (abs(x + 0x100 * y))
#else
# define reg_hashkey(r) (abs((r)->x + 0x100 * (r)->y))
# define coor_hashkey(x, y) (abs(x + 0x100 * y))
#endif
int distance(const struct region*, const struct region*); int distance(const struct region*, const struct region*);
int koor_distance(int ax, int ay, int bx, int by) ; int koor_distance(int ax, int ay, int bx, int by) ;

View file

@ -1105,25 +1105,25 @@ ucansee(const struct faction *f, const struct unit *u, const struct unit *x)
return x; return x;
} }
faction_list * static void
get_addresses(faction * f, struct seen_region * seehash[]) get_addresses(report_context * ctx)
{ {
/* "TODO: travelthru" */ /* "TODO: travelthru" */
region *r, *last = lastregion(f); region *r;
const faction * lastf = NULL; const faction * lastf = NULL;
faction_list * flist = calloc(1, sizeof(faction_list)); faction_list * flist = calloc(1, sizeof(faction_list));
flist->data = f; flist->data = ctx->f;
for (r=firstregion(f);r!=last;r=r->next) { for (r=ctx->first;r!=ctx->last;r=r->next) {
const unit * u = r->units; const unit * u = r->units;
const seen_region * sr = find_seen(seehash, r); const seen_region * sr = find_seen(ctx->seen, r);
if (sr==NULL) continue; if (sr==NULL) continue;
while (u!=NULL) { while (u!=NULL) {
faction * sf = visible_faction(f, u); faction * sf = visible_faction(ctx->f, u);
boolean ballied = sf && sf!=f && sf!=lastf boolean ballied = sf && sf!=ctx->f && sf!=lastf
&& !fval(u, UFL_PARTEITARNUNG) && cansee(f, r, u, 0); && !fval(u, UFL_PARTEITARNUNG) && cansee(ctx->f, r, u, 0);
if (ballied || ALLIED(f, sf)) { if (ballied || ALLIED(ctx->f, sf)) {
faction_list ** fnew = &flist; faction_list ** fnew = &flist;
while (*fnew && (*fnew)->data->no < sf->no) { while (*fnew && (*fnew)->data->no < sf->no) {
fnew =&(*fnew)->next; fnew =&(*fnew)->next;
@ -1140,10 +1140,10 @@ get_addresses(faction * f, struct seen_region * seehash[])
} }
} }
if (f->alliance != NULL) { if (ctx->f->alliance != NULL) {
faction *f2; faction *f2;
for(f2 = factions; f2; f2 = f2->next) { for(f2 = factions; f2; f2 = f2->next) {
if(f2->alliance != NULL && f2->alliance == f->alliance) { if(f2->alliance != NULL && f2->alliance == ctx->f->alliance) {
faction_list ** fnew = &flist; faction_list ** fnew = &flist;
while (*fnew && (*fnew)->data->no < f2->no) { while (*fnew && (*fnew)->data->no < f2->no) {
fnew =&(*fnew)->next; fnew =&(*fnew)->next;
@ -1157,7 +1157,7 @@ get_addresses(faction * f, struct seen_region * seehash[])
} }
} }
} }
return flist; ctx->addresses = flist;
} }
#define MAXSEEHASH 10007 #define MAXSEEHASH 10007
@ -1206,42 +1206,24 @@ find_seen(struct seen_region * seehash[], const region * r)
return NULL; return NULL;
} }
void static void
get_seen_interval(struct seen_region ** seen, region ** first, region ** last) get_seen_interval(report_context * ctx)
{ {
/* this is required to find the neighbour regions of the ones we are in, /* this is required to find the neighbour regions of the ones we are in,
* which may well be outside of [firstregion, lastregion) */ * which may well be outside of [firstregion, lastregion) */
#ifdef ENUM_REGIONS
int i; int i;
for (i=0;i!=MAXSEEHASH;++i) { for (i=0;i!=MAXSEEHASH;++i) {
seen_region * sr = seen[i]; seen_region * sr = ctx->seen[i];
while (sr!=NULL) { while (sr!=NULL) {
if (*first==NULL || sr->r->index<(*first)->index) { if (ctx->first==NULL || sr->r->index<ctx->first->index) {
*first = sr->r; ctx->first = sr->r;
} }
if (*last!=NULL && sr->r->index>=(*last)->index) { if (ctx->last!=NULL && sr->r->index>=ctx->last->index) {
*last = sr->r->next; ctx->last = sr->r->next;
} }
sr = sr->nextHash; sr = sr->nextHash;
} }
} }
#else
region * r = regions;
while (r!=first) {
if (find_seen(seen, r)!=NULL) {
*first = r;
break;
}
r = r->next;
}
r = *last;
while (r!=NULL) {
if (find_seen(seen, r)!=NULL) {
*last = r->next;
}
r = r->next;
}
#endif
} }
boolean boolean
@ -1498,16 +1480,18 @@ int
write_reports(faction * f, time_t ltime) write_reports(faction * f, time_t ltime)
{ {
boolean gotit = false; boolean gotit = false;
struct seen_region ** seen = prepare_report(f);
faction_list * addresses = get_addresses(f, seen);
report_type * rtype = report_types; report_type * rtype = report_types;
struct report_context ctx; struct report_context ctx;
ctx.f = f; ctx.f = f;
ctx.addresses = addresses;
ctx.report_time = time(NULL); ctx.report_time = time(NULL);
ctx.seen = seen; ctx.seen = prepare_report(f);
ctx.first = firstregion(f);
ctx.last = lastregion(f);
ctx.addresses = NULL;
ctx.userdata = NULL; ctx.userdata = NULL;
get_seen_interval(&ctx);
get_addresses(&ctx);
printf("Reports für %s: ", factionname(f)); printf("Reports für %s: ", factionname(f));
fflush(stdout); fflush(stdout);
@ -1529,8 +1513,8 @@ write_reports(faction * f, time_t ltime)
log_warning(("No report for faction %s!\n", factionid(f))); log_warning(("No report for faction %s!\n", factionid(f)));
} }
freelist(addresses); freelist(ctx.addresses);
seen_done(seen); seen_done(ctx.seen);
return 0; return 0;
} }

View file

@ -84,15 +84,15 @@ extern boolean add_seen(struct seen_region * seehash[], struct region * r, unsig
extern struct seen_region ** seen_init(void); extern struct seen_region ** seen_init(void);
extern void seen_done(struct seen_region * seehash[]); extern void seen_done(struct seen_region * seehash[]);
extern void free_seen(void); extern void free_seen(void);
extern void get_seen_interval(struct seen_region ** seen, struct region ** first, struct region ** last);
extern const char * visibility[]; extern const char * visibility[];
typedef struct report_context { typedef struct report_context {
struct faction * f; struct faction * f;
struct faction_list * addresses; struct faction_list * addresses;
struct seen_region ** seen; struct seen_region ** seen;
time_t report_time; struct region * first, * last;
void * userdata; void * userdata;
time_t report_time;
} report_context; } report_context;
typedef int (*report_fun)(const char * filename, report_context * ctx); typedef int (*report_fun)(const char * filename, report_context * ctx);
@ -106,7 +106,6 @@ extern int bufunit_ugroupleader(const struct faction * f, const struct unit * u,
#endif #endif
extern const char * reportpath(void); extern const char * reportpath(void);
extern struct faction_list * get_addresses(struct faction * f, struct seen_region * seehash[]);
extern const char * trailinto(const struct region * r, const struct locale * lang); extern const char * trailinto(const struct region * r, const struct locale * lang);
extern void reports_init(void); extern void reports_init(void);