diff -ru -X /home/jjm/cvs/no.freeciv FreecivCVS/common/game.c freeciv/common/game.c --- FreecivCVS/common/game.c Sun Aug 15 10:07:57 1999 +++ freeciv/common/game.c Mon Aug 16 23:24:38 1999 @@ -17,6 +17,7 @@ #include "city.h" #include "log.h" #include "map.h" +#include "mem.h" #include "player.h" #include "shared.h" #include "spaceship.h" @@ -37,7 +38,8 @@ int elvis; int wonders; int techs; - int landmass; + int landarea; + int population; int cities; int units; int pollution; @@ -46,10 +48,270 @@ int mfg; int spaceship; }; +*/ +struct claim_cell { + int when; + int whom; + int know; +}; -*/ +struct claim_map { + struct claim_cell *claims; + int *player_landarea; +}; + +/************************************************************************** +Land Area Debug... +**************************************************************************/ + +#define LAND_AREA_DEBUG 0 + +#if LAND_AREA_DEBUG || 0 + +static void print_landarea_map (struct claim_map *pcmap, int turn) +{ + int x, y, p; + + if (turn == 0) + { + putchar ('\n'); + } + + printf ("Turn %d...\n", turn); + + if (turn == 0) + { + for (p = 0; p < game.nplayers; p++) + { + printf (".know (%d)\n ", p); + for (x = 0; x < map.xsize; x++) + { + printf ("%d", x % 10); + } + putchar ('\n'); + for (y = 0; y < map.ysize; y++) + { + printf ("%d ", y % 10); + for (x = 0; x < map.xsize; x++) + { + printf ("%c", + (pcmap->claims[map_inx(x,y)].know & (1u << p)) ? + 'X' : + '-'); + } + printf (" %d\n", y % 10); + } + } + } + + printf (".whom\n "); + for (x = 0; x < map.xsize; x++) + { + printf ("%d", x % 10); + } + putchar ('\n'); + for (y = 0; y < map.ysize; y++) + { + printf ("%d ", y % 10); + for (x = 0; x < map.xsize; x++) + { + printf ("%X", pcmap->claims[map_inx(x,y)].whom); + } + printf (" %d\n", y % 10); + } + + printf (".when\n "); + for (x = 0; x < map.xsize; x++) + { + printf ("%d", x % 10); + } + putchar ('\n'); + for (y = 0; y < map.ysize; y++) + { + printf ("%d ", y % 10); + for (x = 0; x < map.xsize; x++) + { + printf ("%X", pcmap->claims[map_inx(x,y)].when); + } + printf (" %d\n", y % 10); + } +} +#else + +#define print_landarea_map(a,b) + +#endif + +/************************************************************************** +Allocates, fills and returns a land area claim map. +Call free_landarea_map(&cmap) to free allocated memory. +**************************************************************************/ + +static void build_landarea_map(struct claim_map *pcmap) +{ + int x, y, p, n, i; + struct tile *ptile; + int turn; + int accum; + int owner; + static int nx[8] = { -1, 0, 1, -1, 1, -1, 0, 1 }; + static int ny[8] = { -1, -1, -1, 0, 0, 1, 1, 1 }; + static int no_owner = MAX_NUM_PLAYERS; + + /* allocate and init claim map */ + + pcmap->claims = + fc_malloc (map.xsize * map.ysize * sizeof (struct claim_cell)); + pcmap->player_landarea = + fc_malloc (game.nplayers * sizeof (int)); + + for (p = 0; p < game.nplayers; p++) + { + pcmap->player_landarea[p] = 0; + } + + turn = 0; + + for (y = 0; y < map.ysize; y++) + { + for (x = 0; x < map.xsize; x++) + { + ptile = map_get_tile (x, y); + + if (ptile->terrain == T_OCEAN) + { + pcmap->claims[map_inx(x,y)].when = 0; + pcmap->claims[map_inx(x,y)].whom = no_owner; + pcmap->claims[map_inx(x,y)].know = 0; + } + else if (ptile->city) + { + pcmap->claims[map_inx(x,y)].when = turn + 1; + pcmap->claims[map_inx(x,y)].whom = ptile->city->owner; + (pcmap->player_landarea[pcmap->claims[map_inx(x,y)].whom])++; + pcmap->claims[map_inx(x,y)].know = map.tiles[map_inx(x,y)].known; + } + else if (ptile->worked) + { + pcmap->claims[map_inx(x,y)].when = turn + 1; + pcmap->claims[map_inx(x,y)].whom = ptile->worked->owner; + (pcmap->player_landarea[pcmap->claims[map_inx(x,y)].whom])++; + pcmap->claims[map_inx(x,y)].know = map.tiles[map_inx(x,y)].known; + } + else if (unit_list_size (&(ptile->units)) > 0) + { + pcmap->claims[map_inx(x,y)].when = turn + 1; + pcmap->claims[map_inx(x,y)].whom = + (unit_list_get (&(ptile->units), 0))->owner; + (pcmap->player_landarea[pcmap->claims[map_inx(x,y)].whom])++; + pcmap->claims[map_inx(x,y)].know = map.tiles[map_inx(x,y)].known; + } + else + { + pcmap->claims[map_inx(x,y)].when = 0; + pcmap->claims[map_inx(x,y)].whom = no_owner; + pcmap->claims[map_inx(x,y)].know = map.tiles[map_inx(x,y)].known; + } + } + } + + print_landarea_map (pcmap, turn); + + /* expand outwards evenly from each starting point, counting tiles */ + + for (accum = 1, turn++; accum > 0; turn++) + { + accum = 0; + + for (y = 0; y < map.ysize; y++) + { + for (x = 0; x < map.xsize; x++) + { + if (pcmap->claims[map_inx(x,y)].when == turn) + { + owner = pcmap->claims[map_inx(x,y)].whom; + + for (n = 0; n < 8; n++) + { + if (((y + ny[n]) < 0) || ((y + ny[n]) >= map.ysize)) + { + continue; + } + i = map_inx (map_adjust_x (x + nx[n]), y + ny[n]); + + if (pcmap->claims[i].know & (1u << owner)) + { + if (pcmap->claims[i].when == 0) + { + pcmap->claims[i].when = turn + 1; + pcmap->claims[i].whom = owner; + (pcmap->player_landarea[owner])++; + accum++; + } + else if ((pcmap->claims[i].when == (turn + 1)) && + (pcmap->claims[i].whom != no_owner) && + (pcmap->claims[i].whom != owner)) + { + (pcmap->player_landarea[pcmap->claims[i].whom])--; + pcmap->claims[i].whom = no_owner; + accum--; + } + } + } + } + } + } + + print_landarea_map (pcmap, turn); + } +} + +/************************************************************************** +Frees and NULLs an allocated claim map. +**************************************************************************/ + +static void free_landarea_map(struct claim_map *pcmap) +{ + if (pcmap) + { + if (pcmap->claims) + { + free (pcmap->claims); + pcmap->claims = NULL; + } + if (pcmap->player_landarea) + { + free (pcmap->player_landarea); + pcmap->player_landarea = NULL; + } + } +} + +/************************************************************************** +Computes and returns the given player's land area (per a claim map). +**************************************************************************/ + +static int get_player_landarea(struct claim_map *pcmap, struct player *pplayer) +{ + int area = 0; + + if (pcmap && pplayer && pcmap->player_landarea) + { + area = pcmap->player_landarea[pplayer->player_no]; + } + +#if LAND_AREA_DEBUG || 0 + printf ("%-14s %d\n", pplayer->name, area); +#endif + + return (area * 1000); +} + +/************************************************************************** +... +**************************************************************************/ int research_time(struct player *pplayer) { @@ -57,6 +319,10 @@ return timemod*pplayer->research.researchpoints*game.techlevel; } +/************************************************************************** +... +**************************************************************************/ + int total_player_citizens(struct player *pplayer) { return (pplayer->score.happy @@ -74,6 +340,8 @@ { int i; struct city *pcity; + static struct claim_map cmap = { NULL, NULL }; + pplayer->score.happy=0; /* done */ pplayer->score.content=0; /* done */ pplayer->score.unhappy=0; /* done */ @@ -83,7 +351,8 @@ pplayer->score.wonders=0; /* done */ pplayer->score.techs=0; /* done */ pplayer->score.techout=0; /* done */ - pplayer->score.landmass=0; + pplayer->score.landarea=0; + pplayer->score.population=0; pplayer->score.cities=0; /* done */ pplayer->score.units=0; /* done */ pplayer->score.pollution=0; /* done */ @@ -95,10 +364,10 @@ pplayer->score.happy+=pcity->ppl_happy[4]; pplayer->score.content+=pcity->ppl_content[4]; pplayer->score.unhappy+=pcity->ppl_unhappy[4]; - pplayer->score.taxmen+=pcity->ppl_taxman; pplayer->score.scientists+=pcity->ppl_scientist; pplayer->score.elvis+=pcity->ppl_elvis; + pplayer->score.population+=city_population(pcity); pplayer->score.cities++; pplayer->score.pollution+=pcity->pollution; pplayer->score.techout+=(1+pcity->science_total); @@ -110,6 +379,16 @@ pplayer->score.literacy+=(city_population(pcity)/2); } city_list_iterate_end; + + if (pplayer->player_no == 0) { + free_landarea_map(&cmap); + build_landarea_map(&cmap); + } + pplayer->score.landarea=get_player_landarea(&cmap, pplayer); + if (pplayer->player_no == (game.nplayers - 1)) { + free_landarea_map(&cmap); + } + for (i=0;iscore.techs++; @@ -132,6 +411,7 @@ pplayer->score.spaceship += (int)(100 * pplayer->spaceship.habitation * pplayer->spaceship.success_rate); } + return (total_player_citizens(pplayer) +pplayer->score.happy +pplayer->score.techs*2 diff -ru -X /home/jjm/cvs/no.freeciv FreecivCVS/common/map.h freeciv/common/map.h --- FreecivCVS/common/map.h Fri Aug 13 16:31:01 1999 +++ freeciv/common/map.h Mon Aug 16 23:32:58 1999 @@ -180,6 +180,9 @@ #define map_adjust_y(Y) \ (((Y)<0) ? 0 : (((Y)>=map.ysize) ? map.ysize-1 : (Y))) +#define map_inx(x,y) \ + ((x)+(y)*map.xsize) + void map_calc_adjacent_xy(int x, int y, int *xx, int *yy); void map_calc_adjacent_xy_void(int x, int y, int *xx, int *yy); diff -ru -X /home/jjm/cvs/no.freeciv FreecivCVS/common/player.h freeciv/common/player.h --- FreecivCVS/common/player.h Mon Aug 16 07:40:57 1999 +++ freeciv/common/player.h Mon Aug 16 18:43:41 1999 @@ -109,7 +109,8 @@ int wonders; int techs; int techout; - int landmass; + int landarea; + int population; int cities; int units; int pollution; diff -ru -X /home/jjm/cvs/no.freeciv FreecivCVS/server/plrhand.c freeciv/server/plrhand.c --- FreecivCVS/server/plrhand.c Sun Aug 15 10:07:59 1999 +++ freeciv/server/plrhand.c Mon Aug 16 18:43:41 1999 @@ -198,6 +198,30 @@ "Wonders of the World", buffer); } +static int rank_population(struct player *pplayer) +{ + int basis=pplayer->score.population; + int place=1; + int i; + for (i=0;ibasis) + place++; + } + return place; +} + +static int rank_landarea(struct player *pplayer) +{ + int basis=pplayer->score.landarea; + int place=1; + int i; + for (i=0;ibasis) + place++; + } + return place; +} + static int rank_calc_research(struct player *pplayer) { return (pplayer->score.techout*100)/(1+research_time(pplayer)); @@ -293,16 +317,51 @@ return place; } -static char *number_to_string(int x) +static char *value_units(char *val, char *uni) { - static char buf[4]; - buf[3]=0; - if (x<0 || x>99) x=0; - sprintf(buf, "%dth",x); - if (x==1) { buf[1]='s'; buf[2]='t';} - if (x==2) { buf[1]='n'; buf[2]='d';} - if (x==3) { buf[1]='r'; buf[2]='d';} - return buf; + static char buf[64] = "??"; + + if ((strlen (val) + strlen (uni) + 1) > sizeof (buf)) + { + return (buf); + } + + sprintf (buf, "%s%s", val, uni); + + return (buf); +} + +static char *number_to_ordinal_string(int num, int parens) +{ + static char buf[16]; + char *fmt; + + fmt = parens ? "(%d%s)" : "%d%s"; + + switch (num) + { + case 1: + sprintf (buf, fmt, num, "st"); + break; + case 2: + sprintf (buf, fmt, num, "nd"); + break; + case 3: + sprintf (buf, fmt, num, "rd"); + break; + default: + if (num > 0) + { + sprintf (buf, fmt, num, "th"); + } + else + { + strcpy (buf, parens ? "(??th)" : "??th"); + } + break; + } + + return (buf); } void do_dipl_cost(struct player *pplayer) @@ -322,32 +381,55 @@ void demographics_report(struct player *pplayer) { char civbuf[1024]; - char buffer[4096]; - char buf2[4096]; - buffer[0]=0; + char buffer[4096] = ""; + char *outptr = buffer; + char *fmt = "%-18s %-18s %6s\n"; sprintf(civbuf,"The %s of the %s", get_government_name(pplayer->government), get_race_name_plural(pplayer->race)); - sprintf(buf2, "%-20s:%d%% (%s)\n", "Research Speed", rank_calc_research(pplayer), number_to_string(rank_research(pplayer))); - strcat(buffer, buf2); - - sprintf(buf2, "%-20s:%d%% (%s)\n", "Literacy",rank_calc_literacy(pplayer), number_to_string(rank_literacy(pplayer))); - strcat(buffer, buf2); - sprintf(buf2, "%-20s:%d M. MFG (%s)\n", "Production", pplayer->score.mfg, number_to_string(rank_production(pplayer))); - strcat(buffer, buf2); - sprintf(buf2, "%-20s:%d M. BNP (%s)\n", "Economics", pplayer->score.bnp, number_to_string(rank_economics(pplayer))); - strcat(buffer, buf2); + outptr = strchr (outptr, '\0'); + sprintf(outptr, fmt, "Population", + int_to_text (pplayer->score.population), + number_to_ordinal_string(rank_population(pplayer), TRUE)); + + outptr = strchr (outptr, '\0'); + sprintf(outptr, fmt, "Land Area", + value_units (int_to_text (pplayer->score.landarea), " sq. mi."), + number_to_ordinal_string(rank_landarea(pplayer), TRUE)); + + outptr = strchr (outptr, '\0'); + sprintf(outptr, fmt, "Research Speed", + value_units (int_to_text (rank_calc_research(pplayer)), "%"), + number_to_ordinal_string(rank_research(pplayer), TRUE)); + + outptr = strchr (outptr, '\0'); + sprintf(outptr, fmt, "Literacy", + value_units (int_to_text (rank_calc_literacy(pplayer)), "%"), + number_to_ordinal_string(rank_literacy(pplayer), TRUE)); + + outptr = strchr (outptr, '\0'); + sprintf(outptr, fmt, "Production", + value_units (int_to_text (pplayer->score.mfg), " M tons"), + number_to_ordinal_string(rank_production(pplayer), TRUE)); + + outptr = strchr (outptr, '\0'); + sprintf(outptr, fmt, "Economics", + value_units (int_to_text (pplayer->score.bnp), " M goods"), + number_to_ordinal_string(rank_economics(pplayer), TRUE)); - sprintf(buf2, "%-20s:%d Months (%s)\n", "Military service", rank_calc_mil_service(pplayer), number_to_string(rank_mil_service(pplayer))); - strcat(buffer, buf2); + outptr = strchr (outptr, '\0'); + sprintf(outptr, fmt, "Military Service", + value_units (int_to_text (rank_calc_mil_service(pplayer)), " months"), + number_to_ordinal_string(rank_mil_service(pplayer), TRUE)); + + outptr = strchr (outptr, '\0'); + sprintf(outptr, fmt, "Pollution", + value_units (int_to_text (pplayer->score.pollution), " tons"), + number_to_ordinal_string(rank_pollution(pplayer), TRUE)); - sprintf(buf2, "%-20s:%d Tons (%s)\n", "Pollution", pplayer->score.pollution, number_to_string(rank_pollution(pplayer))); - strcat(buffer, buf2); - - page_player(pplayer, "Demographics Report:", - civbuf, buffer); + page_player (pplayer, "Demographics Report:", civbuf, buffer); } /* create a log file of the civilizations so you can see what was happening */