Saturday, February 18, 2012

Very Basic Influence Map

So I finally had a little time and was able to edit the control scheme of the maze generation game so that I could control it with a xbox360 controller. I was also able to create a very basic influence map class which I hope to improve upon.

There are numerous uses for influence maps but for this demo, our influence map helps my monster Santa explore. Previously, the monster simply takes a random value and could get stuck in a loop for awhile before the random number generator picks a lucky value and stops the monster from moving in a circle. With influence map, I assign each grid location a numeric value from 0 to 100 with 100 being the most influential value. As the monster reaches a grid location, I set that location's influence value to the maximum. Over time, the value of this grid will slowly decrease until it reaches 0. This makes the AI more believable and gives the effect of "Oh I haven't been to grid x for a long time so I'm not sure what's really there". The second part is to decide what to do with these values. For my monster, as it explores, I've given it a visibility range of 1 which means it will only look at the adjacent grid locations. From those grid locations, it will look at each of its influence value and will move towards the lowest value possible. Because this is done in the monster's explore state, the above implementation creates the behavior of the monster identifying where it hasn't checked in awhile a proceeds to that location.

 
//simply a 2d grid structure with values that decay over time
    class InfluenceMap
    {
        public const float decayInterval = 5.0f;    //decreases influence value every this amount of seconds
        public const float decayAmount = 0.25f;     //for every decayInterval, decrease influence value by this much
        public readonly float maxValue = 100.0f;    //the maximum value a influence location can have

        /// 
        /// 
        /// 
        /// the maximum number of rows        /// the maximum number of columns        public InfluenceMap(uint row, uint col)
        {
            _gridPositions = new float[row, col];
            for (uint i = 0; i < _maxRow; ++i)
            {
                for (uint j = 0; j < _maxCol; ++j)
                {
                    _gridPositions[i, j] = 0.0f;
                }
            }

            _currentInterval = 0.0f;
            _maxRow = row;
            _maxCol = col;
        }

        public void SetLocation(uint row, uint col)
        {
            _gridPositions[row, col] = maxValue;
        }

        public float GetValue(int row, int col)
        {
            return _gridPositions[row, col];
        }

        public void Update(float dt)
        {
            _currentInterval += dt;
            if (_currentInterval > decayInterval)
            {
                ApplyDecay();
                _currentInterval = 0.0f;
            }
        }

        private void ApplyDecay()
        {
            for (uint i = 0; i < _maxRow; ++i)
            {
                for (uint j = 0; j < _maxCol; ++j)
                {
                    _gridPositions[i, j] = MathHelper.Clamp(_gridPositions[i, j] - decayAmount, 0.0f, maxValue);
                }
            }
        }

        private float[,] _gridPositions;
        private float _currentInterval;
        private uint _maxRow;
        private uint _maxCol;
    }
Here is a video showing the maze generation as well as the new basic influence map implementation on the monster.
It's now slightly smarter in its decision in terms of picking which route to take. Something I can improve on is increasing the visibility range of the monster so it looks up to 5 grid location ahead for example. I can also improve on the influence map by performing a propagation effect so that when an influence value is set or we perform decay on the grids, each grid will take into account their neighbors as well which will create a much smoother and more realistic mapping.

Saturday, January 21, 2012

Thoughts about AI Implementation

I've been thinking on how to tackle the AI implementation to the maze game and there are 3 specific cases I need to deal with.

1) When player uses his compass ability, the AI is notified of his position and we can use an A* search algorithm to get a path to the player.

2) If the player is within the AI's line of sight, it will chase after it. We can probably perform a ray cast collision test. The ray will originate from the Ai's position and the direction will be the AI model's forward. If the ray collides with the player within a certain line of sight value, then we can set it to target the player.

3) Lastly, when the AI has no idea where the player is, we need an AI algorithm which can smartly explore the maze. Currently, the AI only knows of its previous position and randomly pick a path that is not the previous position (unless it's a dead end of course). After reading through some pages about how robot solves mazes, I found an interesting implementation where all the grids cells in a maze would contain a value telling the robot the number of times it has visited that particular cell. It would then look for the lowest number and go there.
To make a more believable AI, I think I can take the above concept andincorporate it with a exploration value such that the AI will recursively find possible paths with lengths up to this exploration constant. It would then look for the path that contains the lowest visited grid and go there. If there is nothing smaller than the value of the grid we're on? We can ask the AI to just randomly pick a position. I am also thinking about extending the previously visited position so that the AI remembers the previous x number of positions. That way, if the AI has to randomly pick a path, it will continue to move towards the unknown so to speak. By doing this, the AI can smartly explore places but doesn't turn into a know-it-all.

Once I actually start implementing this, I will post some source code here

Wednesday, January 11, 2012

Hello and welcome!

Hello everyone!

This is a blog for any self projects and interesting tid bits I have encountered. I work with various languages such as c++, c#, objective c as well as several different engines and libraries such as directX, XNA, Unity3D, cocos2d. I may also include information about the unreal engine and unreal script if the thesis project ends up being developed with the unreal engine.

I have a blog for all my current school projects HERE. If you have seen my previous blog, you'll know that I've talked about a maze game I had to make for one of my school projects. Currently, the game is a mouse and cat chasing game where you are trying to escape from Santa's workshop and leave the north pole by locating Santa's sleigh! If you get caught by Santa, then you lose the game. The game uses a randomly generated maze which I will talk in a later post. Because of the time limit, there were some features I was not able to implement. Specifically, I would like to work on improving the Santa AI and implement an A* algorithm and other parameters such as line of sight. I will try to accomplish these goals during my free time and will update my blog about implementations and results.