Complete.Org: Mailing Lists: Archives: freeciv-ai: May 2003:
[freeciv-ai] Re: (PR#4026) Advanced rampage.

[freeciv-ai] Re: (PR#4026) Advanced rampage.

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients:;
Subject: [freeciv-ai] Re: (PR#4026) Advanced rampage.
From: "Per I. Mathisen" <per@xxxxxxxxxxx>
Date: Sat, 10 May 2003 11:22:32 -0700
Reply-to: rt@xxxxxxxxxxxxxx

On Tue, 6 May 2003, Gregory Berkolaiko wrote:
> Here is an up-to-date version of rampage.

+      /* If the victim is in the city, we increase the benefit and correct
+       * it with our health because there may be more units in the city
+       * stacked, and we won't destroy them all at once, so in the next
+       * turn they may attack us. So we shouldn't send already injured
+       * units to useless suicide. */
+      if (map_get_city(x, y)) {
+        /* A WAG for the city value */
+        benefit += unit_value(get_role_unit(F_CITIES, 0));
+        benefit = (benefit * punit->hp) / unit_type(punit)->hp;
+      }

I don't like this. First, those who have commented that we should also
check for fortress are right. Just because fortress is not commonly used
in default rules, does not give you a license to ignore it. (If it is THAT
useless, it should rather be removed from the game.)

Second, the benefit of taking a city is ridiculously small. The loss to
the other player might be enormous. Our benefit of taking the city with
punit depends on punit's ability to defend the city from attack. Taking a
city with a Howitzer when an enemy Howitzer stands outside may not be a
good idea, but checking this might be ardous. If we did assess_danger()
also for enemy cities, we would know how big danger there was of a retake
of this city, though. Also, if the enemy cannot steal any techs from us,
defending from a position inside the city might well be much better than
not. Finally, we may want to reduce want of taking size 1 cities that do
not have city walls, since they will be destroyed.

I suggest we make a function for this right away, even if is presently not
well populated with checks. Perhaps
        int ai_city_attack_want(punit, pcity)
which for now always returns
        unit_value(get_role_unit(F_CITIES, 0)) * pcity->size
        * unit_list_size(&pcity->units_supported)
but is populated with TODO comments.

+      /* If we have non-zero attack rating... */
+      if (att_rating > 0 && is_my_turn(punit, pdef)) {
+        /* No need to amortize! We're doing it in one-turn horizon. */
+        return kill_desire(benefit, attack, loss, vuln, 1);
+      }
+    }

What does this mean?

+  Find and kill anything reachable within this turn and worth more than
+  the relevant of the given thresholds until we have run out of juicy
+  targets or movement.  The first threshold is for attacking which will
+  leave us where we stand (attacking adjacent units), the second is for
+  attacking distant (but within reach) targets.
+  For example, if unit is a bodyguard on duty, it should call
+    ai_military_rampage(punit, 100, RAMPAGE_ONLY_FREE_CITY)
+  meaning "we will move _only_ to pick up a free city but we are happy to
+  attack adjacent squares as long as they are worthy of it".

Modify thres_adj by occupychance. For example:
  assert(thres_adj <= thres_move);
  thres_adj += ((tresh_move - tresh_adj) * game.occupychance / 100);

This teaches the AI about the dangers inherent in occupychance. Not that
anyone uses it, but as above, if it is in the rules, we should support it.

+  Sea attack is the same as overlap (consider bombardment) but we don't
+  want to pass through enemy tiles.
+static int sea_attack_move(int x, int y, enum direction8 dir,
+                           int x1, int y1, struct pf_parameter *param)
+  struct tile *src_tile = map_get_tile(x, y);
+  if (src_tile->terrain == T_OCEAN) {

Use is_ocean(src_tile->terrain), applies everywhere.

+    if (is_non_allied_unit_tile(src_tile, param->owner)) {
+      return PF_IMPOSSIBLE_MC;
+    }

You need to check F_NO_LAND_ATTACK here. Which means that you have to pass
another argument, I guess.

(Don't we have code in common/ that does this kind of thing already?)

+    /* Sea-to-Land.  TODO: Marines support */

Please don't leave such important TODOs unimplemented.

+    /* Land-to-Land */
+    if (is_non_allied_unit_tile(src_tile, param->owner)) {
+      /* Cannot pass through defended tiles */
+      move_cost = PF_IMPOSSIBLE_MC;
+    } else if(is_non_allied_unit_tile(tgt_tile, param->owner)) {
+      /* TODO: Intelligent checking */
+      /* Attack! */

What would 'intelligent checking' mean here?

  - Per

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