public int Seleccionado(dim Posicion, eCasilla estado) { matriz[(int)Posicion.x, (int)Posicion.y] = estado; if ((int)estado > 2) //Es uno de los coches { if (Seleccion_ == (Seleccion)((int)estado - 2)) { Seleccion_ = Seleccion.none; } else { Seleccion_ = (Seleccion)((int)estado - 2); pSeleccion_.Set(Posicion.x, Posicion.y); } } else if (estado == eCasilla.bloqueado && Seleccion_ != Seleccion.none) { Seleccion_ = Seleccion.none; } Fondo.color = colores[(int)Seleccion_]; return((int)(Seleccion_) - 1); }
///Este es el método que resuelve el problema y devuelve una lista con todas las casillas por las que tiene que pasar ///desde el origen hasta el destino, utilizando el algoritmo A* public Resolutor(eCasilla[,] estado, dim posOrigen, dim posDestino) { //Este será el camino que rellenaremos al final camino = new List <dim>(); tablero = new Nodo[10, 10]; estados = estado; destino = posDestino; origen = posOrigen; //Cola de prioridad para los nodos adyacentes no checkeados //Lista con los nodos ya vistos y por los que no hay que volver a pasar List <Nodo> aCheckear = new List <Nodo>(); //List<Nodo> aCheckear = new List<Nodo>(); List <Nodo> vistos = new List <Nodo>(); CrearNodos(); //Cogemos la casilla inicial y se mete a la lista de no chequeados Nodo inicio = tablero[origen.x, origen.y]; inicio.padre = inicio; inicio.G = inicio.g = 0; inicio.F = inicio.G + inicio.H; aCheckear.Add(inicio); bool encontrado = false; while (aCheckear.Count > 0 && !encontrado) { //Cogemos el nodo de menor F de la lista, lo quitamos de ella y lo metemos en los ya checkeados int pos = 0; int valorMax = 10000000; for (int i = 0; i < aCheckear.Count; i++) { if (aCheckear[i].F < valorMax) { valorMax = aCheckear[i].F; pos = i; } } Nodo actual = aCheckear[pos]; // Nodo actual = aCheckear.Dequeue(); aCheckear.Remove(actual); vistos.Add(actual); //Se miran los adyacentes y se les coloca el nodo actual como padre //se les pone como valor G su valor actual sumado al de su padre y se calcula su nuevo F foreach (Pair <int, int> dir in dirs) { //Comprobamos si el adyacente está en el tablero dim nuevaPos = new dim(); nuevaPos.Set(actual.Posicion.x + dir.First, actual.Posicion.y + dir.Second); if (dentroTablero(nuevaPos)) { //Comprobamos si el adyacente ya está entre los vistos if (!vistos.Contains(tablero[nuevaPos.x, nuevaPos.y])) { //Comprobamos si el adyacente es una casilla bloqueada if (tablero[nuevaPos.x, nuevaPos.y].noPasar == true) { vistos.Add(tablero[nuevaPos.x, nuevaPos.y]); } //Si no lo es, calculamos sus nuevos valores y lo metemos en la lista de pendientes else { //Comprobamos si es nuestro destino y si no, seguimos if (isGoal(nuevaPos)) { encontrado = true; tablero[nuevaPos.x, nuevaPos.y].padre = actual; } else { //Miramos si es un camino menos costoso que el anterior int nuevoG = actual.G + tablero[nuevaPos.x, nuevaPos.y].g; if (nuevoG < tablero[nuevaPos.x, nuevaPos.y].G && aCheckear.Contains(tablero[nuevaPos.x, nuevaPos.y])) { tablero[nuevaPos.x, nuevaPos.y].G = nuevoG; tablero[nuevaPos.x, nuevaPos.y].padre = actual; } else if (!aCheckear.Contains(tablero[nuevaPos.x, nuevaPos.y])) { tablero[nuevaPos.x, nuevaPos.y].padre = actual; } tablero[nuevaPos.x, nuevaPos.y].F = tablero[nuevaPos.x, nuevaPos.y].G + tablero[nuevaPos.x, nuevaPos.y].H; aCheckear.Add(tablero[nuevaPos.x, nuevaPos.y]); } } } } } } if (encontrado) { calculaCamino(); } else { imposible = true; } }