Complete.Org: Mailing Lists: Archives: freeciv-dev: March 2002:
[Freeciv-Dev] [Bug][RFC] Stupid attack behaviour by AI (PR#1340)
Home

[Freeciv-Dev] [Bug][RFC] Stupid attack behaviour by AI (PR#1340)

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Cc: bugs@xxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] [Bug][RFC] Stupid attack behaviour by AI (PR#1340)
From: Gregory Berkolaiko <Gregory.Berkolaiko@xxxxxxxxxxxx>
Date: Sat, 23 Mar 2002 12:04:49 -0800 (PST)

Raahul Kumar drew my attention to this phenomenon: if you park your, say, 
phalanx on a wee mountain outside an AI city then from time to time the 
city's gates will burst open and AI will attack you with few phalanxes or 
similarly inefficient units.  Seemingly without any real desire to kill you...

For a long time we were inclined to believe that it's server/autoattack.c 
fault.  Indeed server/autoattack.c selects it's targets on a very dodgy 
basis.  But the problem is elsewhere.

First discovery: AI autoattack is (almost) never activated:
==================================================
193 static void auto_attack_city(struct player *pplayer, struct city *pcity)
194 {
195   unit_list_iterate(map_get_tile(pcity->x, pcity->y)->units, punit) {
196     if (punit->ai.control
197         && punit->activity == ACTIVITY_IDLE
198         && is_military_unit(punit)) {
199       auto_attack_with_unit(pplayer, pcity, punit);
200     }
201   }
202   unit_list_iterate_end;
203 }
==================================================
because by the time the control is passed to autoattack, all AI units are 
fortifying (i.e. not IDLE)

Second discovery: The culprit is ai_military_vindvictim (ai/aiunit.c).
(It's not fault of Petr, who only cleaned it up and acually facilitated my 
discovery).  The problem lies in the lines:
==================================================
910         int vuln = unit_vulnerability(punit, pdef);
911         int attack = reinforcements_value(punit, pdef->x, pdef->y) 
                         + unit_belligerence_primitive(punit);
912         int benefit = unit_type(pdef)->build_cost;
913         int loss = unit_type(punit)->build_cost;
==================================================
because reinforcements are counted in the attack but _not_ counted in the 
loss.

So what happens is:
AI accumulates quite a few defensive units.  Then it thinks that it has 
real chance of defeating you with all those defensive units (which might 
well be right).  What is not taken into account is the cost at which this 
victory will come: it thinks that only the first attacking unit will die 
in the worst-case scenario.

How can we fix that:
The easiest solution is to add currently UNUSED 
int reinforcements_cost(struct unit *punit, int x, int y) 
to "loss".  This will still encourage expensive attacks: AI will think 
that 
--if after all N units attack the enemy still survives, it will lose 
"loss" shields (which is right)
--if after all N units attack the enemy at last dies, it will lose 0 
shields (which is wrong: N-1 units will die too).

However, making more mathematically exact computation is quite hard and, I 
am afraid, will discourage AI from ever attacking enemy cities.  Unless 
city_attack_bonus which is now represented by magic number 40 (or 
misrepresented by unit_value(get_role_unit(F_CITIES, 0)) ) is bumped up 
significantly.

G.




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