Tuesday, April 2, 2013

Turn Based Strategy Game AI part 9b

I should have never posted the prior post just before having to roll out a large project at work. Getting wicked sick after that didn't help. But that only accounts for about 2 weeks, I can only blame my own procrastination at the remainder of the delay. Something about being overdue in writing the next installment makes it even tougher to get started again.

Unlike prior installments, the code is all ready written and ready to go, I just needed to provide the commentary. It is my hope that the next few posts will come out pretty quickly from here on out.

In the last post, I introduced a new structure to the AI in which I have several specialized modules addressing each need instead of a single routine that tried to balance all the needs together. It made sense to use a base class that each of these modules would use. It is this base class I wanted to present first. It is pretty simple, providing a standard set of abstract functions for each module as well as some helper functions of use to all modules.

As the AI engages a Module, it first calls its Initialize() routine, and will then call GetNextMove() repeatedly until the Module is finished, which is determined by checking the IsFinished property prior to each iteration. Not terribly exciting I am afraid.

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;

namespace ShatteredThrone.AI
{
    abstract class CommandModule
    {

        public abstract void Initialize();
        public abstract AiAction GetNextMove(GameDetail gd);
        public abstract bool IsFinished {get;}

        public virtual bool RestartFromBeginning
        {
            get
            {
                return false;
            }
        }

        protected List GetBuildableUnitTypes(GameDetail gd, int gold, int playerId)
        {
            List ret = new List();

            List units = gd.GetPlayerUnitsDetail(playerId);
            foreach (UnitDetail ud in units)
            {
                if (ud.Cost <= gold)
                    ret.Add(ud.UnitType);
            }

            return ret;
        }

        protected List GetUnitsLeftToMove(int who, GameState gs)
        {
            List ret = new List();

            foreach (UnitStatus u in gs.Units)
            {
                if (u.IsAlive && u.Owner == who && !u.HasMoved && u.IsReady)
                {
                    ret.Add(u);
                }
            }

            return ret;
        }

        protected List GetAvailableBuildingSettlements(int who, GameState gs)
        {
            List ret = new List();

            foreach (Settlement s in gs.Settlements)
            {
                if (s.Owner == who && s.CanBuildUnits)
                {
                    // check for unit at this location
                    if (gs.GetUnitAtLocation(s.X, s.Y) == null)
                    {
                        ret.Add(s);
                    }
                }
            }

            return ret;
        }

    }
}

No comments: