Moin,
Ich bin 15 Jahre alt und lerne nun seit etwa 1/2 Jahr programmieren. Heute habe ich eine Coding Challenge im Internet gefunden. Bei der ging es darum, dass man aus einem 2d Array, welches eine Map repräsentiert, einen Weg zu einem Ziel findet. Besser verständlich:
T für Spieler (Startposition)
C für Ziel
# für Wand (man kann diese nicht überqueren)
. für Weg (hier kann man lang gehen)
Map:
##########
#T########
# . ########
# . #######
# . ########
# . ########
# . ########
# . ########
# . . . . . . . C#
##########
Das ist jetzt nur ein Beispiel. Die Mapgröße lässt sich variieren. Es kann auch mehrere Wege geben, welche zum Ziel führen, allerdings wird dann nicht der Kürzere gefunden sondern es wird ein Beliebiger gefunden (Wenn es einen Weg gibt, der rechts vom Spieler anfängt wird immer dieser gefunden). Das einzige Kriterium was gegeben sein muss ist, dass es keinen Weg gibt, welcher ins Nichts führt. Das der kürzere Weg gefunden wird und dass es auch Wege gibt die ins Nichts führen möchte ich demnächst noch implementieren.
So jetzt kommen wir jedenfalls mal zu meinem Code.
Die Main-Klasse:
Die Coordinate Klasse:
Und als Letztes die CoordinateComparator Klasse:
Vielleicht hat ja jemand mal Lust sich das ganze durchzulesen und mir Verbesserungsvorschläge zu geben. Ich möchte immer möglichst sauberen Code schreiben und da meine Lösung wahrscheinlich nicht gerade optimal ist würde ich mich freuen, wenn mir jemand mit Verbesserungsvorschlägen zu einer schöneren Lösung verhelfen würde.
Danke für eure Antworten!
Ich bin 15 Jahre alt und lerne nun seit etwa 1/2 Jahr programmieren. Heute habe ich eine Coding Challenge im Internet gefunden. Bei der ging es darum, dass man aus einem 2d Array, welches eine Map repräsentiert, einen Weg zu einem Ziel findet. Besser verständlich:
T für Spieler (Startposition)
C für Ziel
# für Wand (man kann diese nicht überqueren)
. für Weg (hier kann man lang gehen)
Map:
##########
#T########
# . ########
# . #######
# . ########
# . ########
# . ########
# . ########
# . . . . . . . C#
##########
Das ist jetzt nur ein Beispiel. Die Mapgröße lässt sich variieren. Es kann auch mehrere Wege geben, welche zum Ziel führen, allerdings wird dann nicht der Kürzere gefunden sondern es wird ein Beliebiger gefunden (Wenn es einen Weg gibt, der rechts vom Spieler anfängt wird immer dieser gefunden). Das einzige Kriterium was gegeben sein muss ist, dass es keinen Weg gibt, welcher ins Nichts führt. Das der kürzere Weg gefunden wird und dass es auch Wege gibt die ins Nichts führen möchte ich demnächst noch implementieren.
So jetzt kommen wir jedenfalls mal zu meinem Code.
Die Main-Klasse:
Java:
public final class Main {
private boolean wayFound;
private final char[][] map = { { '#', '#', '#', '#', '#', '#', '#', '#', '#', '#' },
{ '#', 'T', '#', '.', '.', '.', '.', '.', '.', '#' },
{ '#', '.', '#', '#', '#', '#', '#', '#', '.', '#' },
{ '#', '.', '#', '#', '#', '#', '#', '#', '.', '#' },
{ '#', '.', '#', '#', '#', '#', '#', '#', '.', '#' },
{ '#', '.', '#', '#', '#', '#', '#', '#', '.', '#' },
{ '#', '.', '#', '#', '.', '.', '.', '#', '.', '#' },
{ '#', '.', '#', '#', '.', '#', '.', '#', '.', '#' },
{ '#', '.', '.', '.', '.', '#', '.', '.', 'C', '#' },
{ '#', '#', '#', '#', '#', '#', '#', '#', '#', '#' } };
private ArrayList<Coordinate> way = new ArrayList<>();
public static void main(String[] args) {
new Main().getWay();
}
private void getWay() {
Coordinate playerPosition = null;
Coordinate destinationPosition = null;
ArrayList<Coordinate> walkable = new ArrayList<>();
for(int i = 0; i < map.length; i++) {
for(int a = 0; a < map[i].length; a++) {
if(map[i][a] == '.')
walkable.add(new Coordinate(a + 1, i + 1));
else if(map[i][a] == 'T')
playerPosition = new Coordinate(a + 1, i + 1);
else if(map[i][a] == 'C')
destinationPosition = new Coordinate(a + 1, i + 1);
}
}
walkable.sort(new CoordinateComparator());
if(playerPosition == null || destinationPosition == null)
throw new IllegalArgumentException("The map does not contain a player or a destination");
way.add(playerPosition);
//1 = up; 2 = right; 3 = down; 4 = left;
int wayDirection = 0;
findWay(walkable, playerPosition, destinationPosition, wayDirection);
System.out.println(Arrays.toString(way.toArray()));
}
private void findWay(ArrayList<Coordinate> walkable, Coordinate playerPosition, Coordinate destinationPosition, int wayDirection) {
for(int i = 0; i < walkable.size(); i++) {
Coordinate walkableCoordinate = walkable.get(i);
Coordinate previousWayCoordinate = way.get(way.size() - 1);
if(way.contains(walkable.get(i)))
continue;
if(walkableCoordinate.getX() == previousWayCoordinate.getX() - 1 && wayDirection != 2 && walkableCoordinate.getY() == previousWayCoordinate.getY()) {
wayDirection = 4;
way.add(walkable.get(i));
} else if(walkableCoordinate.getX() == previousWayCoordinate.getX() + 1 && wayDirection != 4 && walkableCoordinate.getY() == previousWayCoordinate.getY()) {
wayDirection = 2;
way.add(walkable.get(i));
} else if(walkableCoordinate.getY() == previousWayCoordinate.getY() - 1 && wayDirection != 3 && walkableCoordinate.getX() == previousWayCoordinate.getX()) {
wayDirection = 1;
way.add(walkable.get(i));
} else if(walkableCoordinate.getY() == previousWayCoordinate.getY() + 1 && wayDirection != 1 && walkableCoordinate.getX() == previousWayCoordinate.getX()) {
wayDirection = 3;
way.add(walkable.get(i));
} else if((previousWayCoordinate.getX() == destinationPosition.getX() - 1 && previousWayCoordinate.getY() == destinationPosition.getY()) ||
(previousWayCoordinate.getX() == destinationPosition.getX() + 1 && previousWayCoordinate.getY() == destinationPosition.getY()) ||
(previousWayCoordinate.getY() == destinationPosition.getY() - 1 && previousWayCoordinate.getX() == destinationPosition.getX()) ||
(previousWayCoordinate.getY() == destinationPosition.getY() + 1 && previousWayCoordinate.getX() == destinationPosition.getX())) {
wayFound = true;
way.add(destinationPosition);
return;
}
if(i == walkable.size() - 1)
findWay(walkable, playerPosition, destinationPosition, wayDirection);
}
}
}
Java:
public class Coordinate {
private int x, y;
public Coordinate(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Override
public String toString() {
return x + "," + y;
}
}
Java:
public class CoordinateComparator implements Comparator<Coordinate>{
@Override
public int compare(Coordinate arg0, Coordinate arg1) {
if (arg0.getY() < arg1.getY()) {
return -1;
} else if (arg0.getY() > arg1.getY()) {
return 1;
} else {
if (arg0.getX() < arg1.getX()) {
return -1;
} else if (arg0.getX() > arg1.getX()) {
return 1;
}
return 0;
}
}
}
Vielleicht hat ja jemand mal Lust sich das ganze durchzulesen und mir Verbesserungsvorschläge zu geben. Ich möchte immer möglichst sauberen Code schreiben und da meine Lösung wahrscheinlich nicht gerade optimal ist würde ich mich freuen, wenn mir jemand mit Verbesserungsvorschlägen zu einer schöneren Lösung verhelfen würde.
Danke für eure Antworten!