This explains the design of the Artificial Intelligence behind the computer player in the Empire Tutorial. Although this game only has one computer AI, in theory there can be up to 7 and this design allows that.
A good way to think about an AI design is by asking what it is expected to do. A proper specification includes requirements and tests to show that the completed software fulfills those requirements. That's a bit formal, so let's start with a set of requirements for the computer AI.
- Play a full game against a human player
- Control city production of new units
- React to enemy units on sea/land, near own units and cities
- Have a 1-5 scale of smartness from Dumb to Bright
- Be able to counter attack to recover lost cities.
- Be able to explore the shrouded map and grow its "Empire"
- Play with the same knowledge as the player. No cheating.
That's quite a tough set of requirements. If you are both designing and programming, try and do each one without thinking of the other. Don't be restrained by what you think you can do as a programmer when designing. Push yourself!
The AI is based upon tasks made up of multiple missions with resources allocated to each mission. Resources are units and may need city production to bring them up to the level required. For instance a task to explore sea requires a destroyer. If one isn't available then a request is put into the production scheduler to request a destroyer.
There are two schedulers. A strategy scheduler that generates all combat missions, including attack and defence and a production scheduler that gets requests for new units and farms out the building of them to available (and nearest) cities.
With games like this it would be all too easy for the AI to have full knowledge of the shrouded map terrain etc, but that would be cheating. This AI does not have to cheat. It has access to the cities, map and units arrays but only with the same knowledge that a human player has.
Map visibility is controlled by two bytes in each location. One is called Shrouded and the other Observed. The lowest bit (value 1) is used for the player, the next bit (value 2) for computer player 1, next bit (value 4) for computer player 2 etc). It looks like this:
This is done so up to seven players can play against a human player (and each other). In this game though it's just one one one.
The Shrouded byte controls whether the location is shrouded to the player. If it's a 1 then for that player (computer or human) the location is shrouded. If it's not shrouded then the Observed bit is also checked. This is to detect the movement of enemy units near to a city you own or your units.
Each turn, all Shrouded bits are cleared in a 5 x 5 block centred on each of the units for that unit's player. Also all locations in a 5 x 5 block around each city and unit have the observed bit set. This means you'll only see enemy units near to your cities and units. Likewise the computer AI will only react to units it "sees".
Each city has an owner byte so the AI can only use a city that it owns. Once an unowned city is unshrouded, it can be considered for capture.
AI Tasks and Missions
A task consists of 1-10 missions for a list of units.
Task structure is a struct with the following fields:
- Active Flag
- Task type (See below)
- Units List Structure (see below)
- Array of 1-10 missions.
- Number missions
- Priority. 0 is low, 10 is high
- Mission index 0-9 (depending on how many missions)
- Task Status
Tasks are strategic, while missions that make up a task are tactical. There can be 10-30 tasks on the go at once, determined by the intelligence of the AI. Tasks are only finished by a particular condition.
- Capture Continent
- Explore Map
- Attack Enemy Troops/Ships
Capturing an enemy city is a mission, but not a task.
A mission is a struct with the following information.
- Active flag
- Mission Type (See below)
- Target x,y
- Time to live (TTL). A Turn counter
- State (See below)
Mission Type is an int value for the type of mission. These are the missions available
- Attack Nearby Enemy Unit
- Capture City
- Explore (Sea or Land)
- Defend City
- Move unit to Location
- Move aircraft to city
- Load transport
- Board Transport
- Bomb Target
The Units List Structure is a struct holding a list of units engaged in this mission.
Mission state has the following values. Some of these values should not last very long. Once a mission has ended, the units can be released and made available for other missions.
- Inactive - not being used
- Waiting for units to board
- In transit
- Lost Units
The Lost Units state indicates that a mission needs reinforcements.
In the next AI tutorial I'll look at how these tasks and missions work and how to avoid "Opportunity Blindness" (where units on one mission would be better used in a more rewarding one that occurs) and "Flip flopping" where units switch missions too frequently.