Lachlan's misadventures in games programming

Friday, 22 February 2013

Range Calculation Code - New Version

2/22/2013 12:53:00 am Posted by Lachlan , No comments

My old range calculation code (found here) was, as I admitted, slow and... well... rubbish.

Completely rewritten. Almost no trace of the old code whatsoever, and I do it in a far, far, far simpler manner now.

Again - licensed under Lachlan's Very Public License, being a modified Unlicense. Do whatever you want with it, don't blame me if something goes wrong, and donations/attribution/a comment saying its useful would be really nice.


public List<coord> GetRange(coord start, int range, bool PlayerCollides = true)
        {
            
            List<coord> returnlist = new List<coord>();

            int[,] distances = new int[range * 2 + 3, range * 2 + 3];
            for (int ix = 0; ix < distances.GetLength(0); ix++)
            {
                for (int iy = 0; iy < distances.GetLength(1); iy++)
                {
                    // -1 is not yet visited
                    // -2 is a collision point
                    distances[ix, iy] = (PlayerCollides ?
                                        (CheckCollision(ix + start.X - range - 1, iy + start.Y - range - 1)) :
                                        (TileCollides(ix + start.X - range - 1, iy + start.Y - range - 1))) ?
                                        -2 : -1;
                }
            }

            const int STRAIGHT_COST = 10;
            const int DIAG_COST = 14;

            distances[range + 1 ,range + 1] = 0;            
            
            for (int i = 1; i <= range; i++)
            {
                for (int jx = -i; jx <= i; jx++) { for (int jy =  -i; jy <= i; jy++)
                {
                    if (distances[jx + range + 1, jy + range + 1] == -1)
                    {
                        int minDistance = int.MaxValue;
                        for (int lx = -1; lx < 2; lx++)
                        {
                            for (int ly = -1; ly < 2; ly++)
                            {
                                if (!(lx == 0 && ly == 0))
                                {
                                    int distance = distances[jx + range + lx + 1, jy + range + ly + 1];
                                    if (distance >= 0)
                                    {
                                        minDistance = Math.Min(minDistance, distance +
                                            (((lx == 0) || (ly == 0)) ? STRAIGHT_COST : DIAG_COST));
                                    }
                                }
                            }
                        }
                        if (minDistance != int.MaxValue)
                        {
                            distances[jx + range + 1, jy + range + 1] = minDistance;
                            if (minDistance <= (range * STRAIGHT_COST))
                            {
                                returnlist.Add(new coord(jx + start.X, jy + start.Y));
                            }
                        }
                    }
                }}
            }

            return returnlist;
        }

0 comments:

Post a Comment