From fc9c8c6695edeaf7636739411e7ba07b8df1b61f Mon Sep 17 00:00:00 2001 From: juniemoon Date: Mon, 10 Feb 2025 01:18:15 +0100 Subject: [PATCH] Manual, Escape und Snakes fertig - Rumble fehlt noch --- .gitignore | 29 ++++++++++++++ .idea/.gitignore | 8 ++++ .idea/misc.xml | 6 +++ .idea/modules.xml | 8 ++++ .idea/vcs.xml | 6 +++ NOTES.txt | 51 ++++++++++++++++++++++++ Torus-III-Projekt.iml | 11 ++++++ src/Bot$View.class | Bin 0 -> 1170 bytes src/Bot.class | Bin 0 -> 2302 bytes src/Bot.java | 71 ++++++++++++++++++++++++++++++++++ src/EscapeBot.class | Bin 0 -> 996 bytes src/EscapeBot.java | 88 ++++++++++++++++++++++++++++++++++++++++++ src/Main.java | 5 +++ src/ManualBot.class | Bin 0 -> 1385 bytes src/ManualBot.java | 36 +++++++++++++++++ src/SnakeBot.java | 73 +++++++++++++++++++++++++++++++++++ 16 files changed, 392 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 NOTES.txt create mode 100644 Torus-III-Projekt.iml create mode 100644 src/Bot$View.class create mode 100644 src/Bot.class create mode 100644 src/Bot.java create mode 100644 src/EscapeBot.class create mode 100644 src/EscapeBot.java create mode 100644 src/Main.java create mode 100644 src/ManualBot.class create mode 100644 src/ManualBot.java create mode 100644 src/SnakeBot.java 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 0000000000000000000000000000000000000000..2de1b9ae4a2871727746fc85cc93ea00297c021a GIT binary patch literal 1170 zcmZuwT~8B16g|^jSXvfazLA1}qLxxX1o@CJErK@T!-&E7=0XQtEZe5L6-|8fm*4}> z7%7P+K5F8x@CWz@G$@{FD~R=F?wy%)?>+b2nJ>TIe*_T6-2i;h4Cp2*P$>}FvYuN5 zDa+X$SYF$b>z+X6r0v+=w15`rSv624(0mG7@v^qF8PD0Nq|63jKntK6rhyt0=MWTV zDq!vOKs>jxA+s|1Kw5+fRAuQb*p3uvi1aM{n{vXBTGSb+H_?Db!sBVLd)1aZ0(#Q& zEP=Z67)7AjL<`Q7ww1|9Cn?YuDF>F+I-B0pf*uLQ zvdhFpToS0*v6JdtBovR!Cax#}s=RbD(vJvw3`9-zB6c?OOV^XzOqkA5@5UlsN_L;x zdJLA(3UgOerWZ_hMaUJUi{U z2Kb;(SS6NEZYX1cl|W!6oy)Gvd0W*}^8$C26Dl;yh8 zB|G&{(8byK_{x3I)f=Lxt3lCfU>Q_$9p$c_R?t>N4ep`F777BR^c2tqqTivi<^|Ktan zc&s`VnBqEf(&a05tnp@A5&MK{MM>W!Wo@!Vbt>Gpi>|l0s`lZq0zAp1FOR{ZKe>1O z^^|HWGlThqxJ9aQbYPZ*XQ Aj{pDw literal 0 HcmV?d00001 diff --git a/src/Bot.class b/src/Bot.class new file mode 100644 index 0000000000000000000000000000000000000000..efa20ef8e1757d04ae2a9a816ba88bdb86dffe40 GIT binary patch literal 2302 zcmaJ?TUQfT6#fpGFk~DHhKqvLqM{7}rPbC_VlRdYrcFQ%MX9|F$q^!9CY?+`s=ePY zYxT8Hed<~~+ojMYYuWd{_DA#|bgjOWerF~Lagp|6=3MqZ-`@M%`|R`kKMx)PNa9-q zEePq*OoY)Y&~ejRu||rPy)ZI8e^cf>f!1>cyWqVj5Q+`XwxLZRQgm`wanUJz5g6E` z!!)rMk5MD(@PMWy0@3siR@QS1_Cmry2lnZRn&?EAz`h-Yl%4ABYSSBjFA8#kmY^H-#mm#&VJ0=+d^%C6%DV&&tAiKp%Dk_#Z&MKwn1Uh$=0<(-&$MZ}bvp+CfkgEnp z5mLW%CSCw5M`O%+ff`%8;_}%V#mgqnt0D}SSS`$)fpHVB-~yp-dCSW|Y3%@?JC%a}3oI%esRmCt7@rIIQn$tY_i`r!2wK1tVVXk;KYT{j%T z8@R6HO%re7?MLolcCGA5R!c~_yc^y1>|9a=1*OCUUd6j6EX)fS%zB1?SPP7{tCn%! zlj;?W^4jN3NZepaEL%%*+_7_(ceUUxa#r>%+bav4XmSav_1Xw#U=al!H%%;|*brNT zd%P`vHjDOuTxc@b6T9Bzrc!D0o%Lr&NUq?3t2fQmSlIt0U<+UfFZ4Qbu}< zPQKiRJ5;~mx{f>6FWOu2p@EO^v5rp^$Daxe>=atTUU8P>NZ>?3`-GMA9CuCN$40`d zih+rXmYpxk@<7^gmMW#hZlW4?9yvI(R+3HB8)*t!e4;V4Rfut`Sj_UyBm~S9o1Hse zv{>GxKvOqd$Cm=fcZJr>V;x@$9R7b*J~Bag+7Vv*7M5rWqUuTEEULOZ#}G93pJfQx zT>Zec(i@6zLd1t2{)EU-==3_mQT;w5+|Yi8Ii#Kb742%X`#yT^QoRKZ|4~AL@EQ$t zqn*92110W^LEGlEMTeo|JqV85v{zdPWBE#xZPJ1YS_9`qmX5X(@B1zE&28fG^w1U# z&BgE0v3uy*#1k7hI<$cknJvWUwlF-$#i>o4-o&$0TNve$u`#VzJGp^GueO1g;_9C~ z8y@ZsZ(w45`_HlPIzl`&rM`7^W`Z#?HOw>F;orEG{sjv5od?JP8(6qY4=35Mt|5&! zHj71eumb5UaRhGRHoHi`&II;xr;A$MIEWtfV?WL?3Fp`zliZo)V>yk(#Oi0iI!df# zMC&5PaiSc<9X^uZ;e^j<3XyFd4Ev1s>6p|J*ZDB0c9$mEOm-krWMAHfuHI^rPu0u* zR`_p-q>iiYnx&QhS2=H?;kD}CDBkC+jnWVJ-Nt8JMX51LL!TppFYpz< GLGQoYLpU}7 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..84baf32a2667fe71ba919cd0f7a7f2f8047ab7fc GIT binary patch literal 996 zcmZWnTTc^V5ItXSdvRN8p&$ZUuC^4YSG*KR0E;%3s(=_YFZ@+2zcjgM<6g|TBb82 z&>4T7d#g9}R7tlsQ_D`(v^LX;RRuB>395z*&;(>Q4Xv8Sj)1SIJGwyRe3yz4+9ZTE zTtq}5{6DOKWLiaI_vr>v;@L!2LWe;6X<25sU{oB_wq$gY*^<6(I7ZAe3tLWX)7Yr9 z+3Hu(j!W)ax&@-~^DK_I_h{%vpMZbIEIL~PBCFskViNi_3}EmqySCK==qYDA`RIy^Q?ewC z2`HIbL9ZB;Q$-S9*Q7LD#|{3zTDNH9iB-xoZx;=Lww!4h`FeTXsIKViC1zyH*mV}| z2HjvhcRZDJVxIA`qZhUp^~%3e^+e7Z0n55cbamOTR}031>0*UWxJGJjuSKE<==$Evo6Dt{)=`=Cwd!VB*Gfju#JDeUuE;%l zk1>cmhVUH2c!?3b;+S>b7LmXG>cn@l(kZh0&dT^hy2M>_usS;0SGzH}^x*oyC literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..fdaded340a9b8629e5919a0e7584f8596d3244a5 GIT binary patch literal 1385 zcmZuxU2hvj6g^|Fy|%k?+@uK!<{q@}s0IJwb zA%dt5%|HxsfoQew3&a;~$M&xZOlCi--?#RxQqOX_rH1d?PPdY4>PQHj3?~BL?v)yC z%Wijx9U+5dIP zHPsH|22Npuq4ooY`jqSzgF7Zm;01xwO}k}E+mVjh@MR#~mi$C+_0*7=y<1o+Gz! zUf@(V_g@)PIDP&_$%iCJ+cgPUU=4uJ#1jN2tH*erP3QUyT4XmE` zuW;5|_hs9!ry4bONVq?%Qt1Y)R>Kq+e88 zTsE+vgwVqy_nZ{PUo>z9EDTK^*i=Ew)^g1Rt_c+GINcw=@A-CDx@I*Lx@cBy-(sg8@=&M-PaoxZTtOz7mEr;g_YcG^-wZF$hk7Vl{nrqr}zmi*4Yoh8^ zGw>eXrzUQ|YN9et2J%>@QKk1%eKJGxZA;Z{s?iVJwp_6lZ~95dMO7yPMonFT<(}nvk_pjN)RIAw@(`n|4=^@1 zImFcYAzoQ4ENGE(Y+4&)_G|im9$!8T^bfJmRO| z7fj+;j{e4y{T-+A2e0oMSIoiq8@CbHQPr`oL)USJe*uj0F=iutPK4@cRR04cmGe=4 wiqu'; + 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(); + } +}