Complete.Org: Mailing Lists: Archives: freeciv-dev: October 2004:
[Freeciv-Dev] (PR#10359) Saving changes game state
Home

[Freeciv-Dev] (PR#10359) Saving changes game state

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: marko.lindqvist@xxxxxxxxxxx
Subject: [Freeciv-Dev] (PR#10359) Saving changes game state
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 5 Oct 2004 08:16:19 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=10359 >

pplayer->score is only set in the server (in fact it's not even
initialized in player_init).

So I thought that it should be moved into a server structure.  I moved
it into player_scores[] in server/score.c.  And I found two bad things:

- total_player_citizens(), in common/game.c, uses the score data.  But
this function is server-only (it will return random garbage if called at
the client).

- Some AI code accesses the score data.  In one place
total_player_citizens() is called.  In another player score.mfg is
checked to look at the "production leader".

Both should be fixed.  But I'm not sure how best to fix the second.

This patch makes the scores change and should probably be applied.  But
it doesn't entirely fix the problem and may even be a step backwards if
we later decide to send the scores data to the client.

jason

? 1
? 2
Index: ai/aidata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aidata.c,v
retrieving revision 1.44
diff -u -r1.44 aidata.c
--- ai/aidata.c 29 Sep 2004 02:24:18 -0000      1.44
+++ ai/aidata.c 5 Oct 2004 15:11:52 -0000
@@ -28,6 +28,7 @@
 #include "citytools.h"
 #include "diplhand.h"
 #include "maphand.h"
+#include "score.h"
 #include "settlers.h"
 #include "unittools.h"
 
@@ -349,7 +350,8 @@
   ai->diplomacy.production_leader = NULL;
   players_iterate(aplayer) {
     if (ai->diplomacy.production_leader == NULL
-        || ai->diplomacy.production_leader->score.mfg < aplayer->score.mfg) {
+        || (player_scores[ai->diplomacy.production_leader->player_no].mfg
+           < player_scores[aplayer->player_no].mfg)) {
       ai->diplomacy.production_leader = aplayer;
     }
   } players_iterate_end;
Index: ai/aitools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aitools.c,v
retrieving revision 1.126
diff -u -r1.126 aitools.c
--- ai/aitools.c        29 Sep 2004 02:24:18 -0000      1.126
+++ ai/aitools.c        5 Oct 2004 15:11:53 -0000
@@ -40,6 +40,7 @@
 #include "gotohand.h"
 #include "maphand.h"
 #include "plrhand.h"
+#include "score.h"
 #include "settlers.h"
 #include "unithand.h"
 #include "unittools.h"
Index: common/game.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.c,v
retrieving revision 1.187
diff -u -r1.187 game.c
--- common/game.c       29 Sep 2004 02:24:22 -0000      1.187
+++ common/game.c       5 Oct 2004 15:11:53 -0000
@@ -66,20 +66,6 @@
 */
 
 /**************************************************************************
-...
-**************************************************************************/
-int total_player_citizens(struct player *pplayer)
-{
-  return (pplayer->score.happy
-         +pplayer->score.content
-         +pplayer->score.unhappy
-         +pplayer->score.angry
-         +pplayer->score.scientists
-         +pplayer->score.elvis
-         +pplayer->score.taxmen);
-}
-
-/**************************************************************************
 Count the # of thousand citizen in a civilisation.
 **************************************************************************/
 int civ_population(struct player *pplayer)
Index: common/game.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.h,v
retrieving revision 1.152
diff -u -r1.152 game.h
--- common/game.h       16 Sep 2004 04:38:24 -0000      1.152
+++ common/game.h       5 Oct 2004 15:11:54 -0000
@@ -274,7 +274,6 @@
 
 void game_remove_unit(struct unit *punit);
 void game_remove_city(struct city *pcity);
-int total_player_citizens(struct player *pplayer);
 void initialize_globals(void);
 
 void translate_data_names(void);
Index: common/player.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.c,v
retrieving revision 1.157
diff -u -r1.157 player.c
--- common/player.c     29 Sep 2004 02:24:23 -0000      1.157
+++ common/player.c     5 Oct 2004 15:11:54 -0000
@@ -72,7 +72,7 @@
 /****************************************************************
 ...
 *****************************************************************/
-bool player_owns_city(struct player *pplayer, struct city *pcity)
+bool player_owns_city(const struct player *pplayer, const struct city *pcity)
 {
   if (!pcity || !pplayer)
     return FALSE;                      /* better safe than sorry */
Index: common/player.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.h,v
retrieving revision 1.130
diff -u -r1.130 player.h
--- common/player.h     29 Sep 2004 02:24:23 -0000      1.130
+++ common/player.h     5 Oct 2004 15:11:54 -0000
@@ -99,29 +99,6 @@
   int num_known_tech_with_flag[TF_LAST];
 };
 
-struct player_score {
-  int happy;
-  int content;
-  int unhappy;
-  int angry;
-  int taxmen;
-  int scientists;
-  int elvis;
-  int wonders;
-  int techs;
-  int techout;
-  int landarea;
-  int settledarea;
-  int population;      /* in thousand of citizen */
-  int cities;
-  int units;
-  int pollution;
-  int literacy;
-  int bnp;
-  int mfg;
-  int spaceship;
-};
-
 struct player_ai {
   bool control;
 
@@ -202,7 +179,6 @@
   int city_style;
   struct unit_list units;
   struct city_list cities;
-  struct player_score score;
   struct player_economic economic;
   struct player_research research;
   struct player_spaceship spaceship;
@@ -243,7 +219,8 @@
 bool can_player_see_city_internals(struct player *pplayer,
                                   struct city *pcity);
 
-bool player_owns_city(struct player *pplayer, struct city *pcity);
+bool player_owns_city(const struct player *pplayer,
+                     const struct city *pcity);
 
 struct city *player_find_city_by_id(const struct player *pplayer,
                                    int city_id);
Index: server/report.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/report.c,v
retrieving revision 1.54
diff -u -r1.54 report.c
--- server/report.c     4 Sep 2004 20:36:10 -0000       1.54
+++ server/report.c     5 Oct 2004 15:11:55 -0000
@@ -165,20 +165,22 @@
   struct player_score_entry size[game.nplayers];
 
   players_iterate(pplayer) {
+    struct player_score *score = player_scores + pplayer->player_no;
+
     if (pplayer->is_alive && !is_barbarian(pplayer)) {
       switch(which_news) {
       case HISTORIAN_RICHEST:
        size[j].value = pplayer->economic.gold;
        break;
       case HISTORIAN_ADVANCED:
-       size[j].value = (pplayer->score.techs + pplayer->future_tech);
+       size[j].value = (score->techs + pplayer->future_tech);
        break;
       case HISTORIAN_MILITARY:
-       size[j].value = pplayer->score.units;
+       size[j].value = score->units;
        break;
       case HISTORIAN_HAPPIEST: 
        size[j].value =
-           (((pplayer->score.happy - pplayer->score.unhappy) * 1000) /
+           (((score->happy - score->unhappy) * 1000) /
             (1 + total_player_citizens(pplayer)));
        break;
       case HISTORIAN_LARGEST:
@@ -330,7 +332,7 @@
 **************************************************************************/
 static int get_population(struct player *pplayer)
 {
-  return pplayer->score.population;
+  return player_scores[pplayer->player_no].population;
 }
 
 static int get_pop(struct player *pplayer)
@@ -340,17 +342,17 @@
 
 static int get_landarea(struct player *pplayer)
 {
-    return pplayer->score.landarea;
+    return player_scores[pplayer->player_no].landarea;
 }
 
 static int get_settledarea(struct player *pplayer)
 {
-  return pplayer->score.settledarea;
+  return player_scores[pplayer->player_no].settledarea;
 }
 
 static int get_research(struct player *pplayer)
 {
-  return (pplayer->score.techout * 100) / total_bulbs_required(pplayer);
+  return (player_scores[pplayer->player_no].techout * 100) / 
total_bulbs_required(pplayer);
 }
 
 static int get_literacy(struct player *pplayer)
@@ -360,40 +362,40 @@
   if (pop <= 0) {
     return 0;
   } else if (pop >= 10000) {
-    return pplayer->score.literacy / (pop / 100);
+    return player_scores[pplayer->player_no].literacy / (pop / 100);
   } else {
-    return (pplayer->score.literacy * 100) / pop;
+    return (player_scores[pplayer->player_no].literacy * 100) / pop;
   }
 }
 
 static int get_production(struct player *pplayer)
 {
-  return pplayer->score.mfg;
+  return player_scores[pplayer->player_no].mfg;
 }
 
 static int get_economics(struct player *pplayer)
 {
-  return pplayer->score.bnp;
+  return player_scores[pplayer->player_no].bnp;
 }
 
 static int get_pollution(struct player *pplayer)
 {
-  return pplayer->score.pollution;
+  return player_scores[pplayer->player_no].pollution;
 }
 
 static int get_mil_service(struct player *pplayer)
 {
-  return (pplayer->score.units * 5000) / (10 + civ_population(pplayer));
+  return (player_scores[pplayer->player_no].units * 5000) / (10 + 
civ_population(pplayer));
 }
 
 static int get_cities(struct player *pplayer)
 {
-  return pplayer->score.cities;
+  return player_scores[pplayer->player_no].cities;
 }
 
 static int get_techs(struct player *pplayer)
 {
-  return pplayer->score.techs;
+  return player_scores[pplayer->player_no].techs;
 }
 
 static int get_munits(struct player *pplayer)
@@ -426,22 +428,22 @@
 
 static int get_wonders(struct player *pplayer)
 {
-  return pplayer->score.wonders;
+  return player_scores[pplayer->player_no].wonders;
 }
 
 static int get_techout(struct player *pplayer)
 {
-  return pplayer->score.techout;
+  return player_scores[pplayer->player_no].techout;
 }
 
 static int get_literacy2(struct player *pplayer)
 {
-  return pplayer->score.literacy;
+  return player_scores[pplayer->player_no].literacy;
 }
 
 static int get_spaceship(struct player *pplayer)
 {
-  return pplayer->score.spaceship;
+  return player_scores[pplayer->player_no].spaceship;
 }
 
 static int get_gold(struct player *pplayer)
@@ -479,32 +481,32 @@
 
 static int get_happypop(struct player *pplayer)
 {
-  return pplayer->score.happy;
+  return player_scores[pplayer->player_no].happy;
 }
 
 static int get_contentpop(struct player *pplayer)
 {
-  return pplayer->score.content;
+  return player_scores[pplayer->player_no].content;
 }
 
 static int get_unhappypop(struct player *pplayer)
 {
-  return pplayer->score.unhappy;
+  return player_scores[pplayer->player_no].unhappy;
 }
 
 static int get_taxmen(struct player *pplayer)
 {
-  return pplayer->score.taxmen;
+  return player_scores[pplayer->player_no].taxmen;
 }
 
 static int get_scientists(struct player *pplayer)
 {
-  return pplayer->score.scientists;
+  return player_scores[pplayer->player_no].scientists;
 }
 
 static int get_elvis(struct player *pplayer)
 {
-  return pplayer->score.elvis;
+  return player_scores[pplayer->player_no].elvis;
 }
 
 static int get_gov(struct player *pplayer)
Index: server/score.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/score.c,v
retrieving revision 1.8
diff -u -r1.8 score.c
--- server/score.c      29 Sep 2004 02:24:24 -0000      1.8
+++ server/score.c      5 Oct 2004 15:11:55 -0000
@@ -26,6 +26,8 @@
 #include "unit.h"
 
 
+struct player_score player_scores[MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS];
+
 /**************************************************************************
   Allocates, fills and returns a land area claim map.
   Call free_landarea_map(&cmap) to free allocated memory.
@@ -334,7 +336,7 @@
   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,
+                               const struct player *pplayer,
                                int *return_landarea,
                                int *return_settledarea)
 {
@@ -365,32 +367,33 @@
 /**************************************************************************
   Return the civilization score (a numerical value) for the player.
 **************************************************************************/
-int civ_score(struct player *pplayer)
+int civ_score(const struct player *pplayer)
 {
   struct city *pcity;
   int landarea, settledarea;
   static struct claim_map cmap = { NULL, NULL, NULL,NULL };
+  struct player_score *score = player_scores + pplayer->player_no;
 
-  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;
+  score->happy = 0;
+  score->content = 0;
+  score->unhappy = 0;
+  score->angry = 0;
+  score->taxmen = 0;
+  score->scientists = 0;
+  score->elvis = 0;
+  score->wonders = 0;
+  score->techs = 0;
+  score->techout = 0;
+  score->landarea = 0;
+  score->settledarea = 0;
+  score->population = 0;
+  score->cities = 0;
+  score->units = 0;
+  score->pollution = 0;
+  score->bnp = 0;
+  score->mfg = 0;
+  score->literacy = 0;
+  score->spaceship = 0;
 
   if (is_barbarian(pplayer)) {
     if (pplayer->player_no == game.nplayers - 1) {
@@ -402,22 +405,22 @@
   city_list_iterate(pplayer->cities, pcity) {
     int bonus;
 
-    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->specialists[SP_TAXMAN];
-    pplayer->score.scientists += pcity->specialists[SP_SCIENTIST];
-    pplayer->score.elvis += pcity->specialists[SP_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;
+    score->happy += pcity->ppl_happy[4];
+    score->content += pcity->ppl_content[4];
+    score->unhappy += pcity->ppl_unhappy[4];
+    score->angry += pcity->ppl_angry[4];
+    score->taxmen += pcity->specialists[SP_TAXMAN];
+    score->scientists += pcity->specialists[SP_SCIENTIST];
+    score->elvis += pcity->specialists[SP_ELVIS];
+    score->population += city_population(pcity);
+    score->cities++;
+    score->pollution += pcity->pollution;
+    score->techout += pcity->science_total;
+    score->bnp += pcity->trade_prod;
+    score->mfg += pcity->shield_surplus;
 
     bonus = CLIP(0, get_city_bonus(pcity, EFT_SCIENCE_BONUS), 100);
-    pplayer->score.literacy += (city_population(pcity) * bonus) / 100;
+    score->literacy += (city_population(pcity) * bonus) / 100;
   } city_list_iterate_end;
 
   if (pplayer->player_no == 0) {
@@ -425,22 +428,22 @@
     build_landarea_map(&cmap);
   }
   get_player_landarea(&cmap, pplayer, &landarea, &settledarea);
-  pplayer->score.landarea = landarea;
-  pplayer->score.settledarea = settledarea;
+  score->landarea = landarea;
+  score->settledarea = settledarea;
   if (pplayer->player_no == game.nplayers - 1) {
     free_landarea_map(&cmap);
   }
 
   tech_type_iterate(i) {
     if (get_invention(pplayer, i)==TECH_KNOWN) {
-      pplayer->score.techs++;
+      score->techs++;
     }
   } tech_type_iterate_end;
-  pplayer->score.techs += pplayer->future_tech * 5 / 2;
+  score->techs += pplayer->future_tech * 5 / 2;
   
   unit_list_iterate(pplayer->units, punit) {
     if (is_military_unit(punit)) {
-      pplayer->score.units++;
+      score->units++;
     }
   } unit_list_iterate_end
 
@@ -448,21 +451,36 @@
     if (is_wonder(i)
        && (pcity = find_city_by_id(game.global_wonders[i]))
        && player_owns_city(pplayer, pcity)) {
-      pplayer->score.wonders++;
+      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
+    score->spaceship += (int)(100 * pplayer->spaceship.habitation
                                      * pplayer->spaceship.success_rate);
   }
 
-  /* We used to count pplayer->score.happy here too, but this is too easily
+  /* We used to count score->happy here too, but this is too easily
    * manipulated by players at the endyear. */
   return (total_player_citizens(pplayer)
-         + pplayer->score.techs * 2
-         + pplayer->score.wonders * 5
-         + pplayer->score.spaceship);
+         + score->techs * 2
+         + score->wonders * 5
+         + score->spaceship);
+}
+
+/**************************************************************************
+  Return the total number of player citizens.  This is taken from the
+  score value which is periodically recalculated.
+**************************************************************************/
+int total_player_citizens(const struct player *pplayer)
+{
+  return (player_scores[pplayer->player_no].happy
+         + player_scores[pplayer->player_no].content
+         + player_scores[pplayer->player_no].unhappy
+         + player_scores[pplayer->player_no].angry
+         + player_scores[pplayer->player_no].scientists
+         + player_scores[pplayer->player_no].elvis
+         + player_scores[pplayer->player_no].taxmen);
 }
Index: server/score.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/score.h,v
retrieving revision 1.3
diff -u -r1.3 score.h
--- server/score.h      3 Sep 2004 04:22:37 -0000       1.3
+++ server/score.h      5 Oct 2004 15:11:55 -0000
@@ -15,6 +15,32 @@
 
 #include "fc_types.h"
 
-int civ_score(struct player *pplayer);
+struct player_score {
+  int happy;
+  int content;
+  int unhappy;
+  int angry;
+  int taxmen;
+  int scientists;
+  int elvis;
+  int wonders;
+  int techs;
+  int techout;
+  int landarea;
+  int settledarea;
+  int population;      /* in thousand of citizen */
+  int cities;
+  int units;
+  int pollution;
+  int literacy;
+  int bnp;
+  int mfg;
+  int spaceship;
+};
+
+extern struct player_score player_scores[];
+
+int civ_score(const struct player *pplayer);
+int total_player_citizens(const struct player *pplayer);
 
 #endif /* FC__SCORE_H */

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