Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sheet3 review #157

Merged
merged 9 commits into from
Oct 2, 2023
78 changes: 43 additions & 35 deletions sheets/3/exercise-1.tex
Original file line number Diff line number Diff line change
Expand Up @@ -3,83 +3,91 @@
\begin{enumerate}
\item Instanziiere die Simulation wie bekannt (\lstinline{Sheet3Task1} und \lstinline{Sheet3Task1Verifier}) und mache dich mit dieser vertraut.
\item Probiere Neo mithilfe einer While-Schleife 10 Schritte laufen zu lassen.\\

\end{enumerate}


\begin{Infobox}[For-Schleife]
In Java kann man neben der While-Schleife auch eine For-Schleife benutzen.
Mit einer For-Schleife kann man genau bestimmen wie oft der Code in der Schleife ausgeführt wird.
Anstatt dieselbe Operation n-mal untereinander zu schreiben, um sie n-mal auszuführen, kann man den Code einmal in eine For-Schleife schreiben, die n-mal ausgeführt wird.
Dazu verwenden wir eine For-Schleife.
Mit einer For-Schleife kann man genau bestimmen wie oft der Code in der Schleife ausgeführt wird.\newline

\begin{lstlisting}[numbers=none]
//here neo moves five times
neo.move();
neo.move();
neo.move();
neo.move();
neo.move();
\end{lstlisting}

ist equivalent zu:
Anstatt eine Sequenz von Operationen $n$-mal untereinander zu schreiben, um sie $n$-mal auszuführen, kann man den repetitiven Code einmal in den Rumpf eine For-Schleife schreiben.
Im \enquote{Kopf} der for-Schleife kann man dann angeben, wie oft der Schleifenrumpf ausgeführt werden soll.\newline

Hier ein Beispiel:

\begin{lstlisting}[numbers=none]
//this moves neo five times
for (Integer i = 0; i < 5; i++) {
// Move neo five times
neo.move();
}
neo.move();
neo.move();
neo.move();
neo.move();
// entspricht
for (int i = 0; i < 5; i++) {
neo.move();
}
\end{lstlisting}

Wie die While-Schleife hat auch die For-Schleife einen Schleifenrumpf, der mehrfach ausgeführt wird.
Der Inhalt der runden Klammern \lstinline{()} unterscheidet sich aber deutlich von dem einer While-Schleife.
Der Inhalt der runden Klammern \lstinline{(int i = 0; i < 5; i++)} unterscheidet sich aber deutlich von dem einer While-Schleife.\newline

In den runden Klammern einer For-Schleife stehen insgesamt drei Anweisungen, die jeweils durch ein Semikolon ''\lstinline{;}'' voneinander getrennt sind.
Die erste Anweisung \lstinline{Integer i = 0} setzt die Variable \lstinline{i} auf den Anfangswert \lstinline{0}.
Der Variablenname \lstinline{i} wird gerne für Schleifen verwendet und steht häufig für Index.
Die erste Anweisung wird nur einmal vor Beginn der Schleife ausgeführt.

Die zweite Anweisung \lstinline{i < 5} ist vergleichbar mit der Bedingung einer While-Schleife.

Die erste Anweisung \lstinline{int i = 0} setzt die Zählvariable \lstinline{i} der For-Schleife auf den Anfangswert \lstinline{0}.
Der Name \enquote{\lstinline{i}} ist hierbei typisch für die Zählvariable einer for-Schleife.
Die erste Anweisung wird nur einmal vor Beginn der Schleife ausgeführt.\newline

Die zweite Anweisung (\lstinline{i < 5} in unseren Beispiel) ist vergleichbar mit der bool'schen Bedingung einer While-Schleife.
Sie wird jedes mal überprüft, bevor der Schleifenrumpf ausgeführt wird.
Nur wenn sie \lstinline{true} ist wird der Code-Block der Schleife ausgeführt.
Nur wenn sie den Wert \lstinline{true} zurück gibt, ist wird der Code-Block der Schleife ausgeführt.\newline

Der Ausdruck \lstinline{i < 5} überprüft hier, ob der Wert der Variable \texttt{i} größer (echt) kleiner als die Ganzzahl \texttt{5} ist.
Bei \texttt{<} handelt es sich also wie schon bei \texttt{+},\texttt{-},\texttt{/}, \texttt{*} und \texttt{\%} um eine Operator - genauer einen Vergleichsoperator - der in den meisten Programmiersprachen vorhanden ist.
Weiter Vergleichsoperatoren sind \texttt{>} für \enquote{Ist $\langle$links$\rangle$ (echt) kleiner als $\langle$rechts$\rangle$?}, \texttt{<=}, \texttt{>=}, \texttt{!=} und \texttt{==}.
Genaueres erfährst du hierzu noch in Aufgabe 2.\newline

Die dritte Anweisung \lstinline{i++} wird nach jedem Durchlauf des Codes im Schleifenrumpf ausgeführt, bevor die Bedingung erneut überprüft wird.
\lstinline{i++} heißt, dass \lstinline{i} jeden Schleifendurchlauf um \lstinline{1} erhöht wird.
Das \lstinline{i++} ist also nichts anderes als eine Abkürzung für das Kommando \lstinline{i = i + 1}.\newline

Die dritte Anweisung \lstinline{i++} wird nach jedem Schleifendurchlauf ausgeführt, bevor die Bedingung erneut überprüft wird.
\lstinline{i++} heißt, dass \lstinline{i} jeden Schleifendurchlauf um \lstinline{1} erhöht wird.

Die obige Schleife wird 5 Mal ausgeführt.
Beachte, dass \lstinline{i} mit dem Wert \lstinline{0} beginnt und die Schleifenbedingung auf \lstinline{i < 5} und nicht \lstinline{i <= 5} prüft.
Im letzten Schleifendurchlauf hat \lstinline{i} den Wert \lstinline{4}.
Im letzten Schleifendurchlauf hat \lstinline{i} den Wert \lstinline{4}, wird dann nach der Ausführung des Rumpfes um eins erhöht, wodurch die Bedingung zu \lstinline{flase} ausgewertet wird und der Rumpf nicht weiter ausgeführt wird.
\end{Infobox}


\begin{enumerate}\setcounter{enumi}{2}
\item
\item
Laufe nun mithilfe einer For-Schleife 10 Schritte ohne die Simulation zu pausieren.

\item
Laufe mit Neo jeweils 3, 7, 14 und 22 Schritte indem du die Schleifenbedingung anpasst.
Am Ende sollte Neo auf einem Münzhaufen stehen.

\item
Hebe jetzt mit Neo jeweils 2, 5, 16 und 20 Münzen auf.
Hebe jetzt mit Neo jeweils 2, 5, 16 und 20 Münzen vom Feld \texttt{(0,22)} auf.
Dazu musst du eine weitere For-Schleife benutzen, in der du auch den Schleifenrumpf anpasst.

\item
Verwende für diese Teilaufgabe den Spieler/Neo in der Variable \lstinline{neoF}.

Hebe alle Münzen auf dem aktuellen Feld auf.
Hebe alle Münzen auf Neo's Startposition auf.
Laufe nun 5 Schritte mit einer For-Schleife und lege jeden Schritt so viele Münzen ab, wie du schon Schritte gelaufen bist.

Hinweis: Dafür musst du eine For-Schleife in der For-Schleife verwenden.
Dafür musst du in der inneren For-Schleife einen anderen Variablennamen als \lstinline{i} verwenden.
Du kannst die Variable \lstinline{i} der äußeren For-Schleife in der Schleifenbedingung der inneren For-Schleife benutzen.
Hinweis: Dafür musst du eine For-Schleife in der For-Schleife verwenden.
Du kannst die Variable \lstinline{i} der äußeren For-Schleife in der Schleifenbedingung (an der 2. Stelle im Schleifenkopf) der inneren For-Schleife benutzen.
Überlege Dir, welcher Vergleichsoperator hier am besten passt.

\item
Verwende für diese Teilaufgabe den Spieler/Neo in der Variable \lstinline{neoG}.

Laufe 10 Schritte und hebe dabei maximal 5 Münzen pro Feld auf.

Hinweis: In dieser Aufgabe musst du if-Statements verwenden.
Hinweis: In dieser Aufgabe kannst du if-Statements oder (etwas schwieriger) eine While-Schleife mit einer Zählvariable und 2 Bedingungen verwenden.
Damit letzteres funktioniert, musst du die beiden Bedingungen mit einem \lstinline{\&\&} (=also und-verknüpfen) verbinden.
Dadurch wird der Rumpf der Schleife nur ausgeführt, wenn die beiden Bedingungen links und rechts vom \lstinline{&&} zu \lstinline{true} ausgewertet werden.
All das wird in den Infoboxen der nächsten Aufgabe genauer erklärt.

\begin{lstlisting}
if (neoG.canCollectCoin()) {
Expand Down
151 changes: 76 additions & 75 deletions sheets/3/exercise-2.tex
Original file line number Diff line number Diff line change
@@ -1,59 +1,57 @@
\excercise{If-Conditions }
\excercise{If-Verzweigungen 2}

\begin{enumerate}
\item
Instanziiere die Simulation wie bekannt (\lstinline{Sheet3Task2} und \lstinline{Sheet3Task2Verifier}) und mache dich mit dieser vertraut.

\item
\item
Mit dem folgenden Codebeispiel kannst du die Anzahl der Münzen in dem Feld unter Neo abfragen und auf der Konsole ausgeben.

\begin{lstlisting}
Integer coinsUnderNeo = neo.getCurrentlyCollectableCoins().size();
int coinsUnderNeo = neo.getCurrentlyCollectableCoins().size();
System.out.println(coinsUnderNeo);
\end{lstlisting}

Wichtig: Mit der Operation \lstinline{neo.getCurrentlyCollectableCoins();} bekommt man eine Liste aller Münzen, die auf Neos aktuellem Feld liegen.
Eine Liste hat eine Größe die angibt wie viele Elemente sie enthält.
Die Größe der Liste aller Münzen entspricht genau der Anzahl der Münzen auf Neos aktuellem Feld.
Die Größe kann abgefragt werden mit \lstinline{list.size()}. Was genau Listen in Java sind und wie sie funktionieren, werden wir hier nicht weiter behandeln, für unsere Zwecke reicht es sie in diesem spezifischem Kontext zu verstehen.\\
Laufe mit Neo bis zum ersten Feld mit einer Münze und gib die Anzahl der Münzen unter Neo auf der Konsole aus.\newline

Laufe mit Neo bis zum ersten Feld mit einer Münze und gib die Anzahl der Münzen unter Neo auf der Konsole aus.
\textbf{Wichtig}: Mit der Operation \lstinline{neo.getCurrentlyCollectableCoins();} bekommt man eine Liste aller Münzen-Objekte, die auf Neo's aktuellem Feld liegen.
Du kannst die den Datentyp List wie eine Sequenz (Aneinanderreihung) von Objekten desselben Typs - in diesem Fall des Typs \lstinline{Coin} - vorstellen.
Eine Liste hat eine Länge die angibt wie viele Elemente in ihr enthalten sind.
Diese Länge kann mit der \lstinline{size()}-Methode auf Listen-Objekten abgefragt werden.
\end{enumerate}


\begin{Infobox}[If-Statements 2]

If-Statements kennt ihr ja schon.
Diese können auch dazu verwendet Zahlen (z.B Integer) miteinander zu vergleichen.
If-Statements und die Vergleichsoperatoren (wie z.B. \lstinline{<=}) kennst du ja schon.
Diese können wie schonmal erwähnt zusammen mit primitiven Datentypen wie Ganzzahlen (\lstinline{int}s) verwendet werden.\newline

Hier ein Beispiel:

\begin{lstlisting}[numbers=none]
Integer x = 2;
if ( x < 3 ) {
System.out.println("x ist kleiner als 3!");
}
int x = 2;
if ( x < 3 ) {
System.out.println("x ist kleiner als 3!");
}
\end{lstlisting}

Das kann man zum Beispiel dazu verwenden, um zu schauen wie viele Münzen Neo hat.
Das kann man zum Beispiel dazu verwenden, um zu schauen wie viele Münzen Neo hat.
In Java kannst du die folgenden Vergleichsoperatoren verwenden:

\begin{center}
\begin{tabular}{ l | c | c | l }
Text & Math. Zeichen & Java & Bemerkung\\ \hline
größer als & $>$ & \texttt{>} & \\
kleiner als & $<$ & \texttt{<} & \\
gleich & $=$ & \texttt{==} & \minibox{
mit dem doppelten \texttt{==} sollte man nur \\
Zahlen und keine Objekte vergleichen!\\
Ein einfaches \texttt{==} ist in Java eine Zuweisung!
}\\

ungleich & $\neq$ & \texttt{!=} & \\
größer gleich & $\geq$ & \texttt{>=} & \\
kleiner gleich & $\leq$ & \texttt{<=} & \\
\begin{tabular}{ c | c | c | l }
Natürliche Sprache & Mathematisches Zeichen & Java Operator \\
\hline
größer als & $>$ & \texttt{>} \\
kleiner als & $<$ & \texttt{<} \\
gleich & $=$ & \texttt{==}\\
ungleich & $\neq$ & \texttt{!=} \\
größer gleich & $\geq$ & \texttt{>=} \\
kleiner gleich & $\leq$ & \texttt{<=} \\
\end{tabular} \\
\end{center}

Damit können wir nun prüfen, ob sich auf Neos Feld genau 3 Münzen befinden:
Damit können wir nun prüfen, ob sich auf Neo's Feld genau 3 Münzen befinden:

\begin{lstlisting}[numbers=none]
if ( neo.getCurrentlyCollectableCoins().size() == 3 ){
Expand All @@ -63,9 +61,10 @@
\end{Infobox}


\begin{Infobox}[\lstinline{==} und \lstinline{.equals()}]
Vorsicht: Mit \lstinline{==} sollte man nur Zahlen (Variablen vom Typ Integer und Double (und ein paar andere Typen die wir der einfachheit halber hier weglassen)) vergleichen!
Zum Vergleichen von zwei Objekten sollte immer die \lstinline{.equals} Abfrage von einem der beiden Objekte verwendet werden:
\begin{Infobox}[\lstinline{==} und die \lstinline{equals()}-Methode]
Vorsicht: Mit dem Vergleichsoperator \enquote{\lstinline{==}} sollte man in der Regel nur primitive Datentypen (= etwa Werte vom Typ \lstinline{int}, Fließkommazahlen wie \lstinline{double} und ein paar andere Typen die wir der Einfachheit halber hier weglassen) vergleichen!\newline

Zum Vergleichen von zwei Objekten sollte immer die \lstinline{equals}-Methode, die auf jedem Objekt definiert ist, verwendet werden:

\begin{lstlisting}[numbers=none]
if (neo1.getPosition().equals(new Position(1, 1))){
Expand All @@ -85,84 +84,85 @@

\begin{enumerate}\setcounter{enumi}{2}
\item
Neo soll sich ab jetzt immer geradeaus bewegen, solange keine Münze unter ihm liegt.
Nun wollen wir daran arbeiten möglichst viele Münzen auf dem Spielfeld einzusammeln.

Dazu wollen wir Neo erstmals so lange geradeaus laufen lasse, bis sich unter ihm eine oder mehrere Münzen befinden.
Wenn Neo auf eine Münze trifft, sollst du erst mal anhalten.
\end{enumerate}


\begin{Infobox}[Endlosschleifen und \lstinline{break}]
Eine While-Schleife, in der die Schleifenbedingung \lstinline{true} ist, ist eine Endlosschleife.
Das ist nicht nur ein Name.
Die Schleife wird niemals aufhören!
Deshalb kann es passieren, dass du den Stopp Knopf in der Eclipse Konsole brauchst, um die Schleife wieder abzubrechen.

Endlosschleifen sollte man wann immer möglich vermeiden.
Aber man kann auch eine Endlosschleife wieder beenden.
Dafür braucht man das Schlüsselwort \lstinline{break}.
Wenn du in einer Schleife \lstinline{break} aufrufst, dann wird die Schleife sofort unterbrochen.
Auch die Schleifenbedingung wird dann nicht mehr überprüft.
Das funktioniert auch in einer For-Schleife.
Eine While-Schleife, in der die Schleifenbedingung \lstinline{true} ist, nennt man eine Endlosschleife.
Das heißt, dass die Schleife niemals aufhören wird den Code im Schleifenrumpf auszuführen, wenn das nicht durch eine Exception oder den Stop der Ausführung des Programms verhindert wird!
Deshalb kann es passieren, dass du den Stopp Knopf in der Eclipse Konsole brauchst, um die Schleife wieder abzubrechen.\newline

Endlosschleifen möchte man in der Regel wann immer möglich vermeiden.
Aber man kann auch eine \lstinline{while(true)}-Schleife planmäßig im Quellcode und ohne das Auslösen von Exceptions beenden.
Dafür braucht man das Schlüsselwort \lstinline{break}.\newline

Wenn du im Rumpf einer Schleife \lstinline{break;} aufrufst, dann wird die Schleife sofort unterbrochen.
Auch die Schleifenbedingung wird dann nicht mehr überprüft und der Code nach der Schleife wird weiter ausgeführt.
Das funktioniert auch in For-Schleifen, ist aber hier eher untypisch, da man dort meistens die Zählvariablen zur Begrenzung der Wiederholungen benutzt.

\begin{lstlisting}[numbers=none]
while(true){
// do something
if (hadEnough) {
break;
}
}
while(true){
// do something
if (hadEnough) {
break;
}
}
\end{lstlisting}

\end{Infobox}


\begin{enumerate}\setcounter{enumi}{3}
\item
Wenn sich Neo auf einem Feld mit genau einer Münze befindet, dann lass ihn sich nach rechts drehen und diese Münze aufsammeln.
Danach soll Neo erst mal einen Schritt geradeaus gehen, um wieder von dem Feld herunter zu kommen.
Mit dem neuen Wissen wollen wir nun an unserem Code aus Teilaufgabe c) weiterarbeiten.

Wenn er dann auf einem leeren Feld steht soll Neo wieder geradeaus laufen bis er erneut auf einem Feld mit Münzen steht.
Wenn er direkt auf einem Feld mit Münzen steht, soll Neo wieder prüfen wie viele Münzen auf dem Feld sind und sich danach entscheiden, was er als nächstes tun muss.
Wenn Neo also auf einem Feld mit genau einer Münzen steht, soll er die Münze aufsammeln, sich dann nach rechts drehen und einen weiteren Schritt machen.
Wenn sich mehr als eine Münze unter Neo befinden, soll er die Schleife erstmals mit einem \lstinline{break} verlassen.
Dann soll der wieder anfangen zu laufen, bis unter ihm wieder eine oder mehrere Münzen auftauchen.

\item
Wenn sich mehr als eine Münze unter Neo befindet, dann soll Neo eine Münze aufsammeln und sich nach links drehen bevor er wieder von dem Feld heruntergeht.
Die anderen Münzen soll er liegenlassen.
Wenn sich nun mehr als eine Münze unter Neo befinden sollten, dann soll Neo genau eine Münze aufsammeln, sich nach links drehen und dann wieder einen Schritt nach vorne machen.

Momentan soll Neo noch nicht alle Münzen aufgesammelt bekommen, ohne gegen eine Wand zu laufen.
\end{enumerate}


\begin{Infobox}[Logische Operationen]
\begin{Infobox}[Logische Operatoren]

Wenn mehrere Bedingungen (also bool'sche Werte) für ein Ereignis eine Rolle spielen, muss man diese logisch verknüpfen.
Es folgt eine Auflistung der häufigsten Operatoren:

Wenn mehrere Bedingungen für ein Ereignis eine Rolle spielen, muss man diese logisch verknüpfen.
Java verwendet hierfür folgende Syntax:
\begin{center}
\begin{tabular}{ l | l | l | l}
Text & log. Zeichen & Java Zeichen & Bemerkung \\ \hline
und & $\land$ & \texttt{\&\&} & \minibox{
Achtung! Kein einfaches \texttt{\&} in Java verwenden,\\
das macht etwas leicht Anderes
} \\
oder & $\lor$ & \texttt{||} & Kein einfaches \texttt{|} verwenden (analog zu und) \\
& & \\
\begin{tabular}{ c | c | c | l}
Natürliche Sprache & logische Operatoren & Java Operatoren & Bemerkung \\
\hline
und & $\wedge$ & \texttt{\&\&} & \minibox{Das einfache \texttt{\&} hat eine\\etwas andere Funktion} \\
oder & $\vee$ & \texttt{||} & Dasselbe gilt für \texttt{|} \\
nicht & $\neg$ & \texttt{!} &\\
\end{tabular}\\
\end{center}

Ein paar Beispiele:
Hier ein paar Beispiele der Anwendung dieser in Java-Verzweigungen.
Natürlich kann man die logischen Operatoren aber auch in while- oder for-Schleifeköpfen, oder sonst wo verwenden:

\begin{lstlisting}[numbers=none]
if ( neo.canMove() && (neo.getCurrentlyCollectableCoins().size()==7) ){

if (neo.canMove() && neo.getCurrentlyCollectableCoins().size() == 7) {
//neo hat genau 7 Münzen UND kann nach vorne gehen.
}
\end{lstlisting}

\begin{lstlisting}[numbers=none]
if ( (!neo.canMove()) && (neo.getCurrentlyCollectableCoins().size()==7) ){
if (!neo.canMove() && neo.getCurrentlyCollectableCoins().size() == 7) {
//neo hat genau 7 Münzen UND kann sich NICHT nach vorne gehen.
}
\end{lstlisting}

\begin{lstlisting}[numbers=none]
if ( neo.canMove() || neo.getCurrentlyCollectableCoins().size()==7) ){
if (neo.canMove() || neo.getCurrentlyCollectableCoins().size() == 7) {
//neo hat genau 7 Münzen ODER kann nach vorne gehen.
}
\end{lstlisting}
Expand All @@ -180,8 +180,9 @@
\item
Jetzt wollen wir, dass Neo auch irgendwann aufhört.
Er soll aufhören zu laufen oder Münzen einzusammeln, wenn er schon 20 Münzen gesammelt hat oder wenn er auf einem Feld mit exakt 9 Münzen ankommt.
Mit \lstinline{neo.getCoinsInWallet()} kannst du die Anzahl der Münzen in Neos Inventory abfragen.
Mit \lstinline{neo.getCoinsInWallet()} kannst du die Anzahl der Münzen in Neo's Inventory abfragen.

Tipp: Hierfür kannst du entweder das Argument der Endlosschleife ändern oder \lstinline{break} Verwenden.
\textit{Tipp}: Hierfür kannst du entweder das Argument der Endlosschleife ändern oder \lstinline{break} Verwenden.
Falls du die Entscheidung, was Neo auf einem Feld machen soll, mit einem \lstinline{if-else}-Verzweigung implementiert hast, kannst du hier ein \lstinline{else if(...)} einführen.
\end{enumerate}
\newpage
Loading