Eine Methode um zu testen ob es ein Nachbar gibt?
Hallo, ich muss bei meiner Aufgabe die Klasse Field um eine Methode boolean hasNeighbor(int, int, int) erweitern, sodass die ersten Parameter x- und y-Koordinaten sind und der dritte Parameter die Richtung. Die Methode soll zurückgeben ob es an der übergebenen Stelle, in die Richtung eine Verbindung zum Nachbarn gibt. Aber das schwierige ist, dass es ohne Schleife oder Verzweigung aus der erstellten getNeighborhood Methode mit Bitoperationen bestimmt werden muss. Ich hoffe jemand kann mir helfen, da ich noch ein Anfänger bin.
class Field
{
/**
* Die Dateinamen der Bodengitterelemente, die direkt mit einer
* Rotation 0 verwendet werden können. Der Index ergibt sich
* aus der Summe der folgenden Zahlen:
* 1: In Richtung 0 (+1, 0) gibt es eine Verbindung.
* 2: In Richtung 1 (0, +1) gibt es eine Verbindung.
* 4: In Richtung 2 (-1, 0) gibt es eine Verbindung.
* 8: In Richtung 3 (0, -1) gibt es eine Verbindung.
*/
private static final String[] NEIGHBORHOOD_TO_FILENAME = {
"grass",
"path-e-0",
"path-e-1",
"path-l-0",
"path-e-2",
"path-i-0",
"path-l-1",
"path-t-1",
"path-e-3",
"path-l-3",
"path-i-1",
"path-t-0",
"path-l-2",
"path-t-3",
"path-t-2",
"path-x"
};
/**
* Die Feldbeschreibung. Jede zweite Spalte und Zeile enthält die
* eigentlichen Zellen. Dazwischen sind die Nachbarschaften
* vermerkt.
*/
private final String[] field;
Field(final String[] field)
{
this.field = field;
for (int y = 0; y < field.length; y += 2) {
for (int x = 0; x < field[y].length(); x += 2) {
new GameObject(x / 2, y / 2, 0, NEIGHBORHOOD_TO_FILENAME[getNeighborhood(x, y)]);
}
}
}
private char getCell(final int x, final int y)
{
if (x >= 0 && y >= 0 && y < field.length && x < field[y].length()) {
return field[y].charAt(x);
}
else {
return ' ';
}
}
private int getNeighborhood(final int x, final int y)
{
// Die (x, y)-Versätze für die einzelnen Prüfrichtungen
final int[][] neighbors = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
int neighborhood = 0;
int bit = 1;
for (final int[] offsets : neighbors) {
if (getCell(x + offsets[0], y + offsets[1]) != ' ') {
neighborhood += bit;
}
bit *= 2;
}
return neighborhood;
}
static void test()
{
new GameObject.Canvas(5, 5, 96, 96);
new Field(new String[] {
"O-O-O-O ",
"| | ",
"O O-O-O O",
"| | | | |",
"O-O-O-O-O",
"| | | | |",
"O O-O-O O",
" | |",
"O-O-O-O-O"
});
}
}
1 Antwort
die Methode sieht ähnlich aus wie getNeighborhood(). Allerdings brauchst Du nicht alle 4 Richtungen untersuchen, sondern nur die gewünschte richtung[dir] (wenn dir der dritte Parameter ist).
Also machst Du entweder eine Kopie von getNeighborhood() und wirfst alles unnötige raus:
private boolean getNeighborhood(final int x, final int y, final int dir)
{
final int[][] neighbors = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
final int[] offset = neighbors[dir];
return getCell(x + offsets[0], y + offsets[1]) != ' ');
}
oder du rufst dort getNeighborhood() auf und prüfst, ob deren Rückgabe das dir-Bit gesetzt hat:
private boolean getNeighborhood(final int x, final int y, final int dir)
{
return getNeighborhood(x, y) & (1<<dir) != 0;
}
„Field.field[]“ ist etwas verunglückt:
- Die eckigen Klammern sind völlig fehl am Platz. Das Feld heißt einfach nur „field“.
- „field“ ist kein statisches Feld. Deshalb grauchst Du ein konkretes Objekt vom Typ „Field“, um darauf zuzugreifen. Etwa so:
static void test()
{
new GameObject.Canvas(5, 5, 96, 96);
Field myField = new Field(new String[] { ... };
if (myField.field.length == maxSteps) { ...
Das scheitert in einer anderen Klasse aber daran, dass field private ist (was auch gut so ist). Du könntest Field um eine Methode erweitern:
public int getHeight()
{
return field.length;;
}
und die dann in der anderen klasse verwenden.
Also ich weiß nicht ob ich etwas falsch gemacht habe, aber mit beiden Beispielen funktioniert es trotzdem nicht, weil es eine non-static Methode sei.
Klar, denn jede Instanz von Field hat ihre eigene Feldgröße. Du mußt deshalb die Instanz und nicht die Klasse danach fragen:
field myfield = new Field( ... );
if ( myField.getHeight() == maxSteps )
Dies ist ja dann in der Field-Klasse oder nicht? Soll ich dann das maxSteps public sein?
Sorry das ich dich so nerve, hier es steht aber auch dann bei der if anweisung in der Klasse Field, das die npc Methoden non-static sind
Nur getHeight() ist in der Klasse Field. Du sagtest aber, dass Du in einer anderen Klasse mit so einem Field-Objekt arbeiten willst. Dazu brauchst Du dort eine Variable vom Typ Field, für die Du dann getHeight() und alle anderen non-static-Methoden aufrufen kannst.
Also entweder übergibst Du Deiner Methode, die die NPCs erzeugt, das Field, in dem sie herumlaufen, oder Du legst im Konstruktor dieser anderen Klasse eine solche Variable an.
Danke für deine Antwort, nur es wird ein Error angezeigt ich denke es wäre ohne & (1<<dir) richtig oder ?
Mein Fehler: & bindet schwächer als !=. Du brauchst also Klammern.
Das "& (1<<dir)" ist nötig, weil getNeighborhood() nur eine Zahl zwischen 0 und 15 liefert. Du musst testen, ob das passende Bit gesetzt ist.
Hallo nochmal, du konntest mir echt am meisten Helfen. Dafür auch nochmal danke! Ich hatte da eine kleine Frage. Unzwar müsste ich die String länge nun in einer anderen Klasse ermitteln und NPCs erzeugen, die sich um +2 rotieren, wenn das Ende des Feldes erreicht wurde. mit dem Code funktioniert das aber nicht da bei Field.field[].length ein Error kommt mit class expected bei .length.