Complete.Org: Mailing Lists: Archives: freeciv-dev: December 2004:
[Freeciv-Dev] Re: (PR#11354) log(0.0) causes a server crash
Home

[Freeciv-Dev] Re: (PR#11354) log(0.0) causes a server crash

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: ph.bayon@xxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#11354) log(0.0) causes a server crash
From: "Mike Kaufman" <kaufman@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 9 Dec 2004 20:09:25 -0800
Reply-to: bugs@xxxxxxxxxxx

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

here's a superior patch I think.

-mike

? gamelog
Index: ai/aiexplorer.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiexplorer.c,v
retrieving revision 1.5
diff -u -r1.5 aiexplorer.c
--- ai/aiexplorer.c     29 Sep 2004 02:24:18 -0000      1.5
+++ ai/aiexplorer.c     10 Dec 2004 04:06:48 -0000
@@ -248,8 +248,9 @@
   /* Loop prevention */
   struct tile *ptile = punit->tile;
 
-  /* The want of the most desirable tile, given nearby water, cities, etc. */
-  float most_desirable = 0;
+  /* The log of the want of the most desirable tile, 
+   * given nearby water, cities, etc. */
+  float log_desirable = 0.0;
 
   /* The maximum distance we are willing to search. It decreases depending
    * on the want of already discovered tagets.  It is defined as the distance
@@ -258,14 +259,17 @@
   int max_dist = FC_INFINITY;
 
   /* Coordinates of most desirable tile. Initialized to make 
-   * compiler happy. */
+   * compiler happy. Also MC to the best tile. */
   struct tile *best_tile = NULL;
+  int best_MC = 0;
 
   /* Path-finding stuff */
   struct pf_map *map;
   struct pf_parameter parameter;
 
 #define DIST_FACTOR   0.6
+  float logDF = log(DIST_FACTOR);
+  float logBPS = log(BEST_POSSIBLE_SCORE);
 
   pft_fill_unit_parameter(&parameter, punit);
   parameter.get_TB = no_fights_or_unknown;
@@ -283,23 +287,29 @@
     assert(map_is_known(pos.tile, pplayer));
     
     desirable = explorer_desirable(pos.tile, pplayer, punit);
-    if (desirable == 0) { 
+    if (desirable <= 0) { 
       /* Totally non-desirable tile. No need to continue. */
       continue;
     }
-    desirable *= pow(DIST_FACTOR, pos.total_MC);
 
-    if (desirable > most_desirable) {
-      most_desirable = desirable;
+    /* take the natural log */
+    desirable = log(desirable);
+
+    if (desirable + pos.total_MC * logDF > log_desirable + best_MC * logDF) {
+      log_desirable = desirable;
+
       best_tile = pos.tile;
+      best_MC = pos.total_MC;
+
       /* We want to break when
-       *   most_desirable > BEST_POSSIBLE_SCORE * DIST_FACTOR^dist
+       *   most_desirable * DF^MC > BEST_POSSIBLE_SCORE * DF^dist
+       * (where DF is DIST_FACTOR and most_desirable is best tile yet) 
        * which is equivalent to
-       *   most_desirable/BEST_POSSIBLE_SCORE > DIST_FACTOR^dist
-       *   log(most_desirable/BEST_POSSIBLE_SCORE) > dist * log(DIST_FACTOR)
-       *   log(most_desirable/BEST_POSSIBLE_SCORE)/log(DIST_FACTOR) > dist
+       *   most_desirable/BEST_POSSIBLE_SCORE > DF^dist
+       *   log(most_desirable/BEST_POSSIBLE_SCORE) > dist * log(DF)
+       *   log(most_desirable/BEST_POSSIBLE_SCORE)/log(DF) + MC > dist
        */
-      max_dist = log(most_desirable / BEST_POSSIBLE_SCORE) / log(DIST_FACTOR);
+      max_dist = best_MC + (log_desirable - logBPS)/logDF;
     }
 
     if (pos.total_MC > max_dist) {
@@ -309,7 +319,7 @@
   pf_destroy_map(map);
 
   /* Go to the best tile found. */
-  if (most_desirable > 0) {
+  if (best_tile != NULL) {
     /* TODO: read the path off the map we made.  Then we can make a path 
      * which goes beside the unknown, with a good EC callback... */
     if (!ai_unit_goto(punit, best_tile)) {

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