[Freeciv-Dev] (PR#10359) Saving changes game state
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://rt.freeciv.org/Ticket/Display.html?id=10359 >
Here is a patch for the problem.
- civ_score is split into calc_civ_score and get_civ_score.
- calc_civ_score is called at the beginning and end of every turn. This
is actually a bit complicated. We need to make sure it's called often
enough that no possible timing of saving+reloading will cause it to be
different. That is, if you save and reload, it must be the same as if
you had done nothing. Yet since this data isn't in the savegame it must
be recalculated on load. I think it's not possible to have this work
correctly in all cases. A save may happen mid-turn, in which case the
score is erronously recalculated but _hopefully_ causes no changes in
state since it's not used until the end of the turn. The better
solution would be to either store the data in the savegame (calculating
it just once a turn) or recalculating it every time it is used (i.e.,
getting rid of the pplayer->score structure).
- get_civ_score is called in a few places. However it is now a "pure"
function (no side effects).
- total_player_citizens is moved into the server. This is just a
cleanup since it is server-only anyway.
jason
? diff.diff
? newtiles
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 15 Oct 2004 18:32:25 -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 15 Oct 2004 18:32:25 -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.153
diff -u -r1.153 game.h
--- common/game.h 13 Oct 2004 15:47:42 -0000 1.153
+++ common/game.h 15 Oct 2004 18:32:25 -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: server/gamelog.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gamelog.c,v
retrieving revision 1.38
diff -u -r1.38 gamelog.c
--- server/gamelog.c 29 Sep 2004 02:24:23 -0000 1.38
+++ server/gamelog.c 15 Oct 2004 18:32:26 -0000
@@ -147,7 +147,7 @@
players_iterate(pplayer) {
if (!is_barbarian(pplayer)) {
- rank[count].value = civ_score(pplayer);
+ rank[count].value = get_civ_score(pplayer);
rank[count].idx = pplayer->player_no;
size[count].value = total_player_citizens(pplayer);
size[count].idx = pplayer->player_no;
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 15 Oct 2004 18:32:26 -0000
@@ -1045,10 +1045,6 @@
static enum historian_type report = HISTORIAN_FIRST;
static int time_to_report=20;
- players_iterate(pplayer) {
- (void) civ_score(pplayer);
- } players_iterate_end;
-
if (game.scorelog) {
log_civ_score();
}
@@ -1084,7 +1080,7 @@
players_iterate(pplayer) {
if (!is_barbarian(pplayer)) {
- size[j].value = civ_score(pplayer);
+ size[j].value = get_civ_score(pplayer);
size[j].player = pplayer;
j++;
}
@@ -1118,7 +1114,7 @@
players_iterate(pplayer) {
if (!is_barbarian(pplayer)) {
- size[j].value = civ_score(pplayer);
+ size[j].value = get_civ_score(pplayer);
size[j].player = pplayer;
j++;
}
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 15 Oct 2004 18:32:26 -0000
@@ -363,9 +363,9 @@
}
/**************************************************************************
- Return the civilization score (a numerical value) for the player.
+ Calculates the civilization score for the player.
**************************************************************************/
-int civ_score(struct player *pplayer)
+void calc_civ_score(struct player *pplayer)
{
struct city *pcity;
int landarea, settledarea;
@@ -396,7 +396,7 @@
if (pplayer->player_no == game.nplayers - 1) {
free_landarea_map(&cmap);
}
- return 0;
+ return;
}
city_list_iterate(pplayer->cities, pcity) {
@@ -458,7 +458,13 @@
pplayer->score.spaceship += (int)(100 * pplayer->spaceship.habitation
* pplayer->spaceship.success_rate);
}
+}
+/**************************************************************************
+ Return the civilization score (a numerical value) for the player.
+**************************************************************************/
+int get_civ_score(const struct player *pplayer)
+{
/* We used to count pplayer->score.happy here too, but this is too easily
* manipulated by players at the endyear. */
return (total_player_citizens(pplayer)
@@ -466,3 +472,17 @@
+ pplayer->score.wonders * 5
+ pplayer->score.spaceship);
}
+
+/**************************************************************************
+ Return the total number of citizens in the player's nation.
+**************************************************************************/
+int total_player_citizens(const 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);
+}
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 15 Oct 2004 18:32:26 -0000
@@ -15,6 +15,9 @@
#include "fc_types.h"
-int civ_score(struct player *pplayer);
+void calc_civ_score(struct player *pplayer);
+
+int get_civ_score(const struct player *pplayer);
+int total_player_citizens(const struct player *pplayer);
#endif /* FC__SCORE_H */
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.203
diff -u -r1.203 srv_main.c
--- server/srv_main.c 15 Oct 2004 09:39:06 -0000 1.203
+++ server/srv_main.c 15 Oct 2004 18:32:26 -0000
@@ -478,6 +478,14 @@
{
freelog(LOG_DEBUG, "Begin turn");
+ if (is_new_turn) {
+ /* We build scores at the beginning and end of every turn. We have to
+ * build them at the beginning so that the AI can use the data. */
+ players_iterate(pplayer) {
+ calc_civ_score(pplayer);
+ } players_iterate_end;
+ }
+
/* See if the value of fog of war has changed */
if (is_new_turn && game.fogofwar != game.fogofwar_old) {
if (game.fogofwar) {
@@ -613,6 +621,12 @@
{
freelog(LOG_DEBUG, "Endturn");
+ /* We build scores at the beginning and end of every turn. We have to
+ * build them at the end so that the history report can be built. */
+ players_iterate(pplayer) {
+ calc_civ_score(pplayer);
+ } players_iterate_end;
+
freelog(LOG_DEBUG, "Season of native unrests");
summon_barbarians(); /* wild guess really, no idea where to put it, but
I want to give them chance to move their units */
@@ -1820,7 +1834,6 @@
if (!game.is_new_game) {
players_iterate(pplayer) {
- civ_score(pplayer); /* if we don't, the AI gets really confused */
if (pplayer->ai.control) {
set_ai_level_direct(pplayer, pplayer->ai.skill_level);
}
|
|