Пример #1
0
Файл: Map.cs Проект: tgy/CSharp
 public Map(byte[,] table)
 {
     tileList = new Tile[table.GetLength(0), table.GetLength(1)];
     for (int y = 0; y < table.GetLength(0); y++)
         for (int x = 0; x < table.GetLength(1); x++)
             tileList[y, x] = new Tile(y, x, table[y, x]);
 }
Пример #2
0
Файл: Node.cs Проект: tgy/CSharp
        public Node(Tile tile, Node parent, Tile destination)
        {
            this.tile = tile;
            this.parent = parent;

            this.estimatedMovement = (int) (Math.Abs(destination.Position.X - tile.Position.X) +
                                     Math.Abs(destination.Position.Y - tile.Position.Y));
        }
Пример #3
0
        protected override void Initialize()
        {
            heros = new Hero(0, 13, 4);
            cost = new Cost(heros);
            startTile = map.TileList[heros.Y, heros.X];

            base.Initialize();
        }
Пример #4
0
        public static List<Node> PossibleNode = new List<Node>(); // Les noeuds possibles (cases adjacentes de tout le chemin)

        #endregion Fields

        #region Methods

        public static MyLinkedList<Tile> CalculatePathWithAStar(Map map, Tile startTile, Tile endTile)
        {
            PossibleNode.Clear();
            NodeList<Node> openList = new NodeList<Node>(); // Contiens tout les noeuds candidat (qui vont être examinés)
            NodeList<Node> closedList = new NodeList<Node>(); // Contiens la liste des meilleurs noeuds (le resultat du plus cours chemin)
            List<Node> possibleNodes; // cases adjacentes du noeud courant

            // Le noeud de départ
            Node startNode = new Node(startTile, null, endTile); // FIXME : on recupère le noeud de départ

            /**********************************/
            /* Traitement des noeuds candidat */
            /**********************************/

            openList.Add(startNode);

            while (openList.Count > 0) // Tant que la liste ouverte contient des éléments
            {
                Node current = openList[0];
                openList.RemoveAt(0);
                closedList.Add(current);

                if (current.Tile == endTile) // si l'élément courant est la case destination
                {
                    MyLinkedList<Tile> solution = new MyLinkedList<Tile>();
                    // on reverse la liste fermée et on la retourne pour l'avoir dans le bonne ordre
                    while (current.Parent != null)
                    {
                        solution.AddFirst(current.Tile);
                        current = current.Parent;
                    }
                    return solution;
                }
                possibleNodes = current.GetPossibleNode(map, endTile); // FIXME : recupère la listes des cases adjacentes

                // on ajoute cette liste a notre variable static qui contient l'ensemble des listes adjacentes (gestion de l'affichage)
                PossibleNode.AddRange(possibleNodes) ;

                /***************************************/
                /* Ajout des noeuds adjacents candidat */
                /***************************************/
                for (int i = 0; i < possibleNodes.Count; i++) // on vérifie que chaque noeuds adjacent (possibleNodes)
                {
                    if (!closedList.Contains(possibleNodes[i])) // n'existe pas dans la liste fermée (eviter la redondance)
                    {
                        if (openList.Contains(possibleNodes[i])) // FIXME : Si il existe dans la liste ouverte on vérifie
                        {
                            if (possibleNodes[i].EstimatedMovement < openList[possibleNodes[i]].EstimatedMovement) // si le cout de deplacement du
                                // noeud est inferieur a un coût calculer précedement, dance cas la on remonte le chemin dans la liste ouverte
                                openList[possibleNodes[i]].Parent = current;
                        }
                        else
                            openList.DichotomicInsertion(possibleNodes[i]);
                    }
                }
            }
            return null;
        }
Пример #5
0
Файл: Node.cs Проект: tgy/CSharp
 // recupère les 8 cases adjacentes
 public List<Node> GetPossibleNode(Map map, Tile destination)
 {
     List<Node> result = new List<Node>();
     // Bottom
     if (map.ValidCoordinates(tile.X, tile.Y + 1) && map.TileList[tile.Y + 1,
     tile.X].Type != TileType.Wall)
         result.Add(new Node(map.TileList[tile.Y + 1, tile.X], this,
         destination));
     // Right
     if (map.ValidCoordinates(tile.X + 1, tile.Y) && map.TileList[tile.Y,
     tile.X + 1].Type != TileType.Wall)
         result.Add(new Node(map.TileList[tile.Y, tile.X + 1], this,
         destination));
     // Top
     if (map.ValidCoordinates(tile.X, tile.Y - 1) && map.TileList[tile.Y - 1,
     tile.X].Type != TileType.Wall)
         result.Add(new Node(map.TileList[tile.Y - 1, tile.X], this,
         destination));
     // Left
     if (map.ValidCoordinates(tile.X - 1, tile.Y) && map.TileList[tile.Y,
     tile.X - 1].Type != TileType.Wall)
         result.Add(new Node(map.TileList[tile.Y, tile.X - 1], this,
         destination));
     // Bottom Left
     if (map.ValidCoordinates(tile.X - 1, tile.Y + 1) && map.TileList[tile.Y + 1,
     tile.X - 1].Type != TileType.Wall)
         result.Add(new Node(map.TileList[tile.Y + 1, tile.X - 1], this,
         destination));
     // Bottom Right
     if (map.ValidCoordinates(tile.X + 1, tile.Y + 1) && map.TileList[tile.Y + 1,
     tile.X + 1].Type != TileType.Wall)
         result.Add(new Node(map.TileList[tile.Y + 1, tile.X + 1], this,
         destination));
     // Top Left
     if (map.ValidCoordinates(tile.X - 1, tile.Y - 1) && map.TileList[tile.Y - 1,
     tile.X - 1].Type != TileType.Wall)
         result.Add(new Node(map.TileList[tile.Y - 1, tile.X - 1], this,
         destination));
     // Top Right
     if (map.ValidCoordinates(tile.X + 1, tile.Y - 1) && map.TileList[tile.Y - 1,
     tile.X + 1].Type != TileType.Wall)
         result.Add(new Node(map.TileList[tile.Y - 1, tile.X + 1], this,
         destination));
     return result;
 }
Пример #6
0
        public void aStar()
        {
            int min = minimum(), cost;
            Tile current = new Tile(Vector2.Zero, false);
            List<Tile> neighbors;
            while (min >= 0 && open[min].pos != goalTile.pos) {
                current = open[min];
                open.RemoveAt(min);
                close.Add(current);
                neighbors = neighborTiles(current);

                foreach (Tile neighbor in neighbors) {
                    int gkost = g(current),
                        mkost = movementCost(current, neighbor),
                        gnkost = g(neighbor);
                    cost = gkost + mkost;
                    if (open.Contains(neighbor) && cost < gnkost)
                        open.Remove(neighbor);
                    if (close.Contains(neighbor) && cost < gnkost)
                        close.Remove(neighbor);
                    if (!(open.Contains(neighbor) || close.Contains(neighbor)))
                    {
                        int hkost = h(neighbor);
                        cost = gnkost;
                        neighbor.rank = gnkost + hkost;
                        neighbor.pre = current;
                        open.Add(neighbor);
                    }
                }
                min = minimum();
            }
            walker = null;
            if (min < 0) return;
            walker = open[min];
            if (walker != null)
                walker = reverseConstruct(walker);
        }
Пример #7
0
 public Tile(Vector2 position, bool isBlocked)
 {
     pos = position;
     blocked = isBlocked;
     pre = null;
     rank = 0;
 }
Пример #8
0
        // Constructs the path in the opposite direction
        private Tile reverseConstruct(Tile src)
        {
            Tile tmp = null;

            while (src != null)
            {
                Tile tmp2 = src.pre;
                src.pre = tmp;
                tmp = src;
                src = tmp2;
            }
            return tmp;
        }
Пример #9
0
        private List<Tile> neighborTiles(Tile source)
        {
            int xCoor, yCoor;
            List<Tile> neighbors = new List<Tile>(); ;

            xCoor = (int)source.pos.X / 19;
            yCoor = (int)source.pos.Y / 19;

            // This A* takes manhattan distance approach,
            // the node can only go in 4 directions
            if (xCoor + 1 <= x - 1 && !world[xCoor + 1, yCoor].blocked)
                neighbors.Add(world[xCoor+1, yCoor]);
            if (xCoor - 1 >= 0 && !world[xCoor - 1, yCoor].blocked)
                neighbors.Add(world[xCoor-1, yCoor]);
            if (yCoor + 1 <= y - 1 && !world[xCoor, yCoor + 1].blocked)
                neighbors.Add(world[xCoor, yCoor + 1]);
            if (yCoor - 1 >= 0 && !world[xCoor, yCoor - 1].blocked)
                neighbors.Add(world[xCoor, yCoor - 1]);

            return neighbors;
        }
Пример #10
0
 // cost from src to dst
 private int movementCost(Tile src, Tile dst)
 {
     return (int)Math.Abs((Math.Abs(src.pos.X - dst.pos.X)
         - Math.Abs(src.pos.Y - dst.pos.Y))/19);
 }
Пример #11
0
 // cost from src to goal
 private int h(Tile src)
 {
     return (int)Math.Abs((Math.Abs(src.pos.X - goalTile.pos.X)
         - Math.Abs(src.pos.Y - goalTile.pos.Y)))/19;
 }
Пример #12
0
 // cost from start to current
 private int g(Tile current)
 {
     return (int)(Math.Abs(startTile.pos.X - current.pos.X)
         + Math.Abs(startTile.pos.Y - current.pos.Y))/19;
     //the sum of x and y coordinate divided by 19, each block is 19 by 19 pixels
 }
Пример #13
0
        protected internal override void Initialize()
        {
            x = graphics.GraphicsDevice.Viewport.Width / 19;
            y = graphics.GraphicsDevice.Viewport.Height / 19;

            world = new Tile[x,y];
            for (int i = 0; i < x; i++)
                for (int j = 0; j < y; j++)
                    world[i, j] = new Tile(new Vector2(i * 19, j * 19), rand.NextDouble() > 1-rateOfBlocks);

            startTile = world[3, 3];
            goalTile = world[x - 4,  y-4];

            open = new List<Tile>();
            close = new List<Tile>();

            stepPos = new Vector2(750, 15);
            robPos = new Vector2(400, 15);

            viewport = new Rectangle(0, 0,
                graphics.GraphicsDevice.Viewport.Width,
                graphics.GraphicsDevice.Viewport.Height);

            fontPos = new Vector2(viewport.Width / 2 - 200,
                    viewport.Height / 2 - 10);

            //msec = 0;
            step = 0;
            path.Clear();
            restartPos = new Vector2(viewport.Width / 2 - 300,
                viewport.Height - 100);

            open.Add(startTile);
            LoadContent();
            //base.Initialize();
            aStar();
        }
Пример #14
0
        protected override void Update(GameTime gameTime)
        {
            if (ServiceHelper.Get<IMouseService>().LeftButtonHasBeenPressed())
            {
                startTile.Color = Color.White;
                startTile = map.TileList[heros.Y, heros.X];
                if (heros.Lastpath != null) // suppression des couleurs sur l'ancien chemin
                {
                    MyNode<Tile> head = heros.Lastpath.Head;
                    while (head != null)
                    {
                        head.Data.Color = Color.White;
                        head = head.NextNode;
                    }
                }
                if (heros.WalkingList != null) // suppression des couleurs sur le chemin si on relance un astar en plein calcul.
                {
                    MyNode<Tile> head = heros.WalkingList.Head;
                    while (head != null)
                    {
                        head.Data.Color = Color.White;
                        head = head.NextNode;
                    }
                }

                mouseX = (int)ServiceHelper.Get<IMouseService>().GetCoordinates().X / 50; // on recupere la case destination
                mouseY = (int)ServiceHelper.Get<IMouseService>().GetCoordinates().Y / 50;

                if (heros.X != mouseX || heros.Y != mouseY)
                {
                    heros.Lastpath.Clear();
                    heros.WalkingList = Pathfinding.CalculatePathWithAStar(map, heros, map.TileList[mouseY, mouseX]);
                }

                if (heros.WalkingList != null && heros.WalkingList.Size != 0)
                {
                    MyNode<Tile> head = heros.WalkingList.Head;

                    startTile.Color = Color.Red;
                    while (head != null)
                    {
                        head.Data.Color = Color.Orange;
                        head = head.NextNode;
                    }
                }
            }
            cost.Update(heros);
            heros.Update(gameTime);

            base.Update(gameTime);
        }