public DjikstraNodes(Node _node, int _weight) { node = _node; weight = _weight; prevNode = null; visited = false; //leftNode = null; //rightNode = null; //upNode = null; //downNode = null; }
//djisktra hasta un nodo y devuelve el camino public override List <Node> pathToNode(Node targetNode, Node startNode, int limit) { List <DjikstraNodes> unvisited = new List <DjikstraNodes>(); Stack <Node> path = new Stack <Node>(); List <Node> returnlist = new List <Node>(); foreach (Node n in gridMaster.GetComponent <Grid>().grid) { DjikstraNodes dj; if (n.Equals(startNode)) { dj = new DjikstraNodes(n, 0); } else { dj = new DjikstraNodes(n, 9999); } unvisited.Add(dj); } DjikstraNodes searcher; int countYetToVisit = 1; int iteration = 0; while (countYetToVisit > 0 && iteration < limit) { int startIndex = unvisited.FindIndex(x => x.visited == false); searcher = unvisited[startIndex]; foreach (DjikstraNodes dj in unvisited) { if (dj.weight < searcher.weight && !dj.visited) { searcher = dj; } } int searcherIndex = unvisited.FindIndex(x => x.Equals(searcher)); bool inWalkDistance = searcher.node.walkable; if (searcher.weight == 9999) { inWalkDistance = false; } if (inWalkDistance) { if (searcher.node.Equals(targetNode)) { path.Push(searcher.node); DjikstraNodes backwards = searcher.prevNode; while (backwards != null) { path.Push(backwards.node); backwards = backwards.prevNode; } returnlist = new List <Node>(); returnlist.AddRange(path); return(returnlist); } foreach (Node compareThis in searcher.node.getVecinos()) { if (compareThis != null) { int temp = unvisited.FindIndex(x => x.node.Equals(compareThis)); if (unvisited[temp].node.canSphinxCross() && (searcher.weight + 1 < unvisited[temp].weight)) { if (!unvisited[temp].node.isThereAUnitHere()) { unvisited[temp].weight = searcher.weight + 1; unvisited[temp].prevNode = searcher; } else { if (unvisited[temp].node.unitInThisNode.health < UnitPower) { // como la esfinge prioriza al que tenga una reliquia tiende a ignorar caminos mas cortos a travez de unidades //se le dara la opcion de considerar una unidad debil como un camino aceptable unvisited[temp].weight = searcher.weight + 2; unvisited[temp].prevNode = searcher; } } } } } } unvisited[searcherIndex].visited = true; countYetToVisit = 0; foreach (DjikstraNodes dj in unvisited) { if (dj.visited == false) { countYetToVisit++; } } iteration++; } returnlist = new List <Node>(); returnlist.AddRange(path); Debug.Log("didnt find a path to target"); return(returnlist); }
//----------------------------------------------------- PATH FINDING ----------------------------------------------------------- //buscar un camino de nodos desde el nodo actual a donde esta el jugador ------------------------------------------------------- //este metodo hace djikstra desde el target hasta una zona en el espacio de movimiento de este enemigo public override List <Node> pathToUnit(Node targetNode, Node startNode, int limit, bool llegarAlVecino) { List <DjikstraNodes> unvisited = new List <DjikstraNodes>(); Stack <Node> path = new Stack <Node>(); List <Node> returnlist = new List <Node>(); foreach (Node n in gridMaster.GetComponent <Grid>().grid) { DjikstraNodes dj; if (n.Equals(targetNode)) { dj = new DjikstraNodes(n, 0); } else { dj = new DjikstraNodes(n, 9999); } unvisited.Add(dj); } DjikstraNodes searcher; int countYetToVisit = 1; int iteration = 0; while (countYetToVisit > 0 && iteration < limit) { int startIndex = unvisited.FindIndex(x => x.visited == false); searcher = unvisited[startIndex]; foreach (DjikstraNodes dj in unvisited) { if (dj.weight < searcher.weight && !dj.visited) { searcher = dj; } } int searcherIndex = unvisited.FindIndex(x => x.Equals(searcher)); bool inWalkDistance = searcher.node.walkable; if (searcher.node.isHQhere()) { inWalkDistance = true; } if (searcher.weight == 9999) { inWalkDistance = false; } if (inWalkDistance) { if (llegarAlVecino) { if (this.movementRange.Contains(searcher.node) && (!searcher.node.isThereAnEnemyHere() || searcher.node.enemyInThisNode.Equals(this)) && !searcher.node.tiletype.Contains("locked")) { //en este if se debe checkear para nodos en los que el enemigo no puede quedarse pero puede atravezar //ahora que tenemos el nodo disponible mas cercano al target, buscar un camino hasta aquel return(pathToNode(searcher.node, startNode, limit)); } } else { if (this.attackRangeNodes.Contains(searcher.node)) { //ahora que tenemos el nodo disponible mas cercano al target, buscar un camino hasta aquel return(pathToNode(searcher.node, startNode, limit)); } } foreach (Node compareThis in searcher.node.getVecinos()) { if (compareThis != null) { int temp = unvisited.FindIndex(x => x.node.Equals(compareThis)); if (unvisited[temp].node.canSphinxCross() && (searcher.weight + 1 < unvisited[temp].weight)) { if (!unvisited[temp].node.isThereAUnitHere()) { unvisited[temp].weight = searcher.weight + 1; unvisited[temp].prevNode = searcher; } else { if (unvisited[temp].node.unitInThisNode.health < UnitPower) { unvisited[temp].weight = searcher.weight + 2; unvisited[temp].prevNode = searcher; } } } } } } unvisited[searcherIndex].visited = true; countYetToVisit = 0; foreach (DjikstraNodes dj in unvisited) { if (dj.visited == false) { countYetToVisit++; } } iteration++; } returnlist = new List <Node>(); //returnlist.AddRange(path); Debug.Log("didnt find a path to enemy"); return(returnlist); }
//----------------------------------------------------- PATH FINDING ----------------------------------------------------------- //buscar un camino de nodos desde el nodo actual a donde esta el jugador ------------------------------------------------------- public virtual List <Node> pathToAlert(Node targetNode, Node startNode, int limit) { List <DjikstraNodes> unvisited = new List <DjikstraNodes>(); Stack <Node> path = new Stack <Node>(); List <Node> returnlist = new List <Node>(); foreach (Node n in gridMaster.GetComponent <Grid>().grid) { DjikstraNodes dj; if (n.Equals(startNode)) { //Debug.Log ("thats a start"); dj = new DjikstraNodes(n, 0); } else { dj = new DjikstraNodes(n, 9999); } unvisited.Add(dj); } DjikstraNodes searcher; int countYetToVisit = 1; int iteration = 0; //iniciar circlo de busqueda djikstra while (countYetToVisit > 0 && iteration < limit) { int startIndex = unvisited.FindIndex(x => x.visited == false); searcher = unvisited[startIndex]; foreach (DjikstraNodes dj in unvisited) { if (dj.weight < searcher.weight && !dj.visited) { searcher = dj; } } int searcherIndex = unvisited.FindIndex(x => x.Equals(searcher)); //Debug.Log ("-- searcher["+searcherIndex+"] is at x: "+searcher.node.totalWorldPoint().x +" z: "+searcher.node.totalWorldPoint().z ); bool inWalkDistance = searcher.node.walkable; if (searcher.weight == 9999) { inWalkDistance = false; } if (inWalkDistance) { //desde el nodo objetivo leer en reversa y regresar el camino encontrado if (searcher.node.Equals(targetNode)) { //Debug.Log ("found target at "+searcher.totalWorldPoint().x+", "+searcher.totalWorldPoint().y+", "+searcher.totalWorldPoint().z); //Debug.Log ("found it"); path.Push(searcher.node); DjikstraNodes backwards = searcher.prevNode; while (backwards != null) { path.Push(backwards.node); backwards = backwards.prevNode; } returnlist = new List <Node>(); returnlist.AddRange(path); return(returnlist); } foreach (Node compareThis in searcher.node.getVecinos()) { if (compareThis != null) { int temp = unvisited.FindIndex(x => x.node.Equals(compareThis)); if ((!unvisited[temp].node.tiletype.Contains("bloqueado") && !unvisited[temp].node.tiletype.Contains("GuardOnly") && !unvisited[temp].node.tiletype.Contains("locked") && !unvisited[temp].node.tiletype.Contains("sphinxstatue") && !unvisited[temp].node.tiletype.Contains("nest") && !unvisited[temp].node.tiletype.Contains("bottomless")) && (unvisited[temp].node.walkable) && (!unvisited[temp].node.nodeOculto) && (searcher.weight + 1 < unvisited[temp].weight) && !unvisited[temp].node.isThereAnEnemyHere()) { unvisited[temp].weight = searcher.weight + 1; unvisited[temp].prevNode = searcher; } } } } unvisited[searcherIndex].visited = true; countYetToVisit = 0; foreach (DjikstraNodes dj in unvisited) { if (dj.visited == false) { countYetToVisit++; } } //Debug.Log ("countYetToVisit "+countYetToVisit); iteration++; } returnlist = new List <Node>(); returnlist.AddRange(path); return(returnlist); }
//djisktra hasta un nodo y devuelve el camino public virtual List <Node> pathToNode(Node targetNode, Node startNode, int limit) { List <DjikstraNodes> unvisited = new List <DjikstraNodes>(); Stack <Node> path = new Stack <Node>(); List <Node> returnlist = new List <Node>(); foreach (Node n in gridMaster.GetComponent <Grid>().grid) { DjikstraNodes dj; if (n.Equals(startNode)) { dj = new DjikstraNodes(n, 0); } else { dj = new DjikstraNodes(n, 9999); } unvisited.Add(dj); } DjikstraNodes searcher; int countYetToVisit = 1; int iteration = 0; while (countYetToVisit > 0 && iteration < limit) { int startIndex = unvisited.FindIndex(x => x.visited == false); searcher = unvisited[startIndex]; foreach (DjikstraNodes dj in unvisited) { if (dj.weight < searcher.weight && !dj.visited) { searcher = dj; } } int searcherIndex = unvisited.FindIndex(x => x.Equals(searcher)); bool inWalkDistance = searcher.node.walkable; if (searcher.weight == 9999) { inWalkDistance = false; } if (inWalkDistance) { if (searcher.node.Equals(targetNode)) { path.Push(searcher.node); DjikstraNodes backwards = searcher.prevNode; while (backwards != null) { path.Push(backwards.node); backwards = backwards.prevNode; } returnlist = new List <Node>(); returnlist.AddRange(path); return(returnlist); } foreach (Node compareThis in searcher.node.getVecinos()) { if (compareThis != null) { int temp = unvisited.FindIndex(x => x.node.Equals(compareThis)); if (unvisited[temp].node.canEnemyCross() && (searcher.weight + 1 < unvisited[temp].weight) && !unvisited[temp].node.isThereAUnitHere()) { unvisited[temp].weight = searcher.weight + 1; unvisited[temp].prevNode = searcher; } } } } unvisited[searcherIndex].visited = true; countYetToVisit = 0; foreach (DjikstraNodes dj in unvisited) { if (dj.visited == false) { countYetToVisit++; } } iteration++; } returnlist = new List <Node>(); returnlist.AddRange(path); return(returnlist); }