I assume you meant to imply this too, but I just wanted to make it explicit that as a unit that's at 8 HP is going to be easier to bring down to that critical 0 HP than one that's at full health, it should weigh how close the unit is to death even if it can't take it down in that attack or even that turn. Although then you'd have to give it some parameters for avoiding excessive overkill if it can.
Considering PGF experiences, the following algorithm for city's attack (and any ranged unit defending a city for that matter) should be more than sufficient:
Priority +6: check 2-hex radius for full-health melee enemy units that have an adjacent friendly unit or city. If exists then attack, but only if projected damage more than 0.
Priority +5: check 2-hex radius for units with 2 or less HP. If exists then attack, but only if projected damage more than 0.
Priority +4: check 2-hex radius for units with 4 or less HP. If exists then attack, but only if projected damage more than 0.
Priority +3: check if cavalry unit protecting city. IF so, attack pikeman/spearman unit, but only if projected damage more than 0.
Priority +2: check 2-hex radius for melee unit. If exists, attack the one closest to city.
Priority +1: check 2-hex radius for any melee unit. If exists, attack.
Priority +0: attack any unit within 2-hex radius.
Extend it to 3-hex radius if:
a) logistics or range promotion
b) artillery or rocket artillery
This will have the following effects:
- ranged and city finishing off units
- ranged and city weakening melee units enough for a melee counterattack
- killing off units that can actually capture the city first
***
Similar to the above, city-defender melee units could get similar algorithms:
Priority +4: If adjacent ranged enemy unit on protective terrain AND less than 2 enemy units adjacent to target - attack.
Priority +3: If adjacent melee enemy unit with less than 6 HP on protective terrain - attack.
Priority +2: If adjacent ranged enemy unit on flatland AND no other enemy units in 4-hex radius - attack.
Priority +1: If adjacent melee unit on flatland AND no other enemy units in 4-hex radius - attack.
Priority +0: stay put.
and for cavalry as well:
Priority +4: If adjacent ranged unit on protective terrain AND less than 2 enemy units adjacent to target - attack.
Priority +3: If adjacent ranged unit on flatland - attack and retreat to previous position.
Priority +2: IF adjacent melee unit with less than 8 HP NOT a spearman/pikeman on flatland attack and retreat to previous position.
Priority +1: IF adjacent melee unit with less than 8 HP NOT a spearman/pikeman on rough terrain AND no enemy units in 4-hex radius - attack.
Priority +0: Stay put.
With additional IF-ENEMY-JAPANESE-THEN priority lists.