Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2003:
[Freeciv-Dev] Re: (PR#4582) move civ_score() into server
Home

[Freeciv-Dev] Re: (PR#4582) move civ_score() into server

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] Re: (PR#4582) move civ_score() into server
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 16 Jul 2003 15:15:59 -0700
Reply-to: rt@xxxxxxxxxxxxxx

Gregory Berkolaiko wrote:
> On Wed, 16 Jul 2003, Jason Short wrote:
> 
>>Currently civ_score() (along with a whole heap of associated functions) 
>>is in common/game.c.
>>
>>It should be obvious that only the server can ever hope to use this 
>>function.  Moreover, the borders patch requires civ_score to call other 
>>server functions.  Thus we need to move this function into the server...
>>
>>This patch puts it into server/gamehand.c.  Perhaps there is a better 
>>place for it?  Is it worth creating server/score.c?
> 
> 
> I think creating score.c is a grand idea.

OK...


? rc
? server/score.c
? server/score.h
Index: common/game.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.c,v
retrieving revision 1.164
diff -u -r1.164 game.c
--- common/game.c       2003/06/30 20:53:24     1.164
+++ common/game.c       2003/07/16 22:13:23
@@ -66,359 +66,9 @@
 };
 */
 
-#define USER_AREA_MULT (1000)
-
-struct claim_cell {
-  int when;
-  int whom;
-  int know;
-  int cities;
-};
-
-struct claim_map {
-  struct claim_cell *claims;
-  int *player_landarea;
-  int *player_owndarea;
-  struct map_position *edges;
-};
-
 /**************************************************************************
-Land Area Debug...
-**************************************************************************/
-
-#define LAND_AREA_DEBUG 0
-
-#if LAND_AREA_DEBUG >= 2
-
-static char when_char (int when)
-{
-  static char list[] =
-  {
-    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
-    'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
-    'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
-    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
-    'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
-    'y', 'z'
-  };
-
-  return (((when >= 0) && (when < sizeof (list))) ? list[when] : '?');
-}
-
-/* 
- * Writes the map_char_expr expression for each position on the map.
- * map_char_expr is provided with the variables x,y to evaluate the
- * position. The 'type' argument is used for formatting by printf; for
- * instance it should be "%c" for characters.
- */
-#define WRITE_MAP_DATA(type, map_char_expr)        \
-{                                                  \
-  int x, y;                                        \
-  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++) {              \
-      if (regular_map_pos_is_normal(x, y)) {       \
-       printf(type, map_char_expr);               \
-      } else {                                     \
-       putchar(' ');                              \
-      }                                            \
-    }                                              \
-    printf(" %d\n", y % 10);                        \
-  }                                                \
-}
-
-/**************************************************************************
 ...
 **************************************************************************/
-static void print_landarea_map(struct claim_map *pcmap, int turn)
-{
-  int p;
-
-  if (turn == 0) {
-    putchar ('\n');
-  }
-
-  if (turn == 0)
-    {
-      printf ("Player Info...\n");
-
-      for (p = 0; p < game.nplayers; p++)
-       {
-         printf (".know (%d)\n  ", p);
-         WRITE_MAP_DATA("%c",
-                        TEST_BIT(pcmap->claims[map_pos_to_index(x, y)].know,
-                                 p) ? 'X' : '-');
-         printf (".cities (%d)\n  ", p);
-         WRITE_MAP_DATA("%c",
-                        TEST_BIT(pcmap->
-                                 claims[map_pos_to_index(x, y)].cities,
-                                 p) ? 'O' : '-');
-       }
-    }
-
-  printf ("Turn %d (%c)...\n", turn, when_char (turn));
-
-  printf (".whom\n  ");
-  WRITE_MAP_DATA((pcmap->claims[map_pos_to_index(x, y)].whom ==
-                 32) ? "%c" : "%X",
-                (pcmap->claims[map_pos_to_index(x, y)].whom ==
-                 32) ? '-' : pcmap->claims[map_pos_to_index(x, y)].whom);
-
-  printf (".when\n  ");
-  WRITE_MAP_DATA("%c", when_char(pcmap->claims[map_pos_to_index(x, y)].when));
-}
-
-#endif
-
-/**************************************************************************
-Allocates, fills and returns a land area claim map.
-Call free_landarea_map(&cmap) to free allocated memory.
-**************************************************************************/
-
-static int no_owner = MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS;
-
-/**************************************************************************
-allocate and clear claim map; determine city radii
-**************************************************************************/
-static void build_landarea_map_new(struct claim_map *pcmap)
-{
-  int nbytes;
-
-  nbytes = map.xsize * map.ysize * sizeof(struct claim_cell);
-  pcmap->claims = (struct claim_cell *)fc_malloc(nbytes);
-  memset (pcmap->claims, 0, nbytes);
-
-  nbytes  = game.nplayers * sizeof(int);
-  pcmap->player_landarea = (int *)fc_malloc(nbytes);
-  memset (pcmap->player_landarea, 0, nbytes);
-
-  nbytes  = game.nplayers * sizeof(int);
-  pcmap->player_owndarea = (int *)fc_malloc(nbytes);
-  memset (pcmap->player_owndarea, 0, nbytes);
-
-  nbytes = 2 * map.xsize * map.ysize * sizeof(struct map_position);
-  pcmap->edges = (struct map_position *)fc_malloc(nbytes);
-
-  players_iterate(pplayer) {
-    city_list_iterate(pplayer->cities, pcity) {
-      map_city_radius_iterate(pcity->x, pcity->y, x, y) {
-       int i = map_pos_to_index(x, y);
-       pcmap->claims[i].cities |= (1u << pcity->owner);
-      } map_city_radius_iterate_end;
-    } city_list_iterate_end;
-  } players_iterate_end;
-}
-
-/**************************************************************************
-0th turn: install starting points, counting their tiles
-**************************************************************************/
-static void build_landarea_map_turn_0(struct claim_map *pcmap)
-{
-  int turn;
-  struct map_position *nextedge;
-  struct claim_cell *pclaim;
-  struct tile *ptile;
-  int owner;
-
-  turn = 0;
-  nextedge = pcmap->edges;
-
-  whole_map_iterate(x, y) {
-    int i = map_pos_to_index(x, y);
-    pclaim = &(pcmap->claims[i]);
-    ptile = &(map.tiles[i]);
-
-    if (is_ocean(ptile->terrain)) {
-      /* pclaim->when = 0; */
-      pclaim->whom = no_owner;
-      /* pclaim->know = 0; */
-    } else if (ptile->city) {
-      owner = ptile->city->owner;
-      pclaim->when = turn + 1;
-      pclaim->whom = owner;
-      nextedge->x = x;
-      nextedge->y = y;
-      nextedge++;
-      (pcmap->player_landarea[owner])++;
-      (pcmap->player_owndarea[owner])++;
-      pclaim->know = ptile->known;
-    } else if (ptile->worked) {
-      owner = ptile->worked->owner;
-      pclaim->when = turn + 1;
-      pclaim->whom = owner;
-      nextedge->x = x;
-      nextedge->y = y;
-      nextedge++;
-      (pcmap->player_landarea[owner])++;
-      (pcmap->player_owndarea[owner])++;
-      pclaim->know = ptile->known;
-    } else if (unit_list_size (&(ptile->units)) > 0) {
-      owner = (unit_list_get (&(ptile->units), 0))->owner;
-      pclaim->when = turn + 1;
-      pclaim->whom = owner;
-      nextedge->x = x;
-      nextedge->y = y;
-      nextedge++;
-      (pcmap->player_landarea[owner])++;
-      if (TEST_BIT(pclaim->cities, owner)) {
-       (pcmap->player_owndarea[owner])++;
-      }
-      pclaim->know = ptile->known;
-    } else {
-      /* pclaim->when = 0; */
-      pclaim->whom = no_owner;
-      pclaim->know = ptile->known;
-    }
-  } whole_map_iterate_end;
-
-  nextedge->x = -1;
-
-#if LAND_AREA_DEBUG >= 2
-  print_landarea_map (pcmap, turn);
-#endif
-}
-
-
-/**************************************************************************
-expand outwards evenly from each starting point, counting tiles
-**************************************************************************/
-static void build_landarea_map_expand(struct claim_map *pcmap)
-{
-  int x, y, i, j;
-  struct map_position *midedge;
-  int turn;
-  struct map_position *thisedge;
-  struct map_position *nextedge;
-  int accum;
-  struct claim_cell *pclaim;
-  int owner, other;
-
-  midedge = &(pcmap->edges[map.xsize * map.ysize]);
-
-  for (accum = 1, turn = 1; accum > 0; turn++) {
-    thisedge = ((turn & 0x1) == 1) ? pcmap->edges : midedge;
-    nextedge = ((turn & 0x1) == 1) ? midedge : pcmap->edges;
-
-    for (accum = 0; thisedge->x >= 0; thisedge++) {
-      x = thisedge->x;
-      y = thisedge->y;
-      i = map_pos_to_index (x, y);
-      owner = pcmap->claims[i].whom;
-
-      if (owner != no_owner) {
-       adjc_iterate(x, y, mx, my) {
-         j = map_pos_to_index(mx, my);
-         pclaim = &(pcmap->claims[j]);
-
-         if (TEST_BIT(pclaim->know, owner)) {
-           if (pclaim->when == 0) {
-             pclaim->when = turn + 1;
-             pclaim->whom = owner;
-             nextedge->x = mx;
-             nextedge->y = my;
-             nextedge++;
-             (pcmap->player_landarea[owner])++;
-             if (TEST_BIT(pclaim->cities, owner)) {
-               (pcmap->player_owndarea[owner])++;
-             }
-             accum++;
-           } else if ((pclaim->when == (turn + 1)) &&
-                      (pclaim->whom != no_owner) &&
-                      (pclaim->whom != owner)) {
-             other = pclaim->whom;
-             if (TEST_BIT(pclaim->cities, other)) {
-               (pcmap->player_owndarea[other])--;
-             }
-             (pcmap->player_landarea[other])--;
-             pclaim->whom = no_owner;
-             accum--;
-           }
-         }
-       } adjc_iterate_end;
-      }
-    }
-
-    nextedge->x = -1;
-
-#if LAND_AREA_DEBUG >= 2
-    print_landarea_map (pcmap, turn);
-#endif
-  }
-}
-
-/**************************************************************************
-this just calls the three worker routines
-**************************************************************************/
-static void build_landarea_map(struct claim_map *pcmap)
-{
-  build_landarea_map_new (pcmap);
-  build_landarea_map_turn_0 (pcmap);
-  build_landarea_map_expand (pcmap);
-}
-
-/**************************************************************************
-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;
-    }
-    if (pcmap->player_owndarea) {
-      free (pcmap->player_owndarea);
-      pcmap->player_owndarea = NULL;
-    }
-    if (pcmap->edges) {
-      free (pcmap->edges);
-      pcmap->edges = NULL;
-    }
-  }
-}
-
-/**************************************************************************
-Returns the given player's land and settled areas from a claim map.
-**************************************************************************/
-static void get_player_landarea(struct claim_map *pcmap, struct player 
*pplayer,
-                                int *return_landarea, int *return_settledarea)
-{
-  if (pcmap && pplayer) {
-#if LAND_AREA_DEBUG >= 1
-    printf ("%-14s", pplayer->name);
-#endif
-    if (return_landarea && pcmap->player_landarea) {
-      *return_landarea =
-       USER_AREA_MULT * pcmap->player_landarea[pplayer->player_no];
-#if LAND_AREA_DEBUG >= 1
-      printf (" l=%d", *return_landarea / USER_AREA_MULT);
-#endif
-    }
-    if (return_settledarea && pcmap->player_owndarea) {
-      *return_settledarea =
-       USER_AREA_MULT * pcmap->player_owndarea[pplayer->player_no];
-#if LAND_AREA_DEBUG >= 1
-      printf (" s=%d", *return_settledarea / USER_AREA_MULT);
-#endif
-    }
-#if LAND_AREA_DEBUG >= 1
-    printf ("\n");
-#endif
-  }
-}
-
-/**************************************************************************
-...
-**************************************************************************/
 int total_player_citizens(struct player *pplayer)
 {
   return (pplayer->score.happy
@@ -428,106 +78,6 @@
          +pplayer->score.scientists
          +pplayer->score.elvis
          +pplayer->score.taxmen);
-}
-
-/**************************************************************************
-...
-**************************************************************************/
-int civ_score(struct player *pplayer)
-{
-  int i;
-  struct city *pcity;
-  int landarea, settledarea;
-  static struct claim_map cmap = { NULL, NULL, NULL,NULL };
-
-  pplayer->score.happy=0;                       /* done */
-  pplayer->score.content=0;                     /* done */   
-  pplayer->score.unhappy=0;                     /* done */
-  pplayer->score.angry=0;                       /* done */
-  pplayer->score.taxmen=0;                      /* done */
-  pplayer->score.scientists=0;                  /* done */
-  pplayer->score.elvis=0;                       /* done */ 
-  pplayer->score.wonders=0;                     /* done */
-  pplayer->score.techs=0;                       /* done */
-  pplayer->score.techout=0;                     /* done */
-  pplayer->score.landarea=0;
-  pplayer->score.settledarea=0;
-  pplayer->score.population=0;
-  pplayer->score.cities=0;                      /* done */
-  pplayer->score.units=0;                       /* done */
-  pplayer->score.pollution=0;                   /* done */
-  pplayer->score.bnp=0;                         /* done */
-  pplayer->score.mfg=0;                         /* done */
-  pplayer->score.literacy=0;
-  pplayer->score.spaceship=0;
-
-  if (is_barbarian(pplayer)) {
-    if (pplayer->player_no == (game.nplayers - 1)) {
-      free_landarea_map(&cmap);
-    }
-    return 0;
-  }
-
-  city_list_iterate(pplayer->cities, pcity) {
-    pplayer->score.happy+=pcity->ppl_happy[4];
-    pplayer->score.content+=pcity->ppl_content[4];
-    pplayer->score.unhappy+=pcity->ppl_unhappy[4];
-    pplayer->score.angry+=pcity->ppl_angry[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+=pcity->science_total;
-    pplayer->score.bnp+=pcity->trade_prod;
-    pplayer->score.mfg+=pcity->shield_surplus;
-    if (city_got_building(pcity, B_UNIVERSITY)) 
-      pplayer->score.literacy+=city_population(pcity);
-    else if (city_got_building(pcity,B_LIBRARY))
-      pplayer->score.literacy+=(city_population(pcity)/2);
-  }
-  city_list_iterate_end;
-
-  if (pplayer->player_no == 0) {
-    free_landarea_map(&cmap);
-    build_landarea_map(&cmap);
-  }
-  get_player_landarea(&cmap, pplayer, &landarea, &settledarea);
-  pplayer->score.landarea=landarea;
-  pplayer->score.settledarea=settledarea;
-  if (pplayer->player_no == (game.nplayers - 1)) {
-    free_landarea_map(&cmap);
-  }
-
-  for (i=0;i<game.num_tech_types;i++) 
-    if (get_invention(pplayer, i)==TECH_KNOWN) 
-      pplayer->score.techs++;
-  pplayer->score.techs+=(((pplayer->future_tech)*5)/2);
-  
-  unit_list_iterate(pplayer->units, punit) 
-    if (is_military_unit(punit)) pplayer->score.units++;
-  unit_list_iterate_end;
-
-  impr_type_iterate(i) {
-    if (is_wonder(i) && (pcity=find_city_by_id(game.global_wonders[i])) && 
-       player_owns_city(pplayer, pcity))
-      pplayer->score.wonders++;
-  } impr_type_iterate_end;
-
-  /* How much should a spaceship be worth??
-     This gives 100 points per 10,000 citizens.  --dwp
-  */
-  if (pplayer->spaceship.state == SSHIP_ARRIVED) {
-    pplayer->score.spaceship += (int)(100 * pplayer->spaceship.habitation
-                                     * pplayer->spaceship.success_rate);
-  }
-
-  return (total_player_citizens(pplayer)
-         +pplayer->score.happy
-         +pplayer->score.techs*2
-         +pplayer->score.wonders*5
-         +pplayer->score.spaceship);
 }
 
 /**************************************************************************
Index: common/game.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.h,v
retrieving revision 1.121
diff -u -r1.121 game.h
--- common/game.h       2003/04/17 20:06:36     1.121
+++ common/game.h       2003/07/16 22:13:23
@@ -246,7 +246,6 @@
 void game_remove_unit(struct unit *punit);
 void game_remove_city(struct city *pcity);
 int total_player_citizens(struct player *pplayer);
-int civ_score(struct player *pplayer);
 void initialize_globals(void);
 
 void translate_data_names(void);
Index: server/Makefile.am
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/Makefile.am,v
retrieving revision 1.27
diff -u -r1.27 Makefile.am
--- server/Makefile.am  2003/07/10 03:34:30     1.27
+++ server/Makefile.am  2003/07/16 22:13:23
@@ -57,6 +57,8 @@
                sanitycheck.h   \
                savegame.c      \
                savegame.h      \
+               score.c         \
+               score.h         \
                sernet.c        \
                sernet.h        \
                settlers.c      \
Index: server/gamelog.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gamelog.c,v
retrieving revision 1.27
diff -u -r1.27 gamelog.c
--- server/gamelog.c    2003/04/04 15:47:49     1.27
+++ server/gamelog.c    2003/07/16 22:13:23
@@ -21,13 +21,13 @@
 #include <string.h>
 
 #include "fcintl.h"
-#include "game.h"
 #include "log.h"
 #include "map.h"
 #include "mem.h"
 #include "support.h"
 
 #include "gamelog.h"
+#include "score.h"
 
 int gamelog_level;             /* also accessed from stdinhand.c */
 static char *gamelog_filename;
Index: server/report.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/report.c,v
retrieving revision 1.44
diff -u -r1.44 report.c
--- server/report.c     2003/04/04 15:47:50     1.44
+++ server/report.c     2003/07/16 22:13:23
@@ -20,7 +20,6 @@
 
 #include "events.h"
 #include "fcintl.h"
-#include "game.h"
 #include "government.h"
 #include "log.h"
 #include "mem.h"
@@ -31,8 +30,8 @@
 #include "version.h"
 
 #include "citytools.h"
-
 #include "report.h"
+#include "score.h"
 
 static void page_conn_etype(struct conn_list *dest, const char *caption,
                            const char *headline, const char *lines,
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.130
diff -u -r1.130 srv_main.c
--- server/srv_main.c   2003/07/13 01:51:11     1.130
+++ server/srv_main.c   2003/07/16 22:13:23
@@ -84,6 +84,7 @@
 #include "ruleset.h"
 #include "sanitycheck.h"
 #include "savegame.h"
+#include "score.h"
 #include "sernet.h"
 #include "settlers.h"
 #include "spacerace.h"
/**********************************************************************
 Freeciv - Copyright (C) 2003 - The Freeciv Project
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
***********************************************************************/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <string.h>

#include "improvement.h"
#include "map.h"
#include "mem.h"
#include "player.h"
#include "score.h"
#include "unit.h"


/**************************************************************************
  Allocates, fills and returns a land area claim map.
  Call free_landarea_map(&cmap) to free allocated memory.
**************************************************************************/

#define USER_AREA_MULT 1000

struct claim_cell {
  int when;
  int whom;
  int know;
  int cities;
};

struct claim_map {
  struct claim_cell *claims;
  int *player_landarea;
  int *player_owndarea;
  struct map_position *edges;
};

/**************************************************************************
Land Area Debug...
**************************************************************************/

#define LAND_AREA_DEBUG 0

#if LAND_AREA_DEBUG >= 2

static char when_char(int when)
{
  static char list[] = {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
    'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
    'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
    'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
    'y', 'z'
  };

  return (when >= 0 && when < sizeof(list)) ? list[when] : '?';
}

/* 
 * Writes the map_char_expr expression for each position on the map.
 * map_char_expr is provided with the variables x,y to evaluate the
 * position. The 'type' argument is used for formatting by printf; for
 * instance it should be "%c" for characters.
 */
#define WRITE_MAP_DATA(type, map_char_expr)        \
{                                                  \
  int x, y;                                        \
  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++) {              \
      if (regular_map_pos_is_normal(x, y)) {       \
        printf(type, map_char_expr);               \
      } else {                                     \
        putchar(' ');                              \
      }                                            \
    }                                              \
    printf(" %d\n", y % 10);                       \
  }                                                \
}

/**************************************************************************
  Prints the landarea map to stdout (a debugging tool).
**************************************************************************/
static void print_landarea_map(struct claim_map *pcmap, int turn)
{
  int p;

  if (turn == 0) {
    putchar('\n');
  }

  if (turn == 0) {
    printf("Player Info...\n");

    for (p = 0; p < game.nplayers; p++) {
      printf(".know (%d)\n  ", p);
      WRITE_MAP_DATA("%c",
                     TEST_BIT(pcmap->claims[map_pos_to_index(x, y)].know,
                              p) ? 'X' : '-');
      printf(".cities (%d)\n  ", p);
      WRITE_MAP_DATA("%c",
                     TEST_BIT(pcmap->
                              claims[map_pos_to_index(x, y)].cities,
                              p) ? 'O' : '-');
    }
  }

  printf("Turn %d (%c)...\n", turn, when_char (turn));

  printf(".whom\n  ");
  WRITE_MAP_DATA((pcmap->claims[map_pos_to_index(x, y)].whom ==
                  32) ? "%c" : "%X",
                 (pcmap->claims[map_pos_to_index(x, y)].whom ==
                  32) ? '-' : pcmap->claims[map_pos_to_index(x, y)].whom);

  printf(".when\n  ");
  WRITE_MAP_DATA("%c", when_char(pcmap->claims[map_pos_to_index(x, y)].when));
}

#endif

static int no_owner = MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS;

/**************************************************************************
  allocate and clear claim map; determine city radii
**************************************************************************/
static void build_landarea_map_new(struct claim_map *pcmap)
{
  int nbytes;

  nbytes = map.xsize * map.ysize * sizeof(struct claim_cell);
  pcmap->claims = fc_malloc(nbytes);
  memset(pcmap->claims, 0, nbytes);

  nbytes = game.nplayers * sizeof(int);
  pcmap->player_landarea = fc_malloc(nbytes);
  memset(pcmap->player_landarea, 0, nbytes);

  nbytes = game.nplayers * sizeof(int);
  pcmap->player_owndarea = fc_malloc(nbytes);
  memset(pcmap->player_owndarea, 0, nbytes);

  nbytes = 2 * map.xsize * map.ysize * sizeof(struct map_position);
  pcmap->edges = fc_malloc(nbytes);

  players_iterate(pplayer) {
    city_list_iterate(pplayer->cities, pcity) {
      map_city_radius_iterate(pcity->x, pcity->y, x, y) {
        int i = map_pos_to_index(x, y);

        pcmap->claims[i].cities |= (1u << pcity->owner);
      } map_city_radius_iterate_end;
    } city_list_iterate_end;
  } players_iterate_end;
}

/**************************************************************************
  0th turn: install starting points, counting their tiles
**************************************************************************/
static void build_landarea_map_turn_0(struct claim_map *pcmap)
{
  int turn, owner;
  struct map_position *nextedge;
  struct claim_cell *pclaim;
  struct tile *ptile;

  turn = 0;
  nextedge = pcmap->edges;

  whole_map_iterate(x, y) {
    int i = map_pos_to_index(x, y);

    pclaim = &pcmap->claims[i];
    ptile = &map.tiles[i];

    if (is_ocean(ptile->terrain)) {
      /* pclaim->when = 0; */
      pclaim->whom = no_owner;
      /* pclaim->know = 0; */
    } else if (ptile->city) {
      owner = ptile->city->owner;
      pclaim->when = turn + 1;
      pclaim->whom = owner;
      nextedge->x = x;
      nextedge->y = y;
      nextedge++;
      pcmap->player_landarea[owner]++;
      pcmap->player_owndarea[owner]++;
      pclaim->know = ptile->known;
    } else if (ptile->worked) {
      owner = ptile->worked->owner;
      pclaim->when = turn + 1;
      pclaim->whom = owner;
      nextedge->x = x;
      nextedge->y = y;
      nextedge++;
      pcmap->player_landarea[owner]++;
      pcmap->player_owndarea[owner]++;
      pclaim->know = ptile->known;
    } else if (unit_list_size(&ptile->units) > 0) {
      owner = (unit_list_get(&ptile->units, 0))->owner;
      pclaim->when = turn + 1;
      pclaim->whom = owner;
      nextedge->x = x;
      nextedge->y = y;
      nextedge++;
      pcmap->player_landarea[owner]++;
      if (TEST_BIT(pclaim->cities, owner)) {
        pcmap->player_owndarea[owner]++;
      }
      pclaim->know = ptile->known;
    } else {
      /* pclaim->when = 0; */
      pclaim->whom = no_owner;
      pclaim->know = ptile->known;
    }
  } whole_map_iterate_end;

  nextedge->x = -1;

#if LAND_AREA_DEBUG >= 2
  print_landarea_map(pcmap, turn);
#endif
}

/**************************************************************************
  expand outwards evenly from each starting point, counting tiles
**************************************************************************/
static void build_landarea_map_expand(struct claim_map *pcmap)
{
  struct map_position *midedge;
  int turn, accum, other;
  struct map_position *thisedge;
  struct map_position *nextedge;

  midedge = &pcmap->edges[map.xsize * map.ysize];

  for (accum = 1, turn = 1; accum > 0; turn++) {
    thisedge = ((turn & 0x1) == 1) ? pcmap->edges : midedge;
    nextedge = ((turn & 0x1) == 1) ? midedge : pcmap->edges;

    for (accum = 0; thisedge->x >= 0; thisedge++) {
      int x = thisedge->x;
      int y = thisedge->y;
      int i = map_pos_to_index (x, y);
      int owner = pcmap->claims[i].whom;

      if (owner != no_owner) {
        adjc_iterate(x, y, mx, my) {
          int j = map_pos_to_index(mx, my);
          struct claim_cell *pclaim = &pcmap->claims[j];

          if (TEST_BIT(pclaim->know, owner)) {
            if (pclaim->when == 0) {
              pclaim->when = turn + 1;
              pclaim->whom = owner;
              nextedge->x = mx;
              nextedge->y = my;
              nextedge++;
              pcmap->player_landarea[owner]++;
              if (TEST_BIT(pclaim->cities, owner)) {
                pcmap->player_owndarea[owner]++;
              }
              accum++;
            } else if (pclaim->when == turn + 1
                       && pclaim->whom != no_owner
                       && pclaim->whom != owner) {
              other = pclaim->whom;
              if (TEST_BIT(pclaim->cities, other)) {
                pcmap->player_owndarea[other]--;
              }
              pcmap->player_landarea[other]--;
              pclaim->whom = no_owner;
              accum--;
            }
          }
        } adjc_iterate_end;
      }
    }

    nextedge->x = -1;

#if LAND_AREA_DEBUG >= 2
    print_landarea_map(pcmap, turn);
#endif
  }
}

/**************************************************************************
  this just calls the three worker routines
**************************************************************************/
static void build_landarea_map(struct claim_map *pcmap)
{
  build_landarea_map_new(pcmap);
  build_landarea_map_turn_0(pcmap);
  build_landarea_map_expand(pcmap);
}

/**************************************************************************
  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;
    }
    if (pcmap->player_owndarea) {
      free(pcmap->player_owndarea);
      pcmap->player_owndarea = NULL;
    }
    if (pcmap->edges) {
      free(pcmap->edges);
      pcmap->edges = NULL;
    }
  }
}

/**************************************************************************
  Returns the given player's land and settled areas from a claim map.
**************************************************************************/
static void get_player_landarea(struct claim_map *pcmap,
                                struct player *pplayer,
                                int *return_landarea,
                                int *return_settledarea)
{
  if (pcmap && pplayer) {
#if LAND_AREA_DEBUG >= 1
    printf("%-14s", pplayer->name);
#endif
    if (return_landarea && pcmap->player_landarea) {
      *return_landarea =
        USER_AREA_MULT * pcmap->player_landarea[pplayer->player_no];
#if LAND_AREA_DEBUG >= 1
      printf(" l=%d", *return_landarea / USER_AREA_MULT);
#endif
    }
    if (return_settledarea && pcmap->player_owndarea) {
      *return_settledarea =
        USER_AREA_MULT * pcmap->player_owndarea[pplayer->player_no];
#if LAND_AREA_DEBUG >= 1
      printf(" s=%d", *return_settledarea / USER_AREA_MULT);
#endif
    }
#if LAND_AREA_DEBUG >= 1
    printf("\n");
#endif
  }
}

/**************************************************************************
  Return the civilization score (a numerical value) for the player.
**************************************************************************/
int civ_score(struct player *pplayer)
{
  int i;
  struct city *pcity;
  int landarea, settledarea;
  static struct claim_map cmap = { NULL, NULL, NULL,NULL };

  pplayer->score.happy = 0;
  pplayer->score.content = 0;
  pplayer->score.unhappy = 0;
  pplayer->score.angry = 0;
  pplayer->score.taxmen = 0;
  pplayer->score.scientists = 0;
  pplayer->score.elvis = 0;
  pplayer->score.wonders = 0;
  pplayer->score.techs = 0;
  pplayer->score.techout = 0;
  pplayer->score.landarea = 0;
  pplayer->score.settledarea = 0;
  pplayer->score.population = 0;
  pplayer->score.cities = 0;
  pplayer->score.units = 0;
  pplayer->score.pollution = 0;
  pplayer->score.bnp = 0;
  pplayer->score.mfg = 0;
  pplayer->score.literacy = 0;
  pplayer->score.spaceship = 0;

  if (is_barbarian(pplayer)) {
    if (pplayer->player_no == game.nplayers - 1) {
      free_landarea_map(&cmap);
    }
    return 0;
  }

  city_list_iterate(pplayer->cities, pcity) {
    pplayer->score.happy += pcity->ppl_happy[4];
    pplayer->score.content += pcity->ppl_content[4];
    pplayer->score.unhappy += pcity->ppl_unhappy[4];
    pplayer->score.angry += pcity->ppl_angry[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 += pcity->science_total;
    pplayer->score.bnp += pcity->trade_prod;
    pplayer->score.mfg += pcity->shield_surplus;
    if (city_got_building(pcity, B_UNIVERSITY)) {
      pplayer->score.literacy += city_population(pcity);
    } else if (city_got_building(pcity,B_LIBRARY)) {
      pplayer->score.literacy += city_population(pcity) / 2;
    }
  } city_list_iterate_end;

  if (pplayer->player_no == 0) {
    free_landarea_map(&cmap);
    build_landarea_map(&cmap);
  }
  get_player_landarea(&cmap, pplayer, &landarea, &settledarea);
  pplayer->score.landarea = landarea;
  pplayer->score.settledarea = settledarea;
  if (pplayer->player_no == game.nplayers - 1) {
    free_landarea_map(&cmap);
  }

  for (i = 0; i < game.num_tech_types; i++) {
    if (get_invention(pplayer, i)==TECH_KNOWN) {
      pplayer->score.techs++;
    }
  }
  pplayer->score.techs += pplayer->future_tech * 5 / 2;
  
  unit_list_iterate(pplayer->units, punit) {
    if (is_military_unit(punit)) {
      pplayer->score.units++;
    }
  } unit_list_iterate_end

  impr_type_iterate(i) {
    if (is_wonder(i)
        && (pcity = find_city_by_id(game.global_wonders[i]))
        && player_owns_city(pplayer, pcity)) {
      pplayer->score.wonders++;
    }
  } impr_type_iterate_end;

  /* How much should a spaceship be worth?
   * This gives 100 points per 10,000 citizens. */
  if (pplayer->spaceship.state == SSHIP_ARRIVED) {
    pplayer->score.spaceship += (int)(100 * pplayer->spaceship.habitation
                                      * pplayer->spaceship.success_rate);
  }

  return (total_player_citizens(pplayer)
          + pplayer->score.happy
          + pplayer->score.techs * 2
          + pplayer->score.wonders * 5
          + pplayer->score.spaceship);
}
/********************************************************************** 
 Freeciv - Copyright (C) 2003 - The Freeciv Project
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
***********************************************************************/

#ifndef FC__SCORE_H
#define FC__SCORE_H

int civ_score(struct player *pplayer);

#endif /* FC__SCORE_H */

[Prev in Thread] Current Thread [Next in Thread]