fire-eggs / CivOne

An open source implementation of Sid Meier's Civilization 1 using C# and .NET.
Creative Commons Zero v1.0 Universal
21 stars 4 forks source link

Implement how AI buys things in its cities #165

Open axx0 opened 3 years ago

axx0 commented 3 years ago

(from https://forums.civfanatics.com/threads/how-ai-buys-things-in-its-cities-its-pretty-buggy-btw.667946/)

What rules for AI to buy things in its cities? First thing to say: AI don't need to buy things 'as a whole', as the human player should. Second: rate to buy always 1 shield = 2 gold coins for AI. For human, it's actually 1 shield = 4 coins for space ship parts and wonders and more complex formula for units. Also in most cases AI cannot buy things when city shield storage is 0 (for human player in this case price is doubled). But in some cases AI doesn't care about 0 shield storage, and it's still 1 shield = 2 gold coins (when for human it can be even 1 shield = 8 gold coins for SS parts and wonders!)

These rules are used after the game checks if city finished production of something on this turn, so actually AI cannot buy production and finish it immediately at the same turn (even if it looks like it can - when you attack a city once a turn).

First, set ADD_SHIELDS variable to 0. This is how much shields AI will add to the shield storage of the city at the end.

1st rule: speed up unit production, if unit has same role as the continent policy
if continent policy is "attack", "defend", or "transport"
and the city is not producing settlers
and the city is producing a unit
and role of this unit is same as the continent policy
then ADD_SHIELDS = ADD_SHIELDS + 1/64 of civ treasury

2nd rule: speed up SS production in space race with the player
if the human player is 'SS enabled' (built some SS part(s) and it's possible to see its space ship in "Spaceships" game menu) *
and city is producing space ship part (structure, component or module)
then ADD SHIELDS = 1/128 of civ treasury

*for barbarians, 'SS enabled' flag used as 'end of history' flag, so if you play as barbarians, AI will use this rule after game ends

3rd rule: buy city improvements/wonders if city in disorder
if city in disorder,
and city is producing city improvement, SS part or a wonder,
and city shield storage is not 0,
then ADD_SHIELDS = shields needed to finish it (production cost-shield storage), but not less than 0 and not more than 1/8 of civ treasury

4th rule: buy unit if there's no units in the city or city was successfully attacked
if there's no any unit in the city tile
OR 'defender was destroyed' flag is not 0 (same flag used as 'auto build' for human cities)
and city is producing a unit
and city shield storage is not 0
then ADD_SHIELDS = shields needed to finish it, but not less than 0 and not more than 1/3 of civ treasury

What it's interesting is that AI actually cannot immediately produce a freshly bought unit, even if it's looks like it can. If you destroy last unit in the city, AI can only build new one immediately if it already had some shields in store to do it. But AI cannot produce unit immediately after it bought it. But if you destroy second etc. defender, in this case AI actually bought a unit after your previous attack (on the previous turn), that's why it always seems that AI can buy them 'immediatelly'.

5th rule: strange buggy rule about palace (original purpose: probably to buy a palace)
if city is producing a palace
and city shield storage is not 0
then ADD_SHIELDS = shields needed to finish unit with number -1 (wrong place in memory!!), but not less than 0 and not more than 1/3 of civ treasury

in this place of memory game reads value 0x007f, which means AI will buy very huge amount of shields here, if it has enough money.
What was an original idea of this rule? Most likely it should be not unit array, but city improvements array and its 1st element (the palace). Much less likely that it should be not a palace (-1), but militia (1). Idea to buy palace is actually the good one, but only if AI actually could build a palace when needed. But AI can only build a palace when it has 'nothing to do', as a fail-safe selection.

6th rule: buggy rule (original purpose: buy a nuke if don't have any)
if city flags are strictly 0x19 (disorder+has hydro power+defender destroyed)*
and civ counter of nuclear units is 0
and city shield storage is not 0
then ADD_SHIELDS = shields needed to finish unit with number of production (for city improvements and wonders: wrong place in memory!!), but not less than 0 and not more than 1/4 of civ treasury

*and no any other flags are on!
Well, nuke unit number is 0x19, so there's just a typo in the code... And honestly, for a city to have strictly these flags is a very rare occurrence. But what will happen when it occurs? Well, in this case, if current production is a unit, AI will pretty actively try to buy it... But what if in production is not a unit? In this case, element of array will be negative and game will read some strange places in memory. For palace you already know how it goes: 0x007f. It's 0xffff for barracks, means -1, so AI will not buy barracks from this rule. It's 0x0000 for granary, temple and marketplace... 0x6365 for library. And so on, and so on... You should step 0x22 bytes backwards in unpacked exe every time.

7th rule: speed up anything, if rich enough
if treasury of civ is more than 2000 gold
then ADD_SHIELDS = ADD_SHIELDS+1/512 of civ treasury

finally, add ADD_SHIELDS to the city shield counter
and subtract 2*ADD_SHIELDS from civ treasury