Example usage for org.apache.commons.collections.buffer PriorityBuffer isEmpty

List of usage examples for org.apache.commons.collections.buffer PriorityBuffer isEmpty

Introduction

In this page you can find the example usage for org.apache.commons.collections.buffer PriorityBuffer isEmpty.

Prototype

public boolean isEmpty() 

Source Link

Usage

From source file:de._13ducks.cor.game.server.movement.SectorPathfinder.java

public static synchronized List<Node> findPath(SimplePosition start, SimplePosition target,
        FreePolygon startSector, MovementMap moveMap) {

    if (start == null || target == null) {
        System.out.println("FixMe: SPathfinder, irregular call: " + start + "-->" + target);
        return null;
    }//from w  ww.  j  a va  2  s. c  o  m

    FreePolygon targetSector = moveMap.containingPoly(target.x(), target.y());

    if (targetSector == null) {
        // Ziel ungltig abbrechen
        System.out.println("Irregular target. Aborting");
        return null;
    }
    FakeNode startNode = new FakeNode(start.x(), start.y(), startSector);
    Node targetNode = new FakeNode(target.x(), target.y(), targetSector);
    targetNode.addPolygon(targetSector);

    // Der Startknoten muss die Member seines Polys kennen
    startNode.setReachableNodes(computeDirectReachable(startNode, startSector));
    // Der Zielknoten muss den Membern seines Polys bekannt sein
    // Die Movement-Map darf aber nicht verndert werden. Des halb mssen einige Aufrufe intern abgefangen werden und das reingedoktert werden.
    List<Node> preTargetNodes = Arrays.asList(computeDirectReachable(targetNode, targetSector));

    PriorityBuffer open = new PriorityBuffer(); // Liste fr entdeckte Knoten
    LinkedHashSet<Node> containopen = new LinkedHashSet<Node>(); // Auch fr entdeckte Knoten, hiermit kann viel schneller festgestellt werden, ob ein bestimmter Knoten schon enthalten ist.
    LinkedHashSet<Node> closed = new LinkedHashSet<Node>(); // Liste fr fertig bearbeitete Knoten

    double cost_t = 0; //Movement Kosten (gerade 5, diagonal 7, wird spter festgelegt)

    startNode.setCost(0); //Kosten fr das Startfeld (von dem aus berechnet wird) sind natrlich 0
    open.add(startNode); //Startfeld in die openlist
    containopen.add(startNode);
    targetNode.setParent(null); //"Vorgngerfeld" vom Zielfeld noch nicht bekannt

    for (int j = 0; j < 40000; j++) { //Anzahl der maximalen Durchlufe, bis Wegfindung aufgibt

        if (open.isEmpty()) { //Abbruch, wenn openlist leer ist => es gibt keinen Weg
            return null;
        }

        // Sortieren nicht mehr ntig, PriorityBuffer bewahrt die Felder in der Reihenfolge ihrer Priority - also dem F-Wert auf
        Node current = (Node) open.remove(); //der Eintrag aus der openlist mit dem niedrigesten F-Wert rausholen und gleich lschen
        containopen.remove(current);
        if (current.equals(targetNode)) { //Abbruch, weil Weg von Start nach Ziel gefunden wurde
            targetNode.setParent(current.getParent()); //"Vorgngerfeld" von Ziel bekannt
            break;
        }

        // Aus der open wurde current bereits gelscht, jetzt in die closed verschieben
        closed.add(current);

        List<Node> neighbors = computeNeighbors(current, targetNode, preTargetNodes);

        for (Node node : neighbors) {

            if (closed.contains(node)) {
                continue;
            }

            // Kosten dort hin berechnen
            cost_t = current.movementCostTo(node);

            if (containopen.contains(node)) { //Wenn sich der Knoten in der openlist befindet, muss berechnet werden, ob es einen krzeren Weg gibt

                if (current.getCost() + cost_t < node.getCost()) { //krzerer Weg gefunden?

                    node.setCost(current.getCost() + cost_t); //-> Wegkosten neu berechnen
                    node.setValF(node.getCost() + node.getHeuristic()); //F-Wert, besteht aus Wegkosten vom Start + Luftlinie zum Ziel
                    node.setParent(current); //aktuelles Feld wird zum Vorgngerfeld
                }
            } else {
                node.setCost(current.getCost() + cost_t);
                node.setHeuristic(Math.sqrt(Math.pow(Math.abs((targetNode.getX() - node.getX())), 2)
                        + Math.pow(Math.abs((targetNode.getY() - node.getY())), 2))); // geschtzte Distanz zum Ziel
                //Die Zahl am Ende der Berechnung ist der Aufwand der Wegsuche
                //5 ist schnell, 4 normal, 3 dauert lange

                node.setParent(current); // Parent ist die RogPosition, von dem der aktuelle entdeckt wurde
                node.setValF(node.getCost() + node.getHeuristic()); //F-Wert, besteht aus Wegkosten vom Start aus + Luftlinie zum Ziel
                open.add(node); // in openlist hinzufgen
                containopen.add(node);
            }

        }
    }

    if (targetNode.getParent() == null) { //kein Weg gefunden
        return null;
    }

    ArrayList<Node> pathrev = new ArrayList<Node>(); //Pfad aus parents erstellen, von Ziel nach Start
    while (!targetNode.equals(startNode)) {
        pathrev.add(targetNode);
        targetNode = targetNode.getParent();
    }
    pathrev.add(startNode);

    ArrayList<Node> path = new ArrayList<Node>(); //Pfad umkehren, sodass er von Start nach Ziel ist
    for (int k = pathrev.size() - 1; k >= 0; k--) {
        path.add(pathrev.get(k));
    }

    // Der folgende Algorithmus braucht Polygon-Infos, diese also hier einfgen
    startNode.addPolygon(startSector);
    targetNode.addPolygon(targetSector);

    /**
     * An dieser Stelle muss der Weg nocheinmal berarbeitet werden.
     * Es kann nmlich durch neue Tweaks sein, dass dies die Knoten nicht direkt
     * verbunden sind (also keinen gemeinsamen Polygon haben)
     * Das tritt z.B. bei der Start- und Zieleinsprungpunkt-Variierung auf.
     */
    for (int i = 0; i < path.size() - 1; i++) {
        Node n1 = path.get(i);
        Node n2 = path.get(i + 1);
        FreePolygon commonSector = commonSector(n1, n2);
        if (commonSector == null) {
            // Das hier ist der interessante Fall, die beiden Knoten sind nicht direkt verbunden, es muss ein Zwischenknoten eingefgt werden:
            // Dessen Punkt suchen
            Edge direct = new Edge(n1, n2);
            Node newNode = null;
            // Die Polygone von n1 durchprobieren
            for (FreePolygon currentPoly : n1.getPolygons()) {
                List<Edge> edges = currentPoly.calcEdges();
                for (Edge testedge : edges) {
                    // Gibts da einen Schnitt?
                    SimplePosition intersection = direct.intersectionWithEndsNotAllowed(testedge);
                    if (intersection != null) {
                        // Kandidat fr den nchsten Polygon
                        FreePolygon nextPoly = null;
                        // Kante gefunden
                        // Von dieser Kante die Enden suchen
                        nextPoly = getOtherPoly(testedge.getStart(), testedge.getEnd(), currentPoly);

                        newNode = intersection.toNode();
                        newNode.addPolygon(currentPoly);
                        newNode.addPolygon(nextPoly);
                        break;
                    }
                }
                if (newNode != null) {
                    break;
                }
            }

            if (newNode == null) {
                // Das drfte nicht passieren, der Weg ist legal gefunden worden, muss also eigentlich existieren
                System.out.println("[Pathfinder][ERROR]: Cannot insert Nodes into route, aborting!");
                return null;
            } else {
                path.add(i + 1, newNode);
            }
        }
    }

    return path; //Pfad zurckgeben
}