Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2005:
[Freeciv-Dev] (PR#11610) Two fairness issues with techlevel>0 and techco
Home

[Freeciv-Dev] (PR#11610) Two fairness issues with techlevel>0 and techco

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: saywhat@xxxxxxxxxxxx
Subject: [Freeciv-Dev] (PR#11610) Two fairness issues with techlevel>0 and techcoststyle=1
From: "Mateusz Stefek" <mstefek@xxxxxxxxx>
Date: Mon, 19 Sep 2005 02:01:17 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=11610 >

This is a version for S2_0.

The bug with techlevel > 0 is probably the reason of many cases when
team research is desynchronized.
--
mateusz
Index: server/barbarian.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/barbarian.c,v
retrieving revision 1.79.2.4
diff -u -r1.79.2.4 barbarian.c
--- server/barbarian.c  23 Aug 2005 08:05:37 -0000      1.79.2.4
+++ server/barbarian.c  19 Sep 2005 08:55:56 -0000
@@ -141,7 +141,8 @@
     barbarians->ai.barbarian_type = SEA_BARBARIAN;
   }
   set_ai_level_directer(barbarians, game.skill_level);
-  init_tech(barbarians, game.tech);
+  init_tech(barbarians);
+  give_initial_techs(barbarians);
 
   /* Ensure that we are at war with everyone else */
   players_iterate(pplayer) {
Index: server/plrhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.c,v
retrieving revision 1.330.2.38
diff -u -r1.330.2.38 plrhand.c
--- server/plrhand.c    13 Sep 2005 08:43:33 -0000      1.330.2.38
+++ server/plrhand.c    19 Sep 2005 08:56:14 -0000
@@ -64,6 +64,7 @@
 static Nation_Type_id pick_available_nation(Nation_Type_id *choices);
 static void tech_researched(struct player* plr);
 static bool choose_goal_tech(struct player *plr);
+static Tech_Type_id pick_random_tech(struct player *plr);
 static enum plr_info_level player_info_level(struct player *plr,
                                             struct player *receiver);
 
@@ -482,9 +483,10 @@
     /* Avoid unnecessary recursion. */
     return;
   }
+
   players_iterate(aplayer) {
     if (plr != aplayer
-        && plr->diplstates[aplayer->player_no].type == DS_TEAM
+        && players_on_same_team(aplayer, plr)
         && aplayer->is_alive
         && get_invention(aplayer, tech_found) != TECH_KNOWN) {
       if (tech_exists(plr->research.researching)) {
@@ -605,12 +607,42 @@
 }
 
 /**************************************************************************
+  Returns random researchable tech or A_FUTURE.
+  No side effects
+**************************************************************************/
+static Tech_Type_id pick_random_tech(struct player *plr)
+{
+  int researchable, chosen;
+  
+  researchable = 0;
+  tech_type_iterate(i) {
+    if (get_invention(plr, i) == TECH_REACHABLE) {
+      researchable++;
+    }
+  } tech_type_iterate_end;
+  
+  if (researchable == 0) {
+    return A_FUTURE;
+  }
+  chosen = myrand(researchable) + 1;
+  
+  tech_type_iterate(i) {
+    if (get_invention(plr, i) == TECH_REACHABLE) {
+      chosen--;
+      if (chosen == 0) {
+        return i;
+      }
+    }
+  } tech_type_iterate_end;
+  assert(0);
+  return A_NONE;
+}
+
+/**************************************************************************
 ...
 **************************************************************************/
 void choose_random_tech(struct player *plr)
 {
-  int chosen, researchable = 0;
-  
   if (plr->research.researching != A_UNSET) {
     freelog(LOG_ERROR, "Error: choose_random_tech should only be called "
                        "when research target is A_UNSET. Please report this "
@@ -618,26 +650,8 @@
   }
   
   do {
-    tech_type_iterate(i) {
-      if (get_invention(plr, i) == TECH_REACHABLE) {
-        researchable++;
-      }
-    } tech_type_iterate_end;
-    if (researchable == 0) {
-      choose_tech(plr, A_FUTURE);
-      return;
-    }
-    chosen = myrand(researchable) + 1;
-  
-    tech_type_iterate(i) {
-      if (get_invention(plr, i) == TECH_REACHABLE) {
-        chosen--;
-        if (chosen == 0) {
-         choose_tech(plr, i);
-         break;
-        }
-      }
-    } tech_type_iterate_end;
+    Tech_Type_id tech = pick_random_tech(plr);
+    choose_tech(plr, tech);
   } while (plr->research.researching == A_UNSET);
 }
 
@@ -684,13 +698,10 @@
 }
 
 /**************************************************************************
-...
+  Initializes tech data for the player
 **************************************************************************/
-void init_tech(struct player *plr, int tech)
+void init_tech(struct player *plr)
 {
-  int i;
-  struct nation_type *nation = get_nation_by_plr(plr);
-
   tech_type_iterate(i) {
     set_invention(plr, i, TECH_UNKNOWN);
   } tech_type_iterate_end;
@@ -698,6 +709,20 @@
 
   plr->research.techs_researched = 1;
 
+  /* Mark the reachable techs */
+  update_research(plr);
+  if (!choose_goal_tech(plr)) {
+    choose_random_tech(plr);
+  }
+}
+  
+/**************************************************************************
+  Gives initial techs to the player
+**************************************************************************/
+void give_initial_techs(struct player* plr)
+{
+  struct nation_type *nation = get_nation_by_plr(plr);
+  int i;
   /*
    * Give game wide initial techs
    */
@@ -705,7 +730,7 @@
     if (game.rgame.global_init_techs[i] == A_LAST) {
       break;
     }
-    set_invention(plr, game.rgame.global_init_techs[i], TECH_KNOWN);
+    found_new_tech(plr, game.rgame.global_init_techs[i], FALSE, TRUE, A_NONE);
   }
 
   /*
@@ -715,20 +740,21 @@
     if (nation->init_techs[i] == A_LAST) {
       break;
     }
-    set_invention(plr, nation->init_techs[i], TECH_KNOWN);
-  }
-
-  for (i = 0; i < tech; i++) {
-    update_research(plr);
-    choose_random_tech(plr); /* could be choose_goal_tech -- Syela */
-    set_invention(plr, plr->research.researching, TECH_KNOWN);
+    found_new_tech(plr, nation->init_techs[i], FALSE, TRUE, A_NONE);
   }
+}
 
-  /* Mark the reachable techs */
-  update_research(plr);
-  if (!choose_goal_tech(plr)) {
-    choose_random_tech(plr);
-  }
+/**************************************************************************
+  Gives a player random tech, which he hasn't researched yet.
+  Returns the tech. Does not apply free cost.
+**************************************************************************/
+Tech_Type_id give_random_initial_tech(struct player* pplayer)
+{
+  Tech_Type_id tech;
+  
+  tech = pick_random_tech(pplayer);
+  found_new_tech(pplayer, tech, FALSE, TRUE, A_NONE);
+  return TRUE;
 }
 
 /**************************************************************************
Index: server/plrhand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.h,v
retrieving revision 1.69.2.1
diff -u -r1.69.2.1 plrhand.h
--- server/plrhand.h    6 Jul 2005 08:17:33 -0000       1.69.2.1
+++ server/plrhand.h    19 Sep 2005 08:56:14 -0000
@@ -66,11 +66,13 @@
                     bool saving_bulbs, int next_tech);
 void found_new_future_tech(struct player *pplayer);
 void update_tech(struct player *plr, int bulbs);
-void init_tech(struct player *plr, int tech);
+void init_tech(struct player *plr);
 void choose_random_tech(struct player *plr);
 void choose_tech(struct player *plr, int tech);
 void choose_tech_goal(struct player *plr, int tech);
 void get_a_tech(struct player *pplayer, struct player *target);
+void give_initial_techs(struct player* plr);
+Tech_Type_id give_random_initial_tech(struct player* pplayer);
 
 void send_player_turn_notifications(struct conn_list *dest);
 
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.197.2.19
diff -u -r1.197.2.19 savegame.c
--- server/savegame.c   23 Aug 2005 08:30:23 -0000      1.197.2.19
+++ server/savegame.c   19 Sep 2005 08:56:34 -0000
@@ -1662,7 +1662,8 @@
   }
 
   /* Add techs from game and nation, but ignore game.tech. */
-  init_tech(plr, 0);
+  init_tech(plr);
+  give_initial_techs(plr);
 
   /* not all players have teams */
   if (section_file_lookup(file, "player%d.team", plrno)) {
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.201.2.12
diff -u -r1.201.2.12 srv_main.c
--- server/srv_main.c   15 Aug 2005 03:33:28 -0000      1.201.2.12
+++ server/srv_main.c   19 Sep 2005 08:56:34 -0000
@@ -1819,10 +1819,33 @@
 
     players_iterate(pplayer) {
       player_map_allocate(pplayer);
-      init_tech(pplayer, game.tech);
+      init_tech(pplayer);
       player_limit_to_government_rates(pplayer);
       pplayer->economic.gold = game.gold;
     } players_iterate_end;
+    
+    players_iterate(pplayer) {
+      int i;
+      bool free_techs_already_given = FALSE;
+
+      give_initial_techs(pplayer);
+    
+      players_iterate(eplayer) {
+        if (players_on_same_team(eplayer, pplayer) &&
+            eplayer->player_no < pplayer->player_no) {
+         free_techs_already_given = TRUE;
+         break;
+        }
+      } players_iterate_end;
+      
+      if (free_techs_already_given) {
+        break;
+      }
+      for (i = 0; i < game.tech; i++) {
+        give_random_initial_tech(pplayer);
+      }
+    } players_iterate_end;
+    
     if(game.is_new_game) {
       /* If we're starting a new game, reset the max_players to be the
        * number of players currently in the game.  But when loading a game
Index: server/stdinhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/stdinhand.c,v
retrieving revision 1.354.2.40
diff -u -r1.354.2.40 stdinhand.c
--- server/stdinhand.c  1 Sep 2005 19:52:57 -0000       1.354.2.40
+++ server/stdinhand.c  19 Sep 2005 08:56:34 -0000
@@ -2709,7 +2709,8 @@
 
       if ((server_state == RUN_GAME_STATE) || !game.is_new_game) {
         pplayer->nation = OBSERVER_NATION;
-        init_tech(pplayer, 0);
+        init_tech(pplayer);
+       give_initial_techs(pplayer);
         map_know_and_see_all(pplayer);
       }
 

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