Advertisement
Spectrewiz

Path Finding for AI

Jun 30th, 2012
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.78 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.Xna.Framework;
  6. using Microsoft.Xna.Framework.Audio;
  7. using Microsoft.Xna.Framework.Content;
  8. using Microsoft.Xna.Framework.GamerServices;
  9. using Microsoft.Xna.Framework.Graphics;
  10. using Microsoft.Xna.Framework.Input;
  11. using Microsoft.Xna.Framework.Media;
  12.  
  13. namespace ZombieShooter
  14. {
  15.     class pathFinder
  16.     {
  17.         private Grid[,] map;
  18.         public static int queue = 0;
  19.         public static int Qtimer = 0;
  20.         public const int Qtime = 1;
  21.         public const int gridSize = 32;
  22.  
  23.         public pathFinder(bool[,] bMap)
  24.         {
  25.             //read map
  26.             map = new Grid[bMap.GetLength(0), bMap.GetLength(1)];
  27.  
  28.             for (int r = 0; r < map.GetLength(0); r++) {
  29.                 for (int c = 0; c < map.GetLength(1); c++) {
  30.                     map[r, c] = new Grid();
  31.                     map[r, c].Walkable = bMap[r, c];
  32.                 }
  33.             }
  34.         }
  35.  
  36.         public static bool[,] writeMap(params Obj[] objEx)
  37.         {
  38.             bool[,] cMap = new bool[Convert.ToInt16(Game.stage.Height / pathFinder.gridSize),
  39.                  Convert.ToInt16(Game.stage.Width / pathFinder.gridSize)];
  40.  
  41.             //loop through rows
  42.             for (int r = 0; r < cMap.GetLength(0); r++)
  43.             {
  44.                 //loop through collums
  45.                 for (int c = 0; c < cMap.GetLength(1); c++)
  46.                 {
  47.                     Rectangle rec = new Rectangle();
  48.                     rec.X = c * pathFinder.gridSize; rec.Y = r * pathFinder.gridSize;
  49.                     rec.Width = rec.Height = pathFinder.gridSize;
  50.  
  51.                     //If collision with grid then grid is unwalkable
  52.                     foreach (Obj o in ObjList.objList)
  53.                     {
  54.                         if (o.area.Intersects(rec) && o.alive && o.Solid && !objEx.Contains<Obj>(o)) { cMap[r, c] = false; break; } else { cMap[r, c] = true; }
  55.  
  56.                         //set all borders to walls
  57.                         if (r == 0 || c == 0 || r == cMap.GetLength(0) - 1 || c == cMap.GetLength(1) - 1)
  58.                         {
  59.                             cMap[r, c] = false; break;
  60.                         }
  61.                     }
  62.                 }
  63.             }
  64.  
  65.             return cMap;
  66.         }
  67.  
  68.         public List<Point> findPath(Vector2 pos, Vector2 dest)
  69.         {
  70.             resetMap();
  71.             List<Point> path = new List<Point>();
  72.             //List<Point> openList = new List<Point>();
  73.             List<Point> openListB = new List<Point>();
  74.             openListB.Add(new Point(0,0));
  75.             List<Point> closedList = new List<Point>();
  76.  
  77.             //Get start and end positions
  78.             Point startPos = new Point(Convert.ToInt16(Math.Floor((double)(pos.Y / gridSize))),
  79.                 Convert.ToInt16(Math.Floor((double)(pos.X / gridSize))));
  80.             Point endPos = new Point(Convert.ToInt16(Math.Floor((double)(dest.Y / gridSize))),
  81.                 Convert.ToInt16(Math.Floor((double)(dest.X / gridSize))));
  82.  
  83.             Point curPos = startPos;
  84.  
  85.             map[curPos.X, curPos.Y].Closed = true;
  86.             closedList.Add(curPos);
  87.  
  88.             while (!closedList.Contains(endPos))
  89.             {
  90.                 /* add all adjescent nodes to the open list,
  91.                  * set the parent of all adjacent nodes to the cur node,
  92.                  * calculate F score for all adjacent node */
  93.                 foreach (Point v in getAdj(curPos))
  94.                 {
  95.                     if (map[v.X, v.Y].Walkable && !map[v.X, v.Y].Closed)
  96.                     {
  97.                         if (!openListB.Contains(v))
  98.                         {
  99.                             //Check if cutting corner
  100.                             bool cutCorner = false;
  101.                             if (getG(v, curPos) == 14) {
  102.                                 foreach (Point p in getAdj(v)) {
  103.                                     if (!map[p.X, p.Y].Walkable && getH(curPos, p) == 10) {
  104.                                         cutCorner = true;
  105.                                     }
  106.                                 }
  107.                             }
  108.                             if (!cutCorner)
  109.                             {
  110.                                 openListB.Add(v);
  111.                                 map[v.X, v.Y].Parent = curPos;
  112.                                 map[v.X, v.Y].G = getG(v, curPos);
  113.                                 map[v.X, v.Y].H = getH(v, endPos);
  114.                                 map[v.X, v.Y].F = map[v.X, v.Y].G + map[v.X, v.Y].H;
  115.  
  116.                                 int m = openListB.Count - 1;
  117.                                 while (m != 1) //if node has not gone to top (m=1)
  118.                                 {
  119.                                     //If objLIstB[m] fcost <= objListB[m/2] fcost
  120.                                     if (map[openListB[m].X, openListB[m].Y].F <= map[openListB[m / 2].X, openListB[m / 2].Y].F)
  121.                                     {
  122.                                         //swap positions
  123.                                         Point temp = openListB[m / 2];
  124.                                         openListB[m / 2] = openListB[m];
  125.                                         openListB[m] = temp;
  126.                                         m /= 2;
  127.                                     }
  128.                                     else { break; }
  129.                                 }
  130.                             }
  131.                         }
  132.                         //else if Cur Node G score + New G score < prev G score
  133.                         else if (map[curPos.X, curPos.Y].G + getG(v, curPos) < map[curPos.X, curPos.Y].G)
  134.                         {
  135.                             map[v.X, v.Y].Parent = curPos;
  136.                             map[v.X, v.Y].G = getG(v, curPos);
  137.                             map[v.X, v.Y].H = getH(v, endPos);
  138.                             map[v.X, v.Y].F = map[v.X, v.Y].G + map[v.X, v.Y].H;
  139.  
  140.                             int m = openListB.IndexOf(v);
  141.                             while (m != 1) //if node has not gone to top (m=1)
  142.                             {
  143.                                 //If objLIstB[m] fcost <= objListB[m/2] fcost
  144.                                 if (map[openListB[m].X, openListB[m].Y].F <= map[openListB[m / 2].X, openListB[m / 2].Y].F)
  145.                                 {
  146.                                     //swap positions
  147.                                     Point temp = openListB[m / 2];
  148.                                     openListB[m / 2] = openListB[m];
  149.                                     openListB[m] = temp;
  150.                                     m /= 2;
  151.                                 }
  152.                                 else { break; }
  153.                             }
  154.                         }
  155.                     }
  156.                 }
  157.  
  158.                 if (!closedList.Contains(endPos) && openListB.Count == 1 && closedList.Count >= 1) { return null; }
  159.                 //Choose the node with the lowest F score
  160.                 curPos = openListB[1];
  161.  
  162.                 //remove cur node from open list and add to closed list
  163.                 map[curPos.X, curPos.Y].Closed = true;
  164.                 closedList.Add(curPos);
  165.                 openListB[1] = openListB[openListB.Count-1];
  166.                 openListB.RemoveAt(openListB.Count - 1);
  167.                 int vv = 1;
  168.                 while (true)
  169.                 {
  170.                     int uu = vv;
  171.                     if (2 * uu + 1 < openListB.Count)
  172.                     {
  173.                         if (map[openListB[uu].X, openListB[uu].Y].F >= map[openListB[uu * 2].X, openListB[uu * 2].Y].F) { vv = uu * 2; }
  174.                         if (map[openListB[vv].X, openListB[vv].Y].F >= map[openListB[uu * 2 +1].X, openListB[uu * 2 + 1].Y].F) { vv = uu * 2 + 1; }
  175.                     }
  176.                     else if (2 * uu < openListB.Count)
  177.                     {
  178.                         if (map[openListB[uu].X, openListB[uu].Y].F >= map[openListB[uu * 2].X, openListB[uu * 2].Y].F) { vv = uu * 2; }
  179.                     }
  180.  
  181.                     if (uu != vv)
  182.                     {
  183.                         Point temp = openListB[uu];
  184.                         openListB[uu] = openListB[vv];
  185.                         openListB[vv] = temp;
  186.                     }
  187.                     else { break; }
  188.                 }
  189.  
  190.                 //if endPos unreachable return null
  191.                 if (!closedList.Contains(endPos) && openListB.Count == 1 && closedList.Count > 1) { return null; }
  192.             }
  193.  
  194.             Point curNode = endPos;
  195.             path.Add(new Point((curNode.Y * gridSize) - (gridSize / 2),
  196.                     (curNode.X * gridSize) - (gridSize / 2)));
  197.             while(curNode != startPos)
  198.             {
  199.                 curNode = map[curNode.X, curNode.Y].Parent;
  200.                 path.Add(new Point((curNode.Y * gridSize) + (gridSize / 2),
  201.                     (curNode.X * gridSize) + (gridSize / 2)));
  202.             }
  203.  
  204.             path.Reverse();
  205.  
  206.             return path;
  207.         }
  208.  
  209.         private int getH(Point v, Point endPos)
  210.         {
  211.             Point diff = new Point(v.X - endPos.X, v.Y - endPos.Y);
  212.             if (diff.X < 0) { diff.X *= -1; }
  213.             if (diff.Y < 0) { diff.Y *= -1; }
  214.  
  215.             return Convert.ToInt16(diff.X + diff.Y);
  216.         }
  217.  
  218.         private int getG(Point v, Point curPos)
  219.         {
  220.             Point diff = new Point(v.X - curPos.X, v.Y - curPos.Y);
  221.             if (diff.Y == 0 || diff.X == 0)
  222.             {
  223.                 return 10;
  224.             }
  225.             else
  226.             {
  227.                 return 14;
  228.             }
  229.         }
  230.  
  231.         private void resetMap()
  232.         {
  233.             //read map
  234.             for (int r = 0; r < map.GetLength(0); r++)
  235.             {
  236.                 for (int c = 0; c < map.GetLength(1); c++)
  237.                 {
  238.                     map[r, c].Reset();
  239.                 }
  240.             }
  241.         }
  242.  
  243.         private List<Point> getAdj(Point curPos)
  244.         {
  245.             List<Point> adjList = new List<Point>();
  246.  
  247.             adjList.Add(new Point(curPos.X - 1, curPos.Y - 1));
  248.             adjList.Add(new Point(curPos.X, curPos.Y - 1));
  249.             adjList.Add(new Point(curPos.X + 1, curPos.Y - 1));
  250.             adjList.Add(new Point(curPos.X - 1, curPos.Y));
  251.             adjList.Add(new Point(curPos.X - 1, curPos.Y + 1));
  252.             adjList.Add(new Point(curPos.X + 1, curPos.Y + 1));
  253.             adjList.Add(new Point(curPos.X, curPos.Y + 1));
  254.             adjList.Add(new Point(curPos.X + 1, curPos.Y));
  255.  
  256.             return adjList;
  257.         }
  258.  
  259.         public static void update()
  260.         {
  261.             /*Qtimer++;
  262.             if (Qtimer > Qtime)
  263.             {
  264.                 queue = 0;
  265.                 Qtimer = 0;
  266.             }*/
  267.         }
  268.     }
  269. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement