2016-06-02 5 views
1

Ich habe diese Funktion unten findNeighboringChains (i, j) genannt. Sie übergeben einen Punkt (x, y) und geben alle Kettenobjekte zurück, die in den benachbarten Punkten (x + 1, y), (x - 1, y), (x, y + 1) und (x, y - 1). Wenn keine Kette bei (x, y) existiert, dann findChainId (x, y) = -1, andernfalls wird eine ID> = 0 zurückgegeben. Nur eine Kette kann an jedem (x, y) existieren. Für mehr Kontext ist dies eine Funktion, die ich verwende, um benachbarte Ketten zu einer Zelle im Spiel Go zu finden.Wie man über Ordinalrichtungen über einen Punkt (x, y) iteriert?

Ich fühle mich wie das, was ich bis jetzt habe, ist etwas wortreich, aber ich bin nicht sicher, wie man es besser macht. Es scheint, als wäre es ideal, wenn ich über diese Punkte (x + 1, y) ... (x, y - 1) durch eine Schleife iterieren könnte. Irgendwelche Vorschläge?

public ArrayList<Integer> findNeighboringChains(int i, int j) { 
    ArrayList<Integer> neighboringChains = new ArrayList<>(); 

    int tmp = findChainId(i - 1, j); 
    if (tmp != -1) { 
     neighboringChains.add(tmp); 
    } 

    tmp = findChainId(i + 1, j); 
    if (tmp != -1) { 
     neighboringChains.add(tmp); 
    } 

    tmp = findChainId(i, j - 1); 
    if (tmp != -1) { 
     neighboringChains.add(tmp); 
    } 

    tmp = findChainId(i, j + 1); 
    if (tmp != -1) { 
     neighboringChains.add(tmp); 
    } 

    return neighboringChains; 
} 
+1

siehe http://stackoverflow.com/questions/1240643/a-question-of-design-and-object-verantwortung und http://stackoverflow.com/a/1240759/82118 –

+0

Vielen Dank für Ihren Kommentar, seine Richtung Enum ist sehr nützlich – CowZow

Antwort

2

Eine Möglichkeit wäre, das Point-Objekt zu verwenden, die in Java gebaut wird, und iterieren eine Liste aller Punkte- Zeit, um das gleiche Stück Code aufrufen. In meiner Lösung/Refactoring erstelle ich eine neue Methode namens "getNeighboringPoints (Point p)", die die vier benachbarten Punkte abruft. Dann können Sie in Ihrer Funktion findNeighboringChains mit einer for-each-Schleife über diese Liste von Punkten iterieren.

Es gibt viele Variationen über diese Art von Mustern, die Sie tun könnten, aber Sie haben definitiv Recht zu denken, dass es möglich ist, weniger redundant zu sein. Es ist immer eine gute Idee, dem DRY-Prinzip zu folgen.

public ArrayList<Integer> findNeighboringChains(int i, int j) { 
    ArrayList<Integer> neighboringChains = new ArrayList<>(); 

    Point p = new Point(i, j); 
    List<Point> neighboringPoints = getNeighboringPoints(p); 

    for (Point point : neighboringPoints) { 
     int tmp = findChainId(point.x, point.y); 
     if (tmp != -1) { 
      neighboringChains.add(tmp); 
     } 
    } 

    return neighboringChains; 
} 

/** 
* 
* @param p 
*   The input point. 
* @return a list of points neighboring point p 
*/ 
private List<Point> getNeighboringPoints(Point p) { 
    ArrayList<Point> neighboringPoints = new ArrayList<Point>(); 
    neighboringPoints.add(new Point(p.x - 1, p.y)); 
    neighboringPoints.add(new Point(p.x + 1, p.y)); 
    neighboringPoints.add(new Point(p.x, p.y + 1)); 
    neighboringPoints.add(new Point(p.x, p.y - 1)); 
    return neighboringPoints; 
} 

Einer der Vorteile des oben genannten Verfahrens ist jetzt können Sie später feststellen, dass Sie eine andere Operation auf allen benachbarten Punkten möglicherweise tun müssen, und Sie können die Methode getNeighboringPoints Wiederverwendung().

Edit:

Eine weitere Möglichkeit, um Redundanz zu reduzieren wäre, die extract method Technik zu verwenden.

public ArrayList<Integer> findNeighboringChains(int i, int j) { 
    ArrayList<Integer> neighboringChains = new ArrayList<>(); 

    int tmp = findChainId(i - 1, j); 
    checkChain(neighboringChains, tmp); 

    tmp = findChainId(i + 1, j); 
    checkChain(neighboringChains, tmp); 

    tmp = findChainId(i, j - 1); 
    checkChain(neighboringChains, tmp); 

    tmp = findChainId(i, j + 1); 
    checkChain(neighboringChains, tmp); 

    return neighboringChains; 
} 

private void checkChain(ArrayList<Integer> neighboringChains, int tmp) { 
    if (tmp != -1) { 
     neighboringChains.add(tmp); 
    } 
} 

Dies ist möglicherweise besser, da die Verwendung der Punktklasse in einem Projekt, das bereits keine Punkte verwendet, nicht erzwungen wird. (Es kann ärgerlich sein, wenn es eine Methode gibt, die Punkte verwendet, bei denen alles andere die Eingabe von zwei Eingaben erfordert).

+0

Danke für die Antwort. Ihre Lösung und Carl Manasters Kommentar oben haben mir sehr geholfen – CowZow