]> Dogcows Code - chaz/carfire/commitdiff
AI initial calculations almost done, still a few small bugs. Used to determine lines...
authorbrady <brady@92bb83a3-7c8f-8a45-bc97-515c4e399668>
Sun, 25 Apr 2010 02:29:23 +0000 (02:29 +0000)
committerbrady <brady@92bb83a3-7c8f-8a45-bc97-515c4e399668>
Sun, 25 Apr 2010 02:29:23 +0000 (02:29 +0000)
git-svn-id: https://bd85.net/svn/cs3505_group@144 92bb83a3-7c8f-8a45-bc97-515c4e399668

CarFire/CarFire/CarFire/AI.cs [new file with mode: 0644]
CarFire/CarFire/CarFire/Game.cs

diff --git a/CarFire/CarFire/CarFire/AI.cs b/CarFire/CarFire/CarFire/AI.cs
new file mode 100644 (file)
index 0000000..8b8a25f
--- /dev/null
@@ -0,0 +1,346 @@
+//#define DisplayRegions\r
+#define DisplayFinalRegions\r
+\r
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using Microsoft.Xna.Framework;\r
+\r
+namespace CarFire\r
+{\r
+    /// <summary>\r
+    /// AI infomation to be used by monsters. The map is split into deferent regions, \r
+    /// each region is then linked to other regions that it can see.  \r
+    /// </summary>\r
+    public class AI\r
+    {\r
+        Game game;\r
+        int[,] regions;\r
+        List<Region> regionList;\r
+        int regionCnt;\r
+\r
+        public AI(Game _game)\r
+        {\r
+            game = _game;\r
+            regions = new int[game.State.Map.Width, game.State.Map.Height];\r
+            regionList = new List<Region>();\r
+            regionCnt = 0;\r
+\r
+            //set all square to -1 to show they have not been assigned to a region yet.\r
+            for (int y = 0; y < regions.GetLength(1); y++)\r
+            {\r
+                for (int x = 0; x < regions.GetLength(0); x++)\r
+                {\r
+                    regions[x, y] = -1;\r
+                }\r
+            }\r
+            regionList.Add(new Region(0)); //region 0 will represent all walls and things like it.\r
+           \r
+            #if DisplayRegions\r
+            printRegions();\r
+            #endif\r
+\r
+            setUpRegions();\r
+            foreach (Region r in regionList)\r
+                r.CalcCenter();\r
+            \r
+\r
+            #if (DisplayRegions || DisplayFinalRegions)\r
+            printRegions();\r
+            #endif\r
+            linkRegions();\r
+        }\r
+\r
+        /// <summary>\r
+        /// check to see if a spot on the map is visible from another spot\r
+        /// </summary>\r
+        /// <param name="curX">Current X position</param>\r
+        /// <param name="curY">Current Y position</param>\r
+        /// <param name="testX">X location to test</param>\r
+        /// <param name="testY">Y location to test</param>\r
+        public bool spaceVisible(int curX, int curY, int testX, int testY)\r
+        {\r
+            return regionList[regions[curX, curY]].VisibleRegions.Contains(regions[testX, testY]);\r
+        }\r
+\r
+        //find regions in map. these regions will be large groups of connected grid squares.\r
+        public int setUpRegions()\r
+        {\r
+            \r
+            //find open space that has not been assigned yet\r
+            for (int y = 0; y < regions.GetLength(1); y++)\r
+            {\r
+                for (int x = 0; x < regions.GetLength(0); x++)\r
+                {\r
+                    if (regions[x, y] == -1 && spaceOpen(x, y))\r
+                    {\r
+                        regionCnt++;\r
+                        regionList.Add(new Region(regionCnt));\r
+                        createRegion(x, y);\r
+                    }\r
+                    else if (regions[x, y] == -1)  //grid square is a wall\r
+                    {\r
+                        regions[x, y] = 0;\r
+                    }\r
+                    else //grid already assigned to region, do nothing\r
+                    {\r
+                    }\r
+                }\r
+            }\r
+\r
+            return regionList.Count;\r
+        }\r
+\r
+        #region Private Methods\r
+        private void createRegion(int x, int y)\r
+        {\r
+            regionList[regionCnt].Left = x;\r
+            regionList[regionCnt].Top = y;\r
+\r
+            for (int rY = 0; rY < 5 && y + rY < regions.GetLength(1); rY++) // creates a region as large as possible up to 5x5\r
+            {\r
+                for (int rX = 0; rX < 5 && x + rX < regions.GetLength(0); rX++)\r
+                {\r
+                    if (regions[x + rX, y + rY] == -1 && spaceOpen(x + rX, y + rY))\r
+                    {\r
+                        regions[x + rX, y + rY] = regionCnt;\r
+                    }\r
+                    else if (regions[x + rX, y + rY] == -1)  //grid square is a wall\r
+                    {\r
+                        regions[x + rX, y + rY] = 0;\r
+                        regionList[regionCnt].Right = x + rX;\r
+                        regionList[regionCnt].Bottom = y + rY;\r
+                        #if DisplayRegions\r
+                        printRegions();\r
+                        #endif\r
+                        if (!spaceOpen(x + rX + 1, y + rY)) // hit horizontal wall end region\r
+                            if(x + rX >= regions.GetLength(0)-1)\r
+                                break;\r
+                            else\r
+                                return;\r
+                        else\r
+                            break;\r
+\r
+                        //todo: figure out how to get region to stop being created when \r
+                    }\r
+                    else //grid already assigned to region, do nothing\r
+                    {\r
+                    }\r
+                    regionList[regionCnt].Right = x + rX;\r
+                }\r
+                \r
+                regionList[regionCnt].Bottom = y + rY;\r
+            }\r
+            #if DisplayRegions\r
+            printRegions();\r
+            #endif\r
+            return;\r
+        }\r
+        private bool spaceOpen(int x, int y)\r
+        {\r
+            if (x >= regions.GetLength(0)) return false;\r
+            if (y >= regions.GetLength(1)) return false;\r
+            return !game.State.Map.IsWall(x, y);\r
+        }\r
+        //TODO: scans out from each corner, some areas are still missed\r
+        private void linkRegions()\r
+        {\r
+            foreach (Region r in regionList)\r
+            {\r
+                if (r.Label == 0)\r
+                    continue;\r
+                //scan from center\r
+\r
+                //scan from corners\r
+                //top Left\r
+                int x = r.Left;\r
+                int y = r.Top;\r
+                //scan up\r
+                for (int t = 1; spaceOpen(x, y - t); t++)\r
+                {\r
+                    if ( regions[x, y] != regions[x, y - t] )\r
+                    {\r
+                        regionList[regions[x, y]].AddVisible(regions[x, y - t]);\r
+                    }\r
+                }\r
+                //scan left\r
+                for (int t = 1; spaceOpen(x - t, y); t++)\r
+                {\r
+                    if ( regions[x, y] != regions[x - t, y] )\r
+                    {\r
+                        regionList[regions[x, y]].AddVisible(regions[x - t, y]);\r
+                    }\r
+                }\r
+                //scan diag\r
+                for (int t = 1; spaceOpen(x - t, y - t); t++)\r
+                {\r
+                    if (regions[x, y] != regions[x - t, y - t])\r
+                    {\r
+                        regionList[regions[x, y]].AddVisible(regions[x - t, y - t]);\r
+                    }\r
+                }\r
+\r
+                //top Right\r
+                x = r.Right;\r
+                y = r.Top;\r
+                //scan up\r
+                for (int t = 1; spaceOpen(x, y - t); t++)\r
+                {\r
+                    if (regions[x, y] != regions[x, y - t])\r
+                    {\r
+                        regionList[regions[x, y]].AddVisible(regions[x, y - t]);\r
+                    }\r
+                }\r
+                //scan Right\r
+                for (int t = 1; spaceOpen(x + t, y); t++)\r
+                {\r
+                    if (regions[x, y] != regions[x + t, y])\r
+                    {\r
+                        regionList[regions[x, y]].AddVisible(regions[x + t, y]);\r
+                    }\r
+                }\r
+                //scan diag\r
+                for (int t = 1; spaceOpen(x + t, y - t); t++)\r
+                {\r
+                    if (regions[x, y] != regions[x + t, y - t])\r
+                    {\r
+                        regionList[regions[x, y]].AddVisible(regions[x + t, y - t]);\r
+                    }\r
+                }\r
+\r
+                //bottom Right\r
+                x = r.Right;\r
+                y = r.Bottom;\r
+                //scan down\r
+                for (int t = 1; spaceOpen(x, y + t); t++)\r
+                {\r
+                    if (regions[x, y] != regions[x, y + t])\r
+                    {\r
+                        regionList[regions[x, y]].AddVisible(regions[x, y + t]);\r
+                    }\r
+                }\r
+                //scan Right\r
+                for (int t = 1; spaceOpen(x + t, y); t++)\r
+                {\r
+                    if (regions[x, y] != regions[x + t, y])\r
+                    {\r
+                        regionList[regions[x, y]].AddVisible(regions[x + t, y]);\r
+                    }\r
+                }\r
+                //scan diag\r
+                for (int t = 1; spaceOpen(x + t, y + t); t++)\r
+                {\r
+                    if (regions[x, y] != regions[x + t, y + t])\r
+                    {\r
+                        regionList[regions[x, y]].AddVisible(regions[x + t, y + t]);\r
+                    }\r
+                }\r
+\r
+                //bottom left\r
+                x = r.Left;\r
+                y = r.Bottom;\r
+                //scan down\r
+                for (int t = 1; spaceOpen(x, y + t); t++)\r
+                {\r
+                    if (regions[x, y] != regions[x, y + t])\r
+                    {\r
+                        regionList[regions[x, y]].AddVisible(regions[x, y + t]);\r
+                    }\r
+                }\r
+                //scan Left\r
+                for (int t = 1; spaceOpen(x - t, y); t++)\r
+                {\r
+                    if (regions[x, y] != regions[x - t, y])\r
+                    {\r
+                        regionList[regions[x, y]].AddVisible(regions[x - t, y]);\r
+                    }\r
+                }\r
+                //scan diag\r
+                for (int t = 1; spaceOpen(x - t, y + t); t++)\r
+                {\r
+                    if (regions[x, y] != regions[x - t, y + t])\r
+                    {\r
+                        regionList[regions[x, y]].AddVisible(regions[x - t, y + t]);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        #endregion\r
+        //for testing print the region grid to the console\r
+        public void printRegions()\r
+        {\r
+            Console.WriteLine("--Printing Regions--");\r
+            for (int y = 0; y < regions.GetLength(1); y++)\r
+            {\r
+                for (int x = 0; x < regions.GetLength(0); x++)\r
+                {\r
+                    Console.Write(regions[x, y]);\r
+                }\r
+                Console.WriteLine("");\r
+            }\r
+        }\r
+    }\r
+\r
+    /// <summary>\r
+    /// a chuck of the map that is at most 5x5 used to determine line of sight\r
+    /// </summary>\r
+    public class Region\r
+    {\r
+        List<int> visibleRegions; //other regions that are in this regions sight\r
+        int label;\r
+        int centerX;\r
+        int centerY;\r
+\r
+        //edges\r
+        int left, right, top, bottom; \r
+\r
+        public Region(int _label)\r
+        {\r
+            label = _label;\r
+            visibleRegions = new List<int>();\r
+        }\r
+\r
+        public void AddVisible(int region)\r
+        {\r
+            if(!visibleRegions.Contains(region))\r
+                visibleRegions.Add(region);\r
+        }\r
+\r
+        public void CalcCenter()\r
+        {\r
+             if (right != left) centerX = right + (right - left) / 2;\r
+             else centerX = right;\r
+             if (top != bottom) centerY = top + (bottom - top) / 2;\r
+             else centerY = top;\r
+        }\r
+\r
+        public int Left \r
+        { \r
+            get { return left; } \r
+            set { left = value; }\r
+        }\r
+        public int Right\r
+        {\r
+            get { return right; }\r
+            set { right = value; }\r
+        }\r
+        public int Top\r
+        {\r
+            get { return top; }\r
+            set { top = value; }\r
+        }\r
+        public int Bottom\r
+        {\r
+            get { return bottom; }\r
+            set { bottom = value; }\r
+        }\r
+\r
+        public Point Center { get { return new Point(centerX, centerY); } }\r
+        public int Label { get { return label; } }\r
+\r
+        public List<int> VisibleRegions { get { return visibleRegions; } }\r
+\r
+\r
+    }\r
+}\r
index c2a7aafadf8e0f58cea4b86fa33b07205e3101e9..f91882e047c08f85e578ec0e3716d3cce5986d9d 100644 (file)
@@ -27,7 +27,7 @@ namespace CarFire
         public List<Projectile> mProjectiles = new List<Projectile>();\r
         public Player[] mCharacters;\r
         public Display mDisplay;\r
         public List<Projectile> mProjectiles = new List<Projectile>();\r
         public Player[] mCharacters;\r
         public Display mDisplay;\r
-\r
+        public AI AIData;\r
         #endregion\r
 \r
 \r
         #endregion\r
 \r
 \r
@@ -369,6 +369,8 @@ namespace CarFire
             State.Map.Tilemap = tilemap;\r
             State.Entities = State.Map.GetAllEntities(this);\r
 \r
             State.Map.Tilemap = tilemap;\r
             State.Entities = State.Map.GetAllEntities(this);\r
 \r
+            State.AIData = new AI(this);\r
+\r
             /*\r
             mPlayers.Clear();\r
             for (int i = 0; i < PlayerIdentifiers.Length; i++)\r
             /*\r
             mPlayers.Clear();\r
             for (int i = 0; i < PlayerIdentifiers.Length; i++)\r
This page took 0.030565 seconds and 4 git commands to generate.