And so, it is time for the final project for my Artificial Opponents class. For this project, the game is Empire, a precursor to Civilization with somewhat simpler rules.
This project is split into two parts:
- For the first part, we are supposed to make an AI that can explore as much of the map as it can in a certain number of turns. This is to get us acquainted with the code of the implementation of Empire we are working with, and also to think of some basic strategies and architecture for our AI.
- For the second part, we are supposed to expand on this exploration AI and actually make an AI to play against other opponents in a game of Empire (which consists of exploring the map, conquering cities, and fighting enemy units).
So, for my exploration AI, here’s what I have planned out:
- A pattern-based pathing system: This is something I initially wanted to attempt, and now have implemented. I’m not sure if I will keep this when we go into the next stage of the project, but I thought it might be a good starting point. Honestly, right now there’s not too much discouraging a strategy of sending out a bunch of the weak, yet quick-to-produce army units (since they can travel over water, although there’s a chance they’ll drown).
- Basically, this class so holds a vector containing a pattern: a set of directions (each of which is one of the eight cardinal/intercardinal directions). Each unit loops through this vector and bases its movement off of this pattern.
- However, I give each unit a different starting direction, and then base each subsequent movement in the pattern off of that starting direction. For example, if the unit’s starting direction is East, then East becomes that unit’s de facto “North,” and all directions thereafter are based on that.
- However, I also have a option to make it so that anytime the unit moves, the direction it is heading becomes its new “North.”
- Overall, I thought that this might be a useful system to explore a large amount of area with a small amount of units.
- A Blackboard?: A blackboard implementation might be useful, for storing/having access to the following information:
- Neutral cities: knowing where these cities are could be useful so that I could send a unit to conquer the city and then start producing units from its location.
- Water: knowing whether or not a map is mostly water (and how close cities are to water) would be helpful for choosing which unit types to build.
The reason I implemented the pattern-based system in the first place was because I thought that some sort of system where I sent out units in all directions (according to some sort of movement pattern) would be a fairly efficient way to cover the whole map.
Here are some visuals of some different patterns: as you can see a pattern of [North] covers a lot less ground than the more spiral pattern [North, North, North, East, Northeast, Northeast, Northeast]. So, my final pattern of choice will probably be something like the spiral pattern. Going diagonally also reveals more tiles than travelling straight, so that’s also something I’ll bear in mind.
Overall, I might just stick with my pattern-based system for now. I might augment it with a Blackboard, or at the very least set up the code for one. Going forward, I’ll definitely implement a Blackboard and maybe the A* pathfinding algorithm.