예제 #1
0
파일: LevelData.cs 프로젝트: spayne/ZenGame
    Queue <CellCoord> MakeShortestPath(CellCoord start, CellCoord end)
    {
        // breadth first search
        Queue <CellCoord> open_q = new Queue <CellCoord>();

        // node 2 distanceandparentmap cell coord and how I got there
        Dictionary <CellCoord, DistanceAndParent> visited = new Dictionary <CellCoord, DistanceAndParent>();

        open_q.Enqueue(start);
        visited[start] = new DistanceAndParent(0, start);
        CellCoord current = new CellCoord();

        while (open_q.Count > 0)
        {
            current = open_q.Dequeue();

            if (current == end)
            {
                break;
            }
            // otherwise walk each neighbor and add any accessible ones
            int current_distance = visited[current].distance;

            List <CellCoord> connected = GetConnectedList(current);

            foreach (CellCoord tentative in connected)
            {
                if (!visited.ContainsKey(tentative) && AreConnected(current, tentative))
                {
                    visited[tentative] = new DistanceAndParent(current_distance + 1, current);
                    open_q.Enqueue(tentative);
                }
            }
        }

        if (current == end)
        {
            // todo: make path
            Stack <CellCoord> backwards_path = new Stack <CellCoord>();

            backwards_path.Push(end);

            DistanceAndParent cur = visited[end];
            while (cur.distance > 1)
            {
                backwards_path.Push(cur.parent);
                cur = visited[cur.parent];
            }

            return(new Queue <CellCoord>(backwards_path.ToArray()));
        }
        else
        {
            return(null);
        }
    }
예제 #2
0
 public DistanceAndParent(int distance, DistanceAndParent parent)
 {
     this.distance = distance;
     this.parent   = parent;
 }
예제 #3
0
 public void SetParent(DistanceAndParent parent)
 {
     this.parent = parent;
 }
예제 #4
0
    /// <summary>
    /// Fonction permettant de trouver et afficher un chemin d'un point A à un point B
    /// Seuls les cases sur lesquelles on est sûrs de pouvoir aller sont ajoutées
    /// <param name="deplacement">Valeur de déplacement d'un personnage</param>
    /// <param name="saut">Valeur de saut d'un personnage</param>
    /// <param name="positionBloc">Position du bloc de départ, c'est à dire celui SOUS le personnage</param>
    /// <returns>Retourne une grille qui permet d'avoir les positions de chacun des blocs du chemin, c'est à dire les blocs appartenant au SOL. Le personnage se déplacera une case au dessus</returns>
    /// </summary>
    public DistanceAndParent[,,] CanGo(LivingPlaceable livingPlaceable, int saut, Vector3Int positionBloc)
    {
        int deplacement = livingPlaceable.PmActuels;



        for (int x = 0; x < sizeX; x++)
        {
            for (int y = 0; y < sizeY; y++)
            {
                for (int z = 0; z < sizeZ; z++)
                {
                    gridBool[x, y, z] = new DistanceAndParent(x, y, z);
                }
            }
        }

        Queue <Vector3Int> queue = new Queue <Vector3Int>();

        queue.Enqueue(positionBloc);
        DistanceAndParent parent = null;

        gridBool[positionBloc.x, positionBloc.y, positionBloc.z].SetDistance(0);
        while (parent == null || ((parent.GetDistance() <= deplacement) && queue.Count != 0))
        {
            //On mets ceux à coté, ceux au dessus accessibles ou ceux en dessous accessibles
            //coté

            Vector3Int posBlocActuel = queue.Dequeue();


            parent = gridBool[posBlocActuel.x, posBlocActuel.y, posBlocActuel.z];
            if (parent.GetDistance() <= deplacement)
            {
                Placeable testa = Grid[posBlocActuel.x, posBlocActuel.y, posBlocActuel.z];
                if (testa.gameObject.GetComponent <Renderer>() != null)
                {
                    //On envoie plutot l'id parce que rien n'assure que les blocs soient a la bonne position coté client
                    gameManager.PlayingPlaceable.Joueur.RpcMakeCubeBlue(testa.netId);
                }
                //là mettre l'affichage du bloc en bleu
                for (int yactuel = -saut + 1; yactuel < saut; yactuel++)
                {
                    if (posBlocActuel.y + yactuel >= 0 && posBlocActuel.y + yactuel < sizeY && posBlocActuel.x < sizeX - 1 && //au dessus de 0, en dessous du max, dans le terrain en x
                        gridBool[posBlocActuel.x + 1, posBlocActuel.y + yactuel, posBlocActuel.z].GetDistance() == -1 &&      //si on l'a pas dejà vu
                        Grid[posBlocActuel.x + 1, posBlocActuel.y + yactuel, posBlocActuel.z] != null &&                      // et si le bloc existe
                        (Grid[posBlocActuel.x + 1, posBlocActuel.y + yactuel + 1, posBlocActuel.z] == null || //si le bloc au dessus est vide
                         Grid[posBlocActuel.x + 1, posBlocActuel.y + yactuel + 1, posBlocActuel.z].TraversableChar == TraversableType.ALLTHROUGH || //ou traversable en général
                         Grid[posBlocActuel.x + 1, posBlocActuel.y + yactuel + 1, posBlocActuel.z].TraversableChar == TraversableType.ALLIESTHROUGH &&   //ou seulement par un allié
                         Grid[posBlocActuel.x + 1, posBlocActuel.y + yactuel + 1, posBlocActuel.z].Joueur == livingPlaceable.Joueur) && //si on est l'allié
                        Grid[posBlocActuel.x + 1, posBlocActuel.y + yactuel, posBlocActuel.z].Walkable
                        )
                    {//si le sommet n'est pas marqué et qu'il existe, et qu'il n'y a rien au dessus ou que celui du dessus est traversable, que le bloc est walkable
                        queue.Enqueue(new Vector3Int(posBlocActuel.x + 1, posBlocActuel.y + yactuel, posBlocActuel.z));
                        gridBool[posBlocActuel.x + 1, posBlocActuel.y + yactuel, posBlocActuel.z].SetDistance(
                            parent.GetDistance() + 1);
                        gridBool[posBlocActuel.x + 1, posBlocActuel.y + yactuel, posBlocActuel.z].SetParent(parent);
                    }

                    if (posBlocActuel.y + yactuel >= 0 && posBlocActuel.y + yactuel < sizeY && posBlocActuel.x > 0 &&
                        gridBool[posBlocActuel.x - 1, posBlocActuel.y + yactuel, posBlocActuel.z].GetDistance() == -1 &&
                        Grid[posBlocActuel.x - 1, posBlocActuel.y + yactuel, posBlocActuel.z] != null &&
                        (Grid[posBlocActuel.x - 1, posBlocActuel.y + yactuel + 1, posBlocActuel.z] == null ||
                         Grid[posBlocActuel.x - 1, posBlocActuel.y + yactuel + 1, posBlocActuel.z].TraversableChar == TraversableType.ALLTHROUGH ||
                         Grid[posBlocActuel.x - 1, posBlocActuel.y + yactuel + 1, posBlocActuel.z].TraversableChar == TraversableType.ALLIESTHROUGH &&
                         Grid[posBlocActuel.x - 1, posBlocActuel.y + yactuel + 1, posBlocActuel.z].Joueur == livingPlaceable.Joueur) &&
                        Grid[posBlocActuel.x - 1, posBlocActuel.y + yactuel, posBlocActuel.z].Walkable)
                    {//si le sommet n'est pas marqué et qu'il existe, et qu'il n'y a rien au dessus
                        queue.Enqueue(new Vector3Int(posBlocActuel.x - 1, posBlocActuel.y + yactuel, posBlocActuel.z));
                        gridBool[posBlocActuel.x - 1, posBlocActuel.y + yactuel, posBlocActuel.z].SetDistance(
                            parent.GetDistance() + 1);
                        gridBool[posBlocActuel.x - 1, posBlocActuel.y + yactuel, posBlocActuel.z].SetParent(parent);
                    }
                    if (posBlocActuel.y + yactuel >= 0 && posBlocActuel.y + yactuel < sizeY && posBlocActuel.z < sizeZ - 1 &&
                        gridBool[posBlocActuel.x, posBlocActuel.y + yactuel, posBlocActuel.z + 1].GetDistance() == -1 &&
                        Grid[posBlocActuel.x, posBlocActuel.y + yactuel, posBlocActuel.z + 1] != null &&
                        (Grid[posBlocActuel.x, posBlocActuel.y + yactuel + 1, posBlocActuel.z + 1] == null ||
                         Grid[posBlocActuel.x, posBlocActuel.y + yactuel + 1, posBlocActuel.z + 1].TraversableChar == TraversableType.ALLTHROUGH ||
                         Grid[posBlocActuel.x, posBlocActuel.y + yactuel + 1, posBlocActuel.z + 1].TraversableChar == TraversableType.ALLIESTHROUGH &&
                         Grid[posBlocActuel.x, posBlocActuel.y + yactuel + 1, posBlocActuel.z + 1].Joueur == livingPlaceable.Joueur) &&
                        Grid[posBlocActuel.x, posBlocActuel.y + yactuel, posBlocActuel.z + 1].Walkable)

                    {//si le sommet n'est pas marqué et qu'il existe et qu'il n'y a rien au dessus
                        queue.Enqueue(new Vector3Int(posBlocActuel.x, posBlocActuel.y + yactuel, posBlocActuel.z + 1));
                        gridBool[posBlocActuel.x, posBlocActuel.y + yactuel, posBlocActuel.z + 1].SetDistance(
                            parent.GetDistance() + 1);
                        gridBool[posBlocActuel.x, posBlocActuel.y + yactuel, posBlocActuel.z + 1].SetParent(parent);
                    }
                    if (posBlocActuel.y + yactuel >= 0 && posBlocActuel.y + yactuel < sizeY && posBlocActuel.z > 0 &&
                        gridBool[posBlocActuel.x, posBlocActuel.y + yactuel, posBlocActuel.z - 1].GetDistance() == -1 &&
                        Grid[posBlocActuel.x, posBlocActuel.y + yactuel, posBlocActuel.z - 1] != null &&
                        (Grid[posBlocActuel.x, posBlocActuel.y + yactuel + 1, posBlocActuel.z - 1] == null ||
                         Grid[posBlocActuel.x, posBlocActuel.y + yactuel + 1, posBlocActuel.z - 1].TraversableChar == TraversableType.ALLTHROUGH ||
                         Grid[posBlocActuel.x, posBlocActuel.y + yactuel + 1, posBlocActuel.z - 1].TraversableChar == TraversableType.ALLIESTHROUGH &&
                         Grid[posBlocActuel.x, posBlocActuel.y + yactuel + 1, posBlocActuel.z - 1].Joueur == livingPlaceable.Joueur) &&
                        Grid[posBlocActuel.x, posBlocActuel.y + yactuel, posBlocActuel.z - 1].Walkable)
                    {//si le sommet n'est pas marqué et qu'il existe, et qu'il n'y a rien au dessus
                        queue.Enqueue(new Vector3Int(posBlocActuel.x, posBlocActuel.y + yactuel, posBlocActuel.z - 1));
                        gridBool[posBlocActuel.x, posBlocActuel.y + yactuel, posBlocActuel.z - 1].SetDistance(
                            parent.GetDistance() + 1);
                        gridBool[posBlocActuel.x, posBlocActuel.y + yactuel, posBlocActuel.z - 1].SetParent(parent);
                    }
                }
            }
        }

        return(gridBool);
    }