public void associar(Tile visinho) { if (visinho != null && !visinhos.Contains(visinho)) { visinhos.Add(visinho); visinho.visinhos.Add(this); } }
public Tile(Tile copy) { this.x = copy.x; this.y = copy.y; this.egasto = copy.egasto; this.distancia = copy.distancia; this.pai = copy.pai; this.visinhos = copy.visinhos; }
public PathFinder(Texture2D redMap) { col = redMap.Width; lin = redMap.Height; Color[] retrievedColor = new Color[col * lin]; redMap.GetData<Color>(0, new Rectangle(0, 0, col, lin), retrievedColor, 0, retrievedColor.Length); tilemap = new Tile[col][]; for (int i = 0; i < col; i++) { tilemap[i] = new Tile[lin]; for (int j = 0; j < lin; j++) { tilemap[i][j] = new Tile(i, j); } } start = null; Tile end = null; for (int i = 0; i < col; i++) { for (int j = 0; j < lin; j++) { if (retrievedColor[j * col + i].PackedValue != (uint)4278190080) { if (i > 0) { tilemap[i][j].associar(tilemap[i - 1][j]); if (j > 0) { tilemap[i][j].associar(tilemap[i - 1][j - 1]); } if (j < lin - 1) { tilemap[i][j].associar(tilemap[i - 1][j + 1]); } } if (j > 0) { tilemap[i][j].associar(tilemap[i][j - 1]); } if (retrievedColor[j * col + i].R == 255 && retrievedColor[j * col + i].G == 0 && retrievedColor[j * col + i].B == 0) { end = tilemap[i][j]; } if (retrievedColor[j * col + i].R == 0 && retrievedColor[j * col + i].G == 0 && retrievedColor[j * col + i].B == 255) { start = tilemap[i][j]; } /** start - 4294901760 vermelho end - 4278190335 azul ????? - 4278255360 verde */ } else { tilemap[i][j] = null; } } } Console.WriteLine(">" + (start == null)); Console.WriteLine(">" + (end == null)); if (start != null && end != null) { setTarget(start.x, start.y, end.x, end.y); } }
//usa linked list e deixa lista ordenada para agilizar procura do melhor caminho private void organizaEadiciona(Tile pai) { List<Tile> naoOrganizados = pai.visinhos; bool notInserted;//escolhido.getEgasto()+1, (int)(Point.distance(escolhido.getX(),escolhido.getY()-1, xAlvo,yAlvo) LinkedListNode<Tile> node; Tile aOrganizar; for (int i = 0; i < naoOrganizados.Count; i++) { notInserted = true; aOrganizar = naoOrganizados[i]; if (!utilizados.Contains(aOrganizar) && !emEspera.Contains(aOrganizar)) { aOrganizar.pai = pai; if (rndN != 1) { aOrganizar.egasto = pai.egasto + rnd.Next(rndN); } else { aOrganizar.egasto = pai.egasto + 1; } aOrganizar.distancia = alvo.calculaDistancia(aOrganizar); node = emEspera.First; while (node != null) { if (aOrganizar.distancia + aOrganizar.egasto < node.Value.distancia + node.Value.egasto) { notInserted = false; emEspera.AddBefore(node, aOrganizar); break; } node = node.Next; }; if (notInserted) { emEspera.AddLast(aOrganizar); } } } }
//usar quando tem os Tiles ou quando não é um mapa quadrado public void setTarget(Tile startTile, Tile endTile) { utilizados = new List<Tile>(); emEspera = new LinkedList<Tile>(); startTile.pai = null; startTile.egasto = 0; startTile.distancia = startTile.calculaDistancia(endTile); emEspera.AddFirst(startTile); melhorcaminho = startTile; alvo = endTile; concluido = false; caminhoInexistente = false; }
public void setTarget(int xStart, int yStart, int xEnd, int yEnd) { utilizados = new List<Tile>(); emEspera = new LinkedList<Tile>(); start = tilemap[xStart][yStart]; Tile endTile; try { endTile = tilemap[xEnd][yEnd]; } catch (Exception e) { endTile = null; } if (endTile == null) { endTile = start; } start.pai = null; start.egasto = 0; start.distancia = start.calculaDistancia(endTile); emEspera.AddFirst(start); melhorcaminho = start; alvo = endTile; concluido = false; caminhoInexistente = false; }
public List<Tile> procuraMenorCaminho(int nroNodos) { if (emEspera.Count > 0) { List<Tile> result = new List<Tile>(); int nroAtual = 0; Tile escolhido = null; //0, 0, Int64.MaxValue, Int64.MaxValue, null while (emEspera.Count > 0 && nroNodos > nroAtual) { nroAtual++; escolhido = emEspera.First.Value; emEspera.RemoveFirst(); if (melhorcaminho.distancia > escolhido.distancia) { melhorcaminho = escolhido; } if (escolhido.equals(alvo)) { concluido = true; break; } organizaEadiciona(escolhido); utilizados.Add(escolhido); } if (emEspera.Count == 0) { caminhoInexistente = true; } do { result.Insert(0, melhorcaminho); melhorcaminho = melhorcaminho.pai; } while (melhorcaminho != null); melhorcaminho = escolhido; //extra, para verificar caminho escolhido /* Console.WriteLine(""); int count = 0; for (int i = 0; i < col; i++) { String s = ""; for (int j = 0; j < lin; j++) { if (tilemap[i][j] == null) { s += "[X]"; } else if (result.Contains(tilemap[i][j])) { count++; s += "[o]"; } else { s += "[ ]"; } } Console.WriteLine(s); } */ return result; } else { /* Console.WriteLine(""); for (int i = 0; i < col; i++) { String s = ""; for (int j = 0; j < lin; j++) { if (tilemap[i][j] == null) { s += "[X]"; } else { s += "[ ]"; } } Console.WriteLine(s); }*/ concluido = true; return new List<Tile>(); } }
public PathFinder(int[][] map) { col = map.Length; lin = map[0].Length; tilemap = new Tile[col][]; //criando um Tilemap completo for (int i = 0; i < col; i++) { tilemap[i] = new Tile[lin]; for (int j = 0; j < lin; j++) { tilemap[i][j] = new Tile(i, j); } } //ligando tiles para pathfind e eliminando tiles onde não há caminho for (int i = 0; i < col; i++) { for (int j = 0; j < lin; j++) { //se o número do mapa é menor que 1, o campo está livre //se o número do mapa é maior que 0, o campo está ocupado com a barreira de tipo igual ao número //se o número do mapa é igual a -1, o campo está reservado por alguma regra como bandeira ou pontos if (map[i][j] < 1) { if (i > 0) { tilemap[i][j].associar(tilemap[i - 1][j]); //barreiras do tipo container não possibilitam andar diagonal ao seu lado //checando por container de cima if (map[i - 1][j] < 10) { //checando por container a esquerda if (j > 0 && map[i][j - 1] < 10) { tilemap[i][j].associar(tilemap[i - 1][j - 1]); } //checando por container a direita if (j < lin - 1 && map[i][j + 1] < 10) { tilemap[i][j].associar(tilemap[i - 1][j + 1]); } } } if (j > 0) { tilemap[i][j].associar(tilemap[i][j - 1]); } } else { tilemap[i][j] = null; } } } }
public PathFinder(Tile[][] map) { col = map.Length; lin = map[0].Length; tilemap = map; }
public bool equals(Tile obj) { return obj.x == x && obj.y == y; }
public double calculaDistancia(Tile other) { return Math.Sqrt(((x - other.x) * (x - other.x)) + ((y - other.y) * (y - other.y))); }