private LinkedList<Nodo> construirCaminoConPredecesores(Nodo current) { // Tengamos en cuenta que en esta lista hay tuplas(x,y,z), x,y son las // posiciones en el plano z, que indica, la cantidad de powerup disponible. // Haciendo la resta entre el valor level de dos nodos v->w, se calcula el // powerup utilizado para dicho salto entre v y w // Definamos powerUpUsado(u,v) = level(v) - level(u) // Asumamos que powerUpUsado(null, v) = 0; // powerUpInicial - level(destino) te da la cantidad de powerUp usado total y // level(destino) la cantidad de powerup disponible al salir del laberinto. LinkedList<Nodo> camino = new LinkedList<Nodo>(); // armo una lista de nodos que indican el camino de origen a destino. // como tengo el predecesor para cada nodo, puedo ir de atras hacia adelante encadenandolo. Nodo nodo = current; while (damePredecesor(nodo) != null) { Nodo predecesor = damePredecesor(nodo); nodo.setLevel(predecesor.getLevel() - nodo.getLevel()); camino.addFirst(nodo); // avanzo en el camino nodo = predecesor; } nodo.setLevel(0); camino.addFirst(nodo); return camino; }
/** * Sea un nodo v(i,j,k) sus alcanzables directos son los nodos w de la forma (a, b, k) / ((i-c <= * a <= i+c) && (b==j)) || ((j-c <= b <= j+c) && (a==i)) && c = potencia(v) ahora , sea l una * variable que mueve en el rango [1..k] los nodos t de la forma (a, b, l) / ((a = i-c) || (a = * i+c) && (b==j)) || ((b = j-c) || (b = j+c) && (a==i)) && c = potencia(v) + l * * @param nodo * @param nodoValue * @return */ private List<Nodo> calcularAlcanzables(Nodo nodo, int nodoValue, int dimensionMatriz) { int currentLevel = nodo.getLevel(); int currentX = nodo.getX(); int currentY = nodo.getY(); int potenciaIntrinseca = nodoValue; LinkedList<Nodo> alcanzables = new LinkedList<Nodo>(); // armo los alcanzables directo for (int j = -potenciaIntrinseca; j <= potenciaIntrinseca; j++) { // validacion de bordes y que no sea el mismo if (validarBordes(dimensionMatriz, currentX, j)) { Nodo alcanzableDirecto = new Nodo(currentX + j, currentY, currentLevel); alcanzables.add(alcanzableDirecto); } // validacion de bordes y que no sea el mismo if (validarBordes(dimensionMatriz, currentY, j)) { Nodo alcanzableDirecto = new Nodo(currentX, currentY + j, currentLevel); alcanzables.add(alcanzableDirecto); } } // adiciono los alcanzables indirectos que surgen de utilizas unidadesDePowerUpAdicionadas // unidades de powerup for (int unidadesDePowerUpAdicionadas = 1; unidadesDePowerUpAdicionadas <= currentLevel; unidadesDePowerUpAdicionadas++) { int potenciaTotal = potenciaIntrinseca + unidadesDePowerUpAdicionadas; if (potenciaTotal > dimensionMatriz) { // fix para complejidad, de esta forma es O(dimension) todo el metodo. // si potenciaTotal > dimensionMatriz, validarBordes va a dar false, asi que ni hace falta // revisarlas // veamos que como potenciaIntrinseca > 0 para cualquier nodo, entonces si // unidadesDePowerUpAdicionadas > n-1 // entonces potenciaTotal > dimensionMatriz lo cual no tiene sentido, porque se podria // saltar por fuera de los limites de la matriz break; } if (validarBordes(dimensionMatriz, currentY, potenciaTotal)) { Nodo alcanzableIndirecto = new Nodo( currentX, currentY + potenciaTotal, currentLevel - unidadesDePowerUpAdicionadas); alcanzables.add(alcanzableIndirecto); } if (validarBordes(dimensionMatriz, currentY, -potenciaTotal)) { Nodo alcanzableIndirecto = new Nodo( currentX, currentY - potenciaTotal, currentLevel - unidadesDePowerUpAdicionadas); alcanzables.add(alcanzableIndirecto); } if (validarBordes(dimensionMatriz, currentX, potenciaTotal)) { Nodo alcanzableIndirecto = new Nodo( currentX + potenciaTotal, currentY, currentLevel - unidadesDePowerUpAdicionadas); alcanzables.add(alcanzableIndirecto); } if (validarBordes(dimensionMatriz, currentX, -potenciaTotal)) { Nodo alcanzableIndirecto = new Nodo( currentX - potenciaTotal, currentY, currentLevel - unidadesDePowerUpAdicionadas); alcanzables.add(alcanzableIndirecto); } } return alcanzables; }