Complete.Org: Mailing Lists: Archives: freeciv-ai: November 2004:
[freeciv-ai] Re: (PR#11009) AI Hunts Own Units
Home

[freeciv-ai] Re: (PR#11009) AI Hunts Own Units

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [freeciv-ai] Re: (PR#11009) AI Hunts Own Units
From: "Benedict Adamson" <badamson@xxxxxxxxxxxxx>
Date: Thu, 18 Nov 2004 15:17:40 -0800
Reply-to: rt@xxxxxxxxxxx

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

Gregory Berkolaiko wrote:
...
> the fix is not much better, since you just shift
> the band aid to a different place.  We have to know which one of the
> conditions is actually malfunctioning.
...
OK, it seems you won't let me wriggle out of this one :-). A proper try 
this time.

Self loathing leads to self harm: some additional assertions revealled 
the culprit to be the comparison
    ai->diplomacy.acceptable_reputation > aplayer->reputation
That is, if the AI is a scum bag, he thinks he is a danger to himself.

Attached is a patch, which fixes the problem, provides comments to 
document the peculiarities, and has assertions for checking the 
invariants that the is_player_dangerous function depends on, near where 
those invariants might be broken.

diff -ru -Xfreeciv.PR11009/diff_ignore vendor.freeciv.beta/ai/advdiplomacy.c 
freeciv.PR11009/ai/advdiplomacy.c
--- vendor.freeciv.beta/ai/advdiplomacy.c       2004-11-05 22:58:49.000000000 
+0000
+++ freeciv.PR11009/ai/advdiplomacy.c   2004-11-18 23:18:36.000000000 +0000
@@ -185,6 +185,8 @@
   int giver;
   struct ai_dip_intel *adip = &ai->diplomacy.player_intel[aplayer->player_no];
 
+  assert(pplayer != aplayer);
+
   diplomacy_verbose = verbose;
 
   giver = pclause->from->player_no;
@@ -557,6 +559,8 @@
   bool gift = TRUE;
   struct ai_data *ai = ai_data_get(pplayer);
 
+  assert(pplayer != aplayer);
+
   /* Evaluate clauses */
   clause_list_iterate(ptreaty->clauses, pclause) {
     int balance = ai_goldequiv_clause(pplayer, aplayer, pclause, ai, TRUE);
@@ -698,6 +702,7 @@
   int war_desire[MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS];
   int best_desire = 0;
   struct player *target = NULL;
+  assert(!pplayer->diplstates[pplayer->player_no].has_reason_to_cancel);
 
   memset(war_desire, 0, sizeof(war_desire));
 
@@ -873,6 +878,8 @@
       ai->diplomacy.player_intel[aplayer->player_no].ally_patience = 0;
     } players_iterate_end;
   }
+
+  assert(ai->diplomacy.target != pplayer); /* no self loathing */
 }
 
 /********************************************************************** 
@@ -916,6 +923,7 @@
 static void ai_go_to_war(struct player *pplayer, struct ai_data *ai,
                          struct player *target)
 {
+  assert(pplayer != target);
   if (gives_shared_vision(pplayer, target)) {
     remove_shared_vision(pplayer, target);
   }
@@ -957,6 +965,7 @@
     if (ai->diplomacy.acceptable_reputation > aplayer->reputation
         && pplayer->ai.love[aplayer->player_no] < 0
         && pplayer->diplstates[aplayer->player_no].has_reason_to_cancel >= 2) {
+      assert(pplayer != aplayer);
       PLAYER_LOG(LOG_DIPL2, pplayer, ai, "Declaring war on %s in revenge",
                  target->name);
       notify(target, _("*%s (AI)* I will NOT accept such behaviour! This "
diff -ru -Xfreeciv.PR11009/diff_ignore vendor.freeciv.beta/ai/advmilitary.c 
freeciv.PR11009/ai/advmilitary.c
--- vendor.freeciv.beta/ai/advmilitary.c        2004-11-05 22:58:49.000000000 
+0000
+++ freeciv.PR11009/ai/advmilitary.c    2004-11-18 23:18:36.000000000 +0000
@@ -465,6 +465,9 @@
     if (!is_player_dangerous(city_owner(pcity), aplayer)) {
       continue;
     }
+    assert(city_owner(pcity) != aplayer);
+    /* Note that we still consider the units of players we are not (yet)
+     * at war with. */
 
     /* Look for enemy units */
     unit_list_iterate(aplayer->units, punit) {
@@ -472,6 +475,9 @@
       int move_rate = unit_move_rate(punit);
       unsigned int vulnerability = assess_danger_unit(pcity, punit);
       int dist = assess_distance(pcity, punit, move_rate);
+      /* Although enemy units will not be in our cities,
+       * we might stll consider allies to be dangerous,
+       * so dist can be 0. */
       bool igwall = unit_really_ignores_citywalls(punit);
 
       if (unit_flag(punit, F_PARATROOPERS)) {
diff -ru -Xfreeciv.PR11009/diff_ignore vendor.freeciv.beta/ai/aidata.c 
freeciv.PR11009/ai/aidata.c
--- vendor.freeciv.beta/ai/aidata.c     2004-11-05 22:58:49.000000000 +0000
+++ freeciv.PR11009/ai/aidata.c 2004-11-18 23:18:36.000000000 +0000
@@ -400,6 +400,8 @@
       *punit->ai.cur_pos = punit->tile;
     } unit_list_iterate_end;
   } players_iterate_end;
+  
+  assert(!ai->diplomacy.player_intel[pplayer->player_no].is_allied_with_enemy);
 }
 
 /**************************************************************************
diff -ru -Xfreeciv.PR11009/diff_ignore vendor.freeciv.beta/ai/aihunt.c 
freeciv.PR11009/ai/aihunt.c
--- vendor.freeciv.beta/ai/aihunt.c     2004-10-09 21:01:42.000000000 +0100
+++ freeciv.PR11009/ai/aihunt.c 2004-11-18 23:18:37.000000000 +0000
@@ -269,6 +269,8 @@
     if (!aplayer->is_alive || !is_player_dangerous(pplayer, aplayer)) {
       continue;
     }
+    assert(aplayer != pplayer); /* never hunt self */
+    /* Note that we need not (yet) be at war with aplayer */
     unit_list_iterate(aplayer->units, target) {
       struct tile *ptile = target->tile;
       int dist1, dist2, stackthreat = 0, stackcost = 0;
@@ -328,6 +330,8 @@
                unit_owner(defender)->name, unit_type(defender)->name, 
                defender->tile, defender->id, stackthreat, dist1, 
                dist2);
+      /* TO DO: probably ought to WAG down targets of players we are not (yet)
+       * at war with */
       /* Ok, now we FINALLY have a candidate */
       if (stackthreat > best_val) {
         best_val = stackthreat;
diff -ru -Xfreeciv.PR11009/diff_ignore vendor.freeciv.beta/ai/aitools.c 
freeciv.PR11009/ai/aitools.c
--- vendor.freeciv.beta/ai/aitools.c    2004-11-05 22:58:49.000000000 +0000
+++ freeciv.PR11009/ai/aitools.c        2004-11-18 23:18:36.000000000 +0000
@@ -87,11 +87,15 @@
   struct ai_data *ai = ai_data_get(pplayer);
   struct ai_dip_intel *adip 
     = &ai->diplomacy.player_intel[aplayer->player_no];
+  const bool trustworthy = ((pplayer == aplayer)
+                           || (ai->diplomacy.acceptable_reputation
+                               <= aplayer->reputation));
+  assert(!(!trustworthy && pplayer == aplayer)); /* always trust self */
 
   return (pplayers_at_war(pplayer, aplayer)
           || ai->diplomacy.target == aplayer
           || pplayer->diplstates[aplayer->player_no].has_reason_to_cancel != 0
-          || ai->diplomacy.acceptable_reputation > aplayer->reputation
+         || !trustworthy
           || adip->is_allied_with_enemy);
 }
 
diff -ru -Xfreeciv.PR11009/diff_ignore vendor.freeciv.beta/diff_ignore 
freeciv.PR11009/diff_ignore
--- vendor.freeciv.beta/diff_ignore     2004-10-22 22:48:23.000000000 +0100
+++ freeciv.PR11009/diff_ignore 2004-11-18 23:18:37.000000000 +0000
@@ -17,6 +17,7 @@
 *~
 .#*
 .deps
+.svn
 CVS
 Freeciv.h
 Makefile
diff -ru -Xfreeciv.PR11009/diff_ignore vendor.freeciv.beta/server/diplomats.c 
freeciv.PR11009/server/diplomats.c
--- vendor.freeciv.beta/server/diplomats.c      2004-10-22 22:48:07.000000000 
+0100
+++ freeciv.PR11009/server/diplomats.c  2004-11-18 23:18:17.000000000 +0000
@@ -1323,6 +1323,8 @@
     die("No victim in call to maybe_cause_incident()");
   }
 
+  assert(offender != victim_player);
+
   if (!pplayers_at_war(offender, victim_player) &&
       (myrand(GAME_MAX_REPUTATION) - offender->reputation >
        GAME_MAX_REPUTATION/2 - victim_player->reputation)) {
diff -ru -Xfreeciv.PR11009/diff_ignore vendor.freeciv.beta/server/plrhand.c 
freeciv.PR11009/server/plrhand.c
--- vendor.freeciv.beta/server/plrhand.c        2004-11-05 22:58:34.000000000 
+0000
+++ freeciv.PR11009/server/plrhand.c    2004-11-18 23:18:17.000000000 +0000
@@ -1243,6 +1243,7 @@
         /* If an ally declares war on another ally, break off your alliance
          * to the aggressor. This prevents in-alliance wars, which are not
          * permitted. */
+       assert(other != pplayer);
         notify_player_ex(other, NULL, E_TREATY_BROKEN,
                          _("Game: %s has attacked your ally %s! "
                            "You cancel your alliance to the aggressor."),

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