commit fc9c8c6695edeaf7636739411e7ba07b8df1b61f Author: juniemoon Date: Mon Feb 10 01:18:15 2025 +0100 Manual, Escape und Snakes fertig - Rumble fehlt noch diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f68d109 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..2928d94 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..d114499 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/NOTES.txt b/NOTES.txt new file mode 100644 index 0000000..a90d498 --- /dev/null +++ b/NOTES.txt @@ -0,0 +1,51 @@ +• Wie wird im Client IP-Nummer und Port des Servers festgelegt? Können diese ggf. geändert werden ohne das Programm neu kompilieren zu müssen? + + +- IP-Adresse und der Port des Servers werden in einer Konfigurationsdatei festgelegt. + + +======================================================================================= + + +• Wie ist die im Sequenzdiagramm eingezeichnete Schleife "loop" im Programmcode realisiert? Wann bricht diese Schleife ab? + + +- "loop" wird im Code wahrscheinlich als while- oder for-Schleife realisiert +- wird verwendet, um wiederholt Daten vom Server zu lesen und darauf zu reagieren (z. B. Eingaben verarbeiten und Aktionen ausführen) +- Abbruch der Schleife: Die Schleife bricht ab, wenn eine bestimmte Bedingung erfüllt ist, z. B. wenn: + - der Server das Programm beendet (Verbindungsabbruch) + - eine spezielle Nachricht oder ein Befehl vom Server empfangen wird (z. B. quit") + - ein interner Zustand erreicht wird (z. B. Ziel erreicht oder Fehlermeldung) + + +======================================================================================= + + +• Wie ist die Methode "nextMove()" implementiert? Was bedeutet das Schlüsselwort "abstract"? + + +- Methode "nextMove()" wird in der Klasse "Bot" abstrakt definiert, das bedeutet, dass sie keine eigene Implementierung hat und in einer Unterklasse überschrieben werden muss +- "abstract" wird verwendet, um sicherzustellen, dass jede Unterklasse ihre eigene spezifische Version dieser Methode bereitstellt + + +======================================================================================= + + +• Analysieren Sie die "Inner Class" mit dem Namen "View". Sofern Sie nicht wissen, +was eine "Inner Class" oder "Nested Class" ist, googeln Sie bitte den Begriff und machen Sie sich die Bedeutung klar. Wie speichert "View" den "Scan"? + + +"Inner Class" = eine Klasse, die innerhalb einer anderen Klasse definiert wird. Sie wird verwendet, um logischen Bezug zur umgebenden Klasse (hier "Bot") herzustellen und auf deren Attribute oder Methoden direkt zuzugreifen. +- "View" repräsentiert hier den "Scan" des Rovers und speichert wahrscheinlich Daten wie Sensormessungen oder Positionen + + +======================================================================================= + + +• Betrachten Sie die Zugriffsmodifikatoren public, private und protected. Verschaffen Sie sich einen Überblick, welche Attribute und Methoden in einer möglichen Unterklasse von "Bot" zur Verfügung stünden. + + +- protected: Attribute und Methoden mit protected sind in der Unterklasse verfügbar und können innerhalb der Unterklasse und deren weiteren Unterklassen verwendet werden. + + + diff --git a/Torus-III-Projekt.iml b/Torus-III-Projekt.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/Torus-III-Projekt.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/Bot$View.class b/src/Bot$View.class new file mode 100644 index 0000000..2de1b9a Binary files /dev/null and b/src/Bot$View.class differ diff --git a/src/Bot.class b/src/Bot.class new file mode 100644 index 0000000..efa20ef Binary files /dev/null and b/src/Bot.class differ diff --git a/src/Bot.java b/src/Bot.java new file mode 100644 index 0000000..40d782a --- /dev/null +++ b/src/Bot.java @@ -0,0 +1,71 @@ +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.net.InetSocketAddress; + +public abstract class Bot { + + private final String host; // Hostname oder IP-Adresse des Servers + private final int port; // Port des Servers + + protected Bot(String[] args) { + host = args.length > 0 ? args[0] : "localhost"; + port = args.length > 1 ? Integer.parseInt(args[1]) : 63187; + } + + // Diese Methode stellt die Verbindung zum Server her und startet die Kommunikation + protected void run() { + try (Socket socket = new Socket()) { + socket.connect(new InetSocketAddress(host, port)); + OutputStream out = socket.getOutputStream(); + BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + View view = new View(); + while (true) { + view.read(in); + view.print(); + try { + char ch = nextMove(view); + out.write(ch); // Sende Zug an Server + } + catch (Exception e) { break; } + } + socket.close(); + } catch (IOException e) { + System.err.println("Error: " + e.getMessage()); + } + } + + // Diese Methode ermittelt den nächsten Zug des Bots. Sie wird von der run-Methode aufgerufen + abstract protected char nextMove(View view) throws Exception; + + // Diese Klasse repräsentiert das Spielfeld + public static class View { + protected String data; + protected int width; + + private void read(BufferedReader in) throws IOException { + StringBuilder sb = new StringBuilder(); + data = in.readLine(); + if (data == null) { + return; + } + sb.append(data); + width = data.length(); + for (int i = 1; i < width; ++i) { + sb.append(in.readLine()); + } + data = sb.toString(); + } + + protected void print() { + if (data == null || width < 1) { + return; + } + for (int i = 0, len = data.length(); i < len; i += width) { + System.out.println(data.substring(i, i + width)); + } + } + } +} diff --git a/src/EscapeBot.class b/src/EscapeBot.class new file mode 100644 index 0000000..84baf32 Binary files /dev/null and b/src/EscapeBot.class differ diff --git a/src/EscapeBot.java b/src/EscapeBot.java new file mode 100644 index 0000000..1632691 --- /dev/null +++ b/src/EscapeBot.java @@ -0,0 +1,88 @@ +public class EscapeBot extends Bot { + + //Rechts,Unten,Links,Oben + enum Direction { + Right, + Down, + Left, + Up + } + //5 nach rechts, 5 nach unten, 10 nach links, 10 hoch, 15 nach rechts und 15 nach unten + int[] dx = {3,0,6,0}; + int[] dy = {0,3,0,6}; + char[] Commands = {'>','v','<','^'}; + Direction CurrentDirection = Direction.Right; + int StepsToGoUntilNextEvaluation = 3; + int Start = StepsToGoUntilNextEvaluation; + int NextIncrement = StepsToGoUntilNextEvaluation *2; + boolean first_time = true; + public EscapeBot(String[] args) { + super(args); // Konstruktor von Elternklasse Bot + } + + @Override + protected char nextMove(View view) throws Exception { + int rocketIndex = view.data.indexOf('o'); + int X_Rocket = 0; + int Y_Rocket = 0; + + if(first_time) { + first_time = false ; + return this.Commands[Direction.Right.ordinal()]; + + } + if(-1 != rocketIndex) { + Y_Rocket = rocketIndex / view.width; + X_Rocket = rocketIndex % view.width; + + //System.out.println("X_Rocket: " + X_Rocket + " Y_Rocket: " + Y_Rocket); + + if(2 != Y_Rocket) { + return (2 > Y_Rocket ) ? this.Commands[Direction.Up.ordinal()] : this.Commands[Direction.Down.ordinal()]; + } + + if(X_Rocket != 2) { + return (2>X_Rocket) ? this.Commands[Direction.Left.ordinal()] : this.Commands[Direction.Right.ordinal()]; + } + } + else if(0 < this.StepsToGoUntilNextEvaluation) { + //System.out.println("CurrentDirection:" + this.CurrentDirection.toString() + " StepsToGo: " + this.StepsToGoUntilNextEvaluation); + StepsToGoUntilNextEvaluation--; + return this.Commands[Direction.Up.ordinal()]; + } + else if (0 == this.StepsToGoUntilNextEvaluation){ + switch(this.CurrentDirection) { + case Direction.Right: + dx[Direction.Right.ordinal()]+= this.NextIncrement; + this.CurrentDirection = Direction.Down; + StepsToGoUntilNextEvaluation = this.dy[Direction.Down.ordinal()]; + break; + case Direction.Down: + dy[Direction.Down.ordinal()] += this.NextIncrement; + this.CurrentDirection = Direction.Left; + StepsToGoUntilNextEvaluation = this.dx[Direction.Left.ordinal()]; + break; + case Direction.Left: + dx[Direction.Left.ordinal()] += this.NextIncrement; + this.CurrentDirection = Direction.Up; + StepsToGoUntilNextEvaluation = this.dy[Direction.Up.ordinal()]; + break; + case Direction.Up: + dy[Direction.Up.ordinal()] += this.NextIncrement; + this.CurrentDirection = Direction.Right; + StepsToGoUntilNextEvaluation = this.dx[Direction.Right.ordinal()]; + break; + } + this.Start = StepsToGoUntilNextEvaluation; + return this.Commands[Direction.Right.ordinal()]; + } + + throw new Exception("This Line should not be reacher!!"); + + } + + public static void main(String[] args) { + EscapeBot escapeBot = new EscapeBot(args); + escapeBot.run(); + } +} \ No newline at end of file diff --git a/src/Main.java b/src/Main.java new file mode 100644 index 0000000..d5f06b8 --- /dev/null +++ b/src/Main.java @@ -0,0 +1,5 @@ +public class Main { + public static void main(String[] args) { + System.out.printf("Hello and welcome!"); + } +} \ No newline at end of file diff --git a/src/ManualBot.class b/src/ManualBot.class new file mode 100644 index 0000000..fdaded3 Binary files /dev/null and b/src/ManualBot.class differ diff --git a/src/ManualBot.java b/src/ManualBot.java new file mode 100644 index 0000000..8b2b95e --- /dev/null +++ b/src/ManualBot.java @@ -0,0 +1,36 @@ +import java.util.Scanner; + +public class ManualBot extends Bot { + public ManualBot(String[] args) { + super(args); + } + + @Override + protected char nextMove(View view) throws Exception { + Scanner scanner = new Scanner(System.in); + System.out.print("Gib einen Steuerbefehl ein (W-A-S-D / Q=Quit): "); + + String input = scanner.nextLine(); + switch (input) { + case "w": + return '^'; + case "s": + return 'v'; + case "a": + return '<'; + case "d": + return '>'; + case "q": + System.out.println("Verbindung wird beendet."); + System.exit(0); + default: + System.out.println("Ungültiger Befehl. Bitte versuche es erneut."); + return nextMove(view); // rekursiver Aufruf für nächste Eingabe + } + } + + public static void main(String[] args) { + ManualBot manualBot = new ManualBot(args); + manualBot.run(); + } +} \ No newline at end of file diff --git a/src/SnakeBot.java b/src/SnakeBot.java new file mode 100644 index 0000000..ed20622 --- /dev/null +++ b/src/SnakeBot.java @@ -0,0 +1,73 @@ +import java.util.List; +import java.util.ArrayList; +import java.awt.Point; + +public class SnakeBot extends Bot { + + List tail = new ArrayList<>(); // speichert Positionen der Schlange + Point currentPos = new Point(2, 2); // Startposition des Bots + + public SnakeBot(String[] args) { + super(args); + } + + @Override + protected char nextMove(View view) throws Exception { + int stoneIndex = view.data.indexOf('@'); + + // falls Stein in Sicht + if (stoneIndex != -1) { + int stoneY = stoneIndex / view.width; + int stoneX = stoneIndex % view.width; + + if (stoneY < 2) return move('^'); + if (stoneY > 2) return move('v'); + if (stoneX < 2) return move('<'); + if (stoneX > 2) return move('>'); + } + + return move(safeDirection(view)); + } + + private char move(char direction) { + int newX = currentPos.x, newY = currentPos.y; + if (direction == '^') newY--; + if (direction == 'v') newY++; + if (direction == '<') newX--; + if (direction == '>') newX++; + + // Bot soll nicht in sich selbst laufen + if (tail.contains(new Point(newX, newY))) { + return safeDirection(null); // falls gefährlich, neue Richtung wählen + } + + // Erst aktualisieren, wenn sichergestellt ist, dass die Bewegung sicher ist + currentPos.setLocation(newX, newY); + tail.add(new Point(newX, newY)); + return direction; + } + + private char safeDirection(View view) { + if (isSafeMove('^')) return '^'; + if (isSafeMove('>')) return '>'; + if (isSafeMove('v')) return 'v'; + if (isSafeMove('<')) return '<'; + + return '>'; + } + + private boolean isSafeMove(char move) { + int newX = currentPos.x, newY = currentPos.y; + if (move == '^') newY--; + if (move == 'v') newY++; + if (move == '<') newX--; + if (move == '>') newX++; + + return !tail.contains(new Point(newX, newY)) && !currentPos.equals(new Point(newX, newY)); + } + + public static void main(String[] args) { + SnakeBot snakeBot = new SnakeBot(args); + snakeBot.run(); + } +}