Einführung in JavaKara - SwissEduc.ch
Einführung in JavaKara - SwissEduc.ch
Einführung in JavaKara - SwissEduc.ch
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
1 Die JAVAKARA -Umgebung<br />
Die Programmierumgebung JA-<br />
VAKARA erlaubt es, Kara mit<br />
der Programmierspra<strong>ch</strong>e JAVA<br />
zu steuern. Dazu stellt JAVAKA-<br />
RA e<strong>in</strong>en kle<strong>in</strong>en Programmeditor<br />
zur Verfügung, der beim<br />
Aufruf s<strong>ch</strong>on e<strong>in</strong>e Programms<strong>ch</strong>ablone<br />
enthält.<br />
Um Kara zu programmieren,<br />
muss der vorgegebene Name<br />
F<strong>in</strong>deBaum dur<strong>ch</strong> e<strong>in</strong>en geeigneten<br />
Namen für das zu s<strong>ch</strong>reibende<br />
Programm ersetzt werden.<br />
Unter diesem Namen muss<br />
das Programm au<strong>ch</strong> gespei<strong>ch</strong>ert<br />
werden.<br />
Ebenso muss der im Bild markierte<br />
Teil von myProgram()<br />
dur<strong>ch</strong> eigenen Programmcode<br />
ersetzt werden.<br />
<strong>E<strong>in</strong>führung</strong> <strong>in</strong> JAVAKARA<br />
Gerhard Bits<strong>ch</strong><br />
28. Juni 2008<br />
Das im Bild gezeigte Programm F<strong>in</strong>deBaum zeigt s<strong>ch</strong>on e<strong>in</strong>ige Besonderheiten der Programmierung<br />
mit JAVA im Gegensatz zum Automatenmodell.<br />
In der ersten Zeile wird e<strong>in</strong>e Programmumgebung für KARA ” importiert“, die dem Benutzer<br />
die E<strong>in</strong>zelheiten der Programmierung des Graphik-Interfaces (GUI) abnimmt. Mit ihr werden<br />
die für den Anfang benötigten Methoden bereitgestellt.<br />
Diese Methoden s<strong>in</strong>d <strong>in</strong> dem Kommentar unter dieser import-Anweisung aufgeführt. Der<br />
Kommentar beg<strong>in</strong>nt mit /* und endet mit */. Er kann si<strong>ch</strong> über mehrere Zeilen erstrecken.<br />
Alternativ kann mit // der Rest e<strong>in</strong>er Zeile als Kommentar markiert werden. Kommentare<br />
werden vom Programm während des Ablaufs ignoriert. Sie sollen ledigli<strong>ch</strong> die Verständli<strong>ch</strong>keit<br />
von Code verbessern.<br />
Das Programm wird mit der Zeile<br />
public class F<strong>in</strong>deBaum extends <strong>JavaKara</strong>Program {<br />
1
e<strong>in</strong>geleitet. Die nähere Bedeutung der S<strong>ch</strong>lüsselwörter public, class und extends wird später<br />
geklärt werden. Das mit dieser Deklaration begonnene Programm muss mit e<strong>in</strong>er s<strong>ch</strong>ließenden<br />
ges<strong>ch</strong>weiften Klammer } abges<strong>ch</strong>lossen werden.<br />
Na<strong>ch</strong> dieser Deklaration können die für das Programm benötigten Methoden def<strong>in</strong>iert werden.<br />
Außer der Methode myProgram wird im Beispiel ke<strong>in</strong>e weitere Methode def<strong>in</strong>iert. Die Methode<br />
myProgram muss immer def<strong>in</strong>iert werden. Sie ist diejenige Methode, die beim Start des Programmes<br />
ausgeführt wird.<br />
Das im Beispiel angezeigte Programm lasst KARA bis zum nä<strong>ch</strong>sten Baum laufen und dort<br />
stehen bleiben.<br />
Das Bild zeigt e<strong>in</strong> Automatenprogramm mit<br />
der glei<strong>ch</strong>en Wirkung. Die Anweisung, dass<br />
KARA , wenn er vor ke<strong>in</strong>em Baum steht, e<strong>in</strong>en<br />
S<strong>ch</strong>ritt ma<strong>ch</strong>en soll und dann im Zustand<br />
F<strong>in</strong>deBaum bleiben soll, wird mit der while-<br />
Anweisung übertragen (while solange). Der<br />
S<strong>ch</strong>rittbefehl ist kara.move().<br />
Mit kara.treeFront() wird der Sensor abgefragt. Diese Abfrage liefert true, falls KARA vor<br />
e<strong>in</strong>em Baum steht und false andernfalls. Das Ausrufezei<strong>ch</strong>en ! steht für die Negation, d.h. es<br />
vertaus<strong>ch</strong>t die Werte true und false.<br />
2 E<strong>in</strong>fa<strong>ch</strong>e Anweisungen <strong>in</strong> JAVA<br />
In diesem Abs<strong>ch</strong>nitt werden e<strong>in</strong>fa<strong>ch</strong>e JAVA -Anweisungen zur Strukturierung von Programmen<br />
vorgestellt.<br />
Bed<strong>in</strong>gungen: Beim Automatenmodell wird e<strong>in</strong> unters<strong>ch</strong>iedli<strong>ch</strong>es Verhalten von KARA dur<strong>ch</strong> die Zustände<br />
der Sensoren gesteuert. In JAVA kann man diese Sensoren abfragen. Sie liefern<br />
dabei e<strong>in</strong>en der Werte true oder false . Ausdrücke mit der Eigens<strong>ch</strong>aft, e<strong>in</strong>en dieser Werte<br />
zu liefern, nennt man Bed<strong>in</strong>gungen.<br />
Bed<strong>in</strong>gungen können mit aussagenlogis<strong>ch</strong>en Operatoren verknüpft werden. Die folgende<br />
Tabelle gibt das Ergebnis e<strong>in</strong>er sol<strong>ch</strong>en Verknüpfung für zwei Bed<strong>in</strong>gungen a und b<br />
wieder:<br />
a b (! a) (a && b) (a || b)<br />
ni<strong>ch</strong>t und oder<br />
Beispiele:<br />
true true false true true<br />
true false false false true<br />
false true true false true<br />
false false true false false<br />
(! kara.onLeaf()) true , falls KARA auf e<strong>in</strong>em leeren Feld steht.<br />
(kara.treeLeft() && kara.treeRight()) true , falls l<strong>in</strong>ks und re<strong>ch</strong>ts von KARA e<strong>in</strong><br />
Baum steht.<br />
(kara.treeFront() || kara.onLeaf()) true , falls m<strong>in</strong>destens e<strong>in</strong>e der beiden Bed<strong>in</strong>gungen<br />
zutrifft.<br />
2
Blöcke: Man kann mehrere Anweisungen zu e<strong>in</strong>er Anweisung (e<strong>in</strong>em Block) zusammenfassen,<br />
<strong>in</strong>dem man vor die erste Anweisung e<strong>in</strong>e geöffnete ges<strong>ch</strong>weifte Klammer und na<strong>ch</strong> der<br />
letzten Anweisung e<strong>in</strong>e ges<strong>ch</strong>lossene ges<strong>ch</strong>weifte Klammer setzt.<br />
while: Die while-S<strong>ch</strong>leife, die s<strong>ch</strong>on im vorigen Abs<strong>ch</strong>nitt angespro<strong>ch</strong>en wurde, hat folgende<br />
Gestalt:<br />
while (Bed<strong>in</strong>gung ) {<br />
}<br />
Anweisung1;<br />
Anweisungn;<br />
. Diese Anweisungen bilden e<strong>in</strong>en Block<br />
Bei der Ausführung e<strong>in</strong>er while-Anweisung wird zunä<strong>ch</strong>st die (immer <strong>in</strong> runden Klammern<br />
e<strong>in</strong>ges<strong>ch</strong>lossene) Bed<strong>in</strong>gung überprüft. Liefert sie den Wert true , so werden die (immer<br />
dur<strong>ch</strong> e<strong>in</strong> Paar ges<strong>ch</strong>weifte Klammern e<strong>in</strong>ges<strong>ch</strong>lossenen) Anweisungen (jeweils dur<strong>ch</strong> e<strong>in</strong>en<br />
Stri<strong>ch</strong>punkt abges<strong>ch</strong>lossen) na<strong>ch</strong>e<strong>in</strong>ander ausgeführt. Ans<strong>ch</strong>ließend beg<strong>in</strong>nt der Vorgang<br />
mit der Überprüfung der Bed<strong>in</strong>gung neu. Dies wird so lange wiederholt, bis die Bed<strong>in</strong>gung<br />
den Wert false liefert.<br />
Verzweigung: Verzweigungen entstehen, wenn je na<strong>ch</strong> dem Wert e<strong>in</strong>er Bed<strong>in</strong>gung unters<strong>ch</strong>iedli<strong>ch</strong>e Anweisungen<br />
ausgeführt werden. Die allgeme<strong>in</strong>e Form ist:<br />
if (Bed<strong>in</strong>gung ) {<br />
}<br />
else {<br />
}<br />
Anweisungen falls true<br />
Anweisungen falls false<br />
Beispiel:<br />
1 i f ( kara . onLeaf ( ) ) { / / f a l l s K a r a a u f e i n e m B l a t t s t e h t<br />
2 kara . removeLeaf ( ) ; / / B l a t t e n t f e r n e n<br />
3 }<br />
4 e lse { / / a n d e r n f a l l s<br />
5 kara . putLeaf ( ) ; / / B l a t t a b l e g e n<br />
6 }<br />
Soll ke<strong>in</strong>e Anweisung ausgeführt werden, wenn die Bed<strong>in</strong>gung ni<strong>ch</strong>t erfüllt ist, so kann<br />
man den else-Teil der Anweisung weglassen.<br />
Beispiel:<br />
1 i f ( kara . t r e e F r o n t ( ) ) { / / f a l l s K a r a v o r e i n e m B a u m s t e h t<br />
2 kara . t u r n L e f t ( ) ; / / n a c h l i n k s d r e h e n<br />
3 } / / a n s o n s t e n n i c h t s t u n ,<br />
4 / / P r o g r a m m f o r t s e t z e n<br />
Methoden: Außer myProgram() kann man au<strong>ch</strong> eigenen Methoden def<strong>in</strong>ieren, die dann wie die <strong>in</strong><br />
der Umgebung vorhandenen Methoden verwendet werden können. Es gibt dafür mehrere<br />
Mögli<strong>ch</strong>keiten, die e<strong>in</strong>fa<strong>ch</strong>ste führen wir jetzt e<strong>in</strong>.<br />
3
private void Methodenname() {<br />
}<br />
Anweisungen<br />
Das S<strong>ch</strong>lüsselwort private besagt, dass diese Methode nur <strong>in</strong>nerhalb des gegenwärtigen<br />
Programms zur Verfügung stehen soll. void gibt an, dass die Methode ke<strong>in</strong> Ergebnis<br />
zurück gibt (sie verändert die Welt oder den Zustand KARAS).<br />
Beispiel: KARA soll zum nä<strong>ch</strong>sten Baum gehen, si<strong>ch</strong> dort umdrehen und weiter laufen<br />
und dies endlos wiederholen.<br />
1 public c l a s s laufen extends <strong>JavaKara</strong>Program {<br />
2<br />
3 private void drehen ( ) { / / M e t h o d e z u r D r e h u n g um 1 8 0 ◦<br />
4 kara . t u r n L e f t ( ) ;<br />
5 kara . t u r n L e f t ( ) ;<br />
6 }<br />
7<br />
8 public void myProgram ( ) {<br />
9 while ( true ) { / / d a s e r z e u g t e i n e E n d l o s s c h l e i f e<br />
10 i f ( kara . t r e e F r o n t ( ) ) { / / W e n n K a r a v o r e i n e m B a u m i s t<br />
11 drehen ( ) ; / / u m d r e h e n<br />
12 }<br />
13 kara . move ( ) ; / / w e i t e r l a u f e n<br />
14 }<br />
15 }<br />
16 }<br />
3 Struktogramme<br />
Struktogramme ermögli<strong>ch</strong>en es, den Ablauf e<strong>in</strong>es Programms graphis<strong>ch</strong> zu entwerfen. Das ganze<br />
Programm wird <strong>in</strong> e<strong>in</strong>em Re<strong>ch</strong>teck e<strong>in</strong>getragen. S<strong>ch</strong>leifen, Fallunters<strong>ch</strong>eidungen und Methodenaufrufe<br />
(für selbstges<strong>ch</strong>riebene Methoden) werden wie folgt dargestellt:<br />
• while-S<strong>ch</strong>leifen<br />
S<strong>ch</strong>leifenbed<strong>in</strong>gung<br />
Anweisung1<br />
· · ·<br />
Anweisungn<br />
• Fallunters<strong>ch</strong>eidungen<br />
✏✏<br />
Bed<strong>in</strong>gung ✏✏<br />
✏✏<br />
✏✏<br />
T ✏✏<br />
F<br />
✏<br />
True-Teil False-Teil<br />
4
• Methodenaufrufe<br />
Beispiel:<br />
Methode<br />
Hier ist e<strong>in</strong> e<strong>in</strong>fa<strong>ch</strong>es Beispiel für e<strong>in</strong> Struktogramm zum Entwurf e<strong>in</strong>es JAVAKARA -Programms.<br />
KARA soll zum nä<strong>ch</strong>sten Baum laufen und unterwegs alle Felder <strong>in</strong>vertieren, d.h. auf Feldern<br />
mit Blatt das Blatt wegnehmen und auf Feldern ohne Blatt e<strong>in</strong> Blatt ablegen.<br />
ZumBaum<br />
!(treeFront())<br />
<strong>in</strong>vertiereFeld()<br />
move()<br />
<strong>in</strong>vertiereFeld()<br />
In diesem Struktogramm wird e<strong>in</strong>e Anweisung verwendet, die KARA ni<strong>ch</strong>t kennt: <strong>in</strong>vertiere-<br />
Feld(). Diese Anweisung wird als Methode implementiert. Das zugehörige Struktogramm ist:<br />
<strong>in</strong>vertiereFeld()<br />
✏✏<br />
onLeaf() ✏✏<br />
✏✏<br />
✏✏<br />
T ✏✏<br />
F<br />
✏<br />
removeLeaf() putLeaf()<br />
Diese Struktogramme übersetzen si<strong>ch</strong> <strong>in</strong> folgendes JAVAKARA -Programm:<br />
1 public c l a s s zumBaum extends <strong>JavaKara</strong>Program {<br />
2<br />
3 private void i n v e r t i e r e F e l d ( ) {<br />
4 i f ( kara . onLeaf ( ) ) {<br />
5 kara . removeLeaf ( ) ;<br />
6 }<br />
7 e lse {<br />
8 kara . putLeaf ( ) ;<br />
9 }<br />
10 }<br />
11<br />
12 public void myProgram ( ) {<br />
13 i n v e r t i e r e F e l d ( ) ;<br />
14 while ( ! kara . t r e e F r o n t ( ) ) {<br />
15 kara . move ( ) ;<br />
16 i n v e r t i e r e F e l d ( ) ;<br />
17 }<br />
18 }<br />
19 }<br />
5
4 Variablen und Typen<br />
Aufgabe: KARA soll zu e<strong>in</strong>em Baum laufen, si<strong>ch</strong> umdrehen und dann weiter laufen. Das soll<br />
er fünf mal wiederholen.<br />
Im Automatenmodell wurden für diese Aufgabe fünf Zustände benötigt. Ändert man die Anzahl<br />
der Wiederholungen, so ändert si<strong>ch</strong> die Anzahl der benötigten Zustände entspre<strong>ch</strong>end. Es<br />
gibt im Automatenmodell ke<strong>in</strong>e e<strong>in</strong>fa<strong>ch</strong>e Mögli<strong>ch</strong>keit, beliebig weit zu zählen.<br />
In JAVAKARA kann man zählen, <strong>in</strong>dem man Variablen verwendet. Variablen bieten e<strong>in</strong>e Mögli<strong>ch</strong>keit,<br />
Daten im Spei<strong>ch</strong>er des Re<strong>ch</strong>ners abzulegen und zu verändern. Da vers<strong>ch</strong>iedene Daten<br />
unters<strong>ch</strong>iedli<strong>ch</strong> viel Platz zur Spei<strong>ch</strong>erung beanspru<strong>ch</strong>en, muss man (bei vielen Programmierspra<strong>ch</strong>en,<br />
au<strong>ch</strong> bei JAVA ) im Programm vorher angeben, wel<strong>ch</strong>en Typ die zu spei<strong>ch</strong>ernden<br />
Daten haben. Außerdem muss man si<strong>ch</strong> den Spei<strong>ch</strong>erort merken, um auf die gespei<strong>ch</strong>erten<br />
Daten zugreifen zu können. Dazu werden Variablen deklariert. In JAVA erfolgt das dur<strong>ch</strong> die<br />
Angabe des Datentyps, e<strong>in</strong>es Namens und eventuell e<strong>in</strong>es Anfangswertes:<br />
<strong>in</strong>t zähler = 0;<br />
Diese Anweisung deklariert e<strong>in</strong>e Variable zähler, <strong>in</strong> der ganze Zahlen (<strong>in</strong>t <strong>in</strong>teger ganze<br />
Zahl) gespei<strong>ch</strong>ert werden können und spei<strong>ch</strong>ert 0 als Wert dieser Variablen.<br />
boolean gefunden;<br />
Damit wird die Variable gefunden als e<strong>in</strong>e Variable deklariert, die e<strong>in</strong>en der Werte true oder<br />
false aufnehmen kann. Die Variable erhält ke<strong>in</strong>en Anfangswert. (Der Typ boolean ist na<strong>ch</strong><br />
George Boole (1815 - 1864) benannt.)<br />
In JAVA gibt es e<strong>in</strong>e Vielzahl weiterer Datentypen (man kann au<strong>ch</strong> eigene Typen erzeugen).<br />
Wenn man si<strong>ch</strong> e<strong>in</strong> Gedankenmodell für Variable ma<strong>ch</strong>en will, kann man si<strong>ch</strong> folgendes vorstellen:<br />
mit e<strong>in</strong>er Deklaration e<strong>in</strong>er Variablen wird e<strong>in</strong>e S<strong>ch</strong>a<strong>ch</strong>tel (zum Typ) passender Größe<br />
angefertigt und mit e<strong>in</strong>em Namenss<strong>ch</strong>ild versehen. Ist e<strong>in</strong> Anfangswert angegeben, so wird<br />
dieser auf e<strong>in</strong>en Zettel ges<strong>ch</strong>rieben und der Zettel <strong>in</strong> die S<strong>ch</strong>a<strong>ch</strong>tel gelegt. Die S<strong>ch</strong>a<strong>ch</strong>tel kommt<br />
<strong>in</strong> e<strong>in</strong> Lager, wo sie über den aufgeklebten Namen wieder gefunden werden kann.<br />
Nun soll mit Hilfe e<strong>in</strong>er Variablen das anfangs gestellte Problem gelöst werden. Zunä<strong>ch</strong>st e<strong>in</strong><br />
Struktogramm:<br />
FünfRunden<br />
<strong>in</strong>t runden ← 0<br />
❤❤❤❤❤❤❤❤❤❤❤❤❤❤<br />
runden < 5<br />
✟<br />
treeFront() ✟<br />
✟<br />
W ✟<br />
❤✟<br />
F<br />
drehen()<br />
move()<br />
runden ← runden + 1<br />
Die Zuweisung e<strong>in</strong>es Wertes zu e<strong>in</strong>er deklarierten Variablen symbolisieren wir im Struktogramm<br />
dur<strong>ch</strong> e<strong>in</strong>en l<strong>in</strong>ksgeri<strong>ch</strong>teten Pfeil ←. Besonders <strong>in</strong>teressant ist dabei die Zuweisung<br />
<strong>in</strong> der Fallunters<strong>ch</strong>eidung. Sie zeigt an, dass der Variable runden ihr um 1 erhöhter alter Wert<br />
zugewiesen werden soll. Da dies jedesmal ges<strong>ch</strong>ieht, wenn KARA vor e<strong>in</strong>em Baum steht, zählt<br />
diese Variable die von KARA zurückgelegten Runden. Na<strong>ch</strong> 5 Runden hat die Variable den<br />
Wert 5, die S<strong>ch</strong>leifenbed<strong>in</strong>gung ist also ni<strong>ch</strong>t mehr erfüllt und KARA bleibt stehen.<br />
Im zugehörige JAVAKARA -Programm wird die Zuweisung von Werten an die Variable runden<br />
mit dem Glei<strong>ch</strong>heitszei<strong>ch</strong>en = ges<strong>ch</strong>rieben. Diese Verwendung entspri<strong>ch</strong>t natürli<strong>ch</strong> ni<strong>ch</strong>t dem<br />
6
Gebrau<strong>ch</strong> von = <strong>in</strong> der Mathematik, ist aber <strong>in</strong> vielen Programmierspra<strong>ch</strong>en übli<strong>ch</strong>. Für Verglei<strong>ch</strong>e<br />
von Zahlen kann man mit , == Bed<strong>in</strong>gungen formulieren (das doppelte Glei<strong>ch</strong>heitszei<strong>ch</strong>en<br />
überprüft die Glei<strong>ch</strong>heit zweier Zahlen).<br />
1 public c l a s s FünfRunden extends <strong>JavaKara</strong>Program {<br />
2<br />
3 private void drehen ( ) {<br />
4 kara . t u r n L e f t ( ) ;<br />
5 kara . t u r n L e f t ( ) ;<br />
6 }<br />
7<br />
8 public void myProgram ( ) {<br />
9 i n t runden =0;<br />
10 while ( runden < 5) {<br />
11 i f ( kara . t r e e F r o n t ( ) ) {<br />
12 drehen ( ) ;<br />
13 runden = runden + 1 ; / / k e i n e G l e i c h u n g ,<br />
14 } / / s o n d e r n e i n e Z u w e i s u n g<br />
15 e lse {<br />
16 kara . move ( ) ;<br />
17 }<br />
18 }<br />
19 }<br />
20 }<br />
Aufgaben<br />
Fertigen Sie für die folgenden Aufgaben jeweils e<strong>in</strong> Struktogramm an, ehe Sie versu<strong>ch</strong>en das<br />
Programm zu erstellen. verwenden Sie wo mögli<strong>ch</strong> eigene Methoden.<br />
1. Bearbeiten Sie die Aufgabe Tunnelsu<strong>ch</strong>er II und die drei Aufgaben zur Kleeblattsu<strong>ch</strong>e im<br />
Wald.<br />
2. Bearbeiten Sie die Aufgabe Pacman.<br />
3. KARA soll e<strong>in</strong> 4 × 5-Re<strong>ch</strong>teck mit Blättern belegen.<br />
4. KARA soll e<strong>in</strong> S<strong>ch</strong>a<strong>ch</strong>brett (8 × 8) auslegen (weisse Felder leer, s<strong>ch</strong>warze Felder mit Blatt).<br />
Lösungen<br />
Aufgabe 1:<br />
Tunnelsu<strong>ch</strong>er:<br />
Den zwei benötigten Zuständen für dieses Problem im Automatenmodell entspre<strong>ch</strong>en hier<br />
zwei while-S<strong>ch</strong>leifen.<br />
TunnelEnde<br />
(! (treeLeft() && treeRight()))<br />
move()<br />
(treeLeft() && treeRight())<br />
move()<br />
Das zugehörige Programm:<br />
7
1 public c l a s s TunnelEnde extends <strong>JavaKara</strong>Program {<br />
2 public void myProgram ( ) {<br />
3 while ( ! ( kara . t r e e L e f t ( ) && kara . t r e e R i g h t ( ) ) ) {<br />
4 kara . move ( ) ; / / zum T u n n e l a n f a n g<br />
5 }<br />
6 while ( kara . t r e e L e f t ( ) && kara . t r e e R i g h t ( ) ) {<br />
7 kara . move ( ) ; / / zum T u n n e l e n d e<br />
8 }<br />
9 }<br />
10 }<br />
Wald I<br />
Das Struktogramm verwendet die Methode umBaum(), die no<strong>ch</strong> def<strong>in</strong>iert werden muss.<br />
Wald I<br />
(! onLeaf())<br />
❳❳ ❳❳❳<br />
❳❳❳ treeFront() ✘<br />
❳❳ ✘✘✘<br />
T ✘ F<br />
✘<br />
umBaum() move()<br />
removeLeaf()<br />
Das zugehörige Programm:<br />
✘<br />
✘<br />
✘<br />
✘<br />
1 public c l a s s Wald1 extends <strong>JavaKara</strong>Program {<br />
2<br />
3 private void umBaum( ) {<br />
4 kara . t u r n L e f t ( ) ;<br />
5 kara . move ( ) ;<br />
6 kara . turnRight ( ) ;<br />
7 kara . move ( ) ;<br />
8 kara . move ( ) ;<br />
9 kara . turnRight ( ) ;<br />
10 kara . move ( ) ;<br />
11 kara . t u r n L e f t ( ) ;<br />
12 }<br />
13<br />
14 public void myProgram ( ) {<br />
15 while ( ! kara . onLeaf ( ) ) {<br />
16 i f ( kara . t r e e F r o n t ( ) ) {<br />
17 umBaum ( ) ;<br />
18 }<br />
19 e lse {<br />
20 kara . move ( ) ;<br />
21 }<br />
22 }<br />
23 kara . removeLeaf ( ) ;<br />
24 }<br />
25 }<br />
8
Wald II<br />
Hier muss ledigli<strong>ch</strong> die Methode umBaum() angepasst werden. Der mittlere Teil mit den zwei<br />
move()-Befehlen muss ersetzt werden dur<strong>ch</strong> e<strong>in</strong>e S<strong>ch</strong>leife, um beliebig viele Bäume zu umgehen:<br />
1 private void umBaum( ) {<br />
2 kara . t u r n L e f t ( ) ;<br />
3 kara . move ( ) ;<br />
4 kara . turnRight ( ) ;<br />
5 while ( kara . t r e e R i g h t ( ) ) {<br />
6 kara . move ( ) ;<br />
7 }<br />
8 kara . turnRight ( ) ;<br />
9 kara . move ( ) ;<br />
10 kara . t u r n L e f t ( ) ;<br />
11 }<br />
Wald III<br />
Hier wird e<strong>in</strong>e Unters<strong>ch</strong>eidung von drei vers<strong>ch</strong>iedenen Fällen benötigt: Baum vorn, Baum l<strong>in</strong>ks<br />
und Baum re<strong>ch</strong>ts. Man erledigt das mit e<strong>in</strong>er ges<strong>ch</strong>a<strong>ch</strong>telten Fallunters<strong>ch</strong>eidung. Man prüft<br />
zunä<strong>ch</strong>st, ob vorn e<strong>in</strong> Baum steht. Ist dies ni<strong>ch</strong>t der Fall, prüft man, ob re<strong>ch</strong>ts oder l<strong>in</strong>ks e<strong>in</strong><br />
Baum steht.<br />
Man erhält folgendes Struktogramm:<br />
Wald3<br />
! onLeaf()<br />
✏✏<br />
(! treeFront())<br />
✏✏<br />
✏✏<br />
✏✏<br />
✏✏<br />
✏✏<br />
✏✏<br />
T ✏✏<br />
✏✏<br />
F<br />
✏ ✏<br />
✏<br />
<br />
✏✏<br />
(! treeLeft())<br />
✏✏<br />
✏✏<br />
T ✏✏<br />
✏<br />
F<br />
∅<br />
turnLeft() turnRight()<br />
❅<br />
❅<br />
❅<br />
❅<br />
❅<br />
❅<br />
❅<br />
move()<br />
move()<br />
removeLeaf()<br />
move()<br />
Dies führt zu folgendem Programm. Die ges<strong>ch</strong>a<strong>ch</strong>telte Fallunters<strong>ch</strong>eidung wird aus dem Struktogramm<br />
so übertragen, dass <strong>in</strong>nerhalb des else-Teils der ersten Fallunters<strong>ch</strong>eidung e<strong>in</strong>e zweite<br />
e<strong>in</strong>gefügt wird. Dies lässt si<strong>ch</strong> beliebig oft wiederholen.<br />
1 public c l a s s Wald3 extends <strong>JavaKara</strong>Program {<br />
2<br />
3 public void myProgram ( ) {<br />
4 while ( ! kara . onLeaf ( ) ) {<br />
5 i f ( ! kara . t r e e F r o n t ( ) ) {<br />
6 kara . move ( ) ;<br />
7 }<br />
8 e lse {<br />
9 i f ( ! kara . t r e e L e f t ( ) ) {<br />
9
10 kara . t u r n L e f t ( ) ;<br />
11 kara . move ( ) ;<br />
12 }<br />
13 e lse {<br />
14 kara . turnRight ( ) ;<br />
15 kara . move ( ) ;<br />
16 }<br />
17 }<br />
18 }<br />
19 kara . removeLeaf ( ) ;<br />
20 }<br />
21 }<br />
Aufgabe 2:<br />
Pacman<br />
Dieses Programm benötigt e<strong>in</strong>e S<strong>ch</strong>leife und <strong>in</strong>nerhalb der S<strong>ch</strong>leife e<strong>in</strong>e ges<strong>ch</strong>a<strong>ch</strong>telte Fallunters<strong>ch</strong>eidung.<br />
Im ersten Fall ist ni<strong>ch</strong>ts zu tun, falls KARA auf e<strong>in</strong>em Blatt ist, im anderen Fall<br />
muss KARA das nä<strong>ch</strong>ste Blatt erst lokalisieren und si<strong>ch</strong> auf das Feld mit dem Blatt begeben. Die<br />
S<strong>ch</strong>leife hat also als Invariante die Bed<strong>in</strong>gung, dass KARA auf e<strong>in</strong>em Blatt stehen muss. Dieses<br />
wird am Ende jedes S<strong>ch</strong>leifendur<strong>ch</strong>gangs entfernt.<br />
Pacman<br />
! treeFront()<br />
removeLeaf()<br />
move()<br />
❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤<br />
✟<br />
✟<br />
! onLeaf()<br />
✟<br />
✟<br />
✟<br />
T<br />
✟<br />
✟ F<br />
✟<br />
zurück()<br />
turnRight()<br />
move()<br />
❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤<br />
✟<br />
! onLeaf() ✟<br />
✟<br />
✟<br />
✟<br />
T ❤✟<br />
F<br />
zurück()<br />
∅<br />
move()<br />
removeLeaf()<br />
Um KARA auf das nä<strong>ch</strong>ste Blatt zu bewegen wird die Methode zurück verwendet. Das benötigte<br />
Struktogramm für die Methode zurück ist:<br />
zurück<br />
turnLeft()<br />
turnLeft()<br />
move()<br />
Daraus erhält man das folgende Programm:<br />
10<br />
∅
1 public c l a s s Pacman extends <strong>JavaKara</strong>Program {<br />
2<br />
3 private void zurück ( ) {<br />
4 kara . t u r n L e f t ( ) ;<br />
5 kara . t u r n L e f t ( ) ;<br />
6 kara . move ( ) ;<br />
7 }<br />
8<br />
9 public void myProgram ( ) {<br />
10 kara . removeLeaf ( ) ; / / V o r b e d i n g u n g : K a r a i s t a u f K l e e b l a t t<br />
11 while ( ! kara . t r e e F r o n t ( ) ) { / / s o l a n g e n i c h t v o r Baum ,<br />
12 / / n ä c h s t e s K l e e b l a t t s u c h e n<br />
13 kara . move ( ) ; / / F e l d v o r n<br />
14 i f ( ! kara . onLeaf ( ) ) { / / k e i n K l e e b l a t t v o r n ?<br />
15 zurück ( ) ; / / d a n n l i n k s u n t e r s u c h e n<br />
16 kara . turnRight ( ) ;<br />
17 kara . move ( ) ;<br />
18 i f ( ! kara . onLeaf ( ) ) { / / a u c h k e i n B l a t t l i n k s ?<br />
19 zurück ( ) ; / / d a n n m u s s e s r e c h t s s e i n !<br />
20 kara . move ( ) ;<br />
21 }<br />
22 }<br />
23 kara . removeLeaf ( ) ; / / I n v a r i a n t e : K a r a i s t a u f K l e e b l a t t<br />
24 }<br />
25 }<br />
26 }<br />
Aufgabe 3:<br />
Für das Re<strong>ch</strong>teck erhält man zunä<strong>ch</strong>st e<strong>in</strong>e Programmstruktur mit zwei <strong>in</strong>e<strong>in</strong>ander ges<strong>ch</strong>a<strong>ch</strong>telten<br />
S<strong>ch</strong>leifen. E<strong>in</strong>e äußere S<strong>ch</strong>leife ist für die aufe<strong>in</strong>anderfolgende Anordnung der Reihen<br />
des Re<strong>ch</strong>tecks zuständig, <strong>in</strong> e<strong>in</strong>er <strong>in</strong>neren S<strong>ch</strong>leife wird jeweils e<strong>in</strong>e e<strong>in</strong>zelne Reihe ausgegeben.<br />
Re<strong>ch</strong>teck<br />
i < 4<br />
<strong>in</strong>t i ← 0<br />
reiheLegen()<br />
i ← i + 1<br />
nä<strong>ch</strong>steReihe()<br />
Das Legen e<strong>in</strong>er Reihe wird als Methode formuliert und mit e<strong>in</strong>er S<strong>ch</strong>leife realisiert:<br />
11
eiheLegen()<br />
<strong>in</strong>t j ← 0<br />
j < 5<br />
putLeaf()<br />
move()<br />
j ← j + 1<br />
nä<strong>ch</strong>steReihe()<br />
turnLeft()<br />
turnLeft()<br />
<strong>in</strong>t j ← 0<br />
j < 5<br />
move()<br />
j ← j + 1<br />
turnLeft()<br />
move()<br />
turnLeft()<br />
Der We<strong>ch</strong>sel zur nä<strong>ch</strong>sten Reihe ist ebenfalls als Methode realisiert. KARA geht zum Anfang der<br />
vorigen Reihe und we<strong>ch</strong>selt dann <strong>in</strong> die zu legende neue Reihe. Das s<strong>ch</strong>e<strong>in</strong>t umständli<strong>ch</strong>, aber<br />
für abwe<strong>ch</strong>selnde L<strong>in</strong>ks- und Re<strong>ch</strong>tsdur<strong>ch</strong>gänge benötigt man jetzt no<strong>ch</strong> ni<strong>ch</strong>t bespro<strong>ch</strong>ene<br />
Hilfsmittel. Das folgende Programm zei<strong>ch</strong>net das gewüns<strong>ch</strong>te Re<strong>ch</strong>teck. Dabei wird e<strong>in</strong>e <strong>in</strong><br />
JAVA erlaubte Abkürzung für den Befehl i = i + 1 verwendet, nämli<strong>ch</strong> i++.<br />
1 public c l a s s Re<strong>ch</strong>teck extends <strong>JavaKara</strong>Program {<br />
2 private void reiheLegen ( ) {<br />
3 i n t j =0;<br />
4 while ( j
Aufgabe 4<br />
Diese Aufgabe ist e<strong>in</strong>e Variante des Re<strong>ch</strong>teck-Problems. Allerd<strong>in</strong>gs müssen zwei aufe<strong>in</strong>ander<br />
folgende Reihen um e<strong>in</strong>s gegene<strong>in</strong>ander versetzt gelegt werden. Die folgenden Struktogramme<br />
bes<strong>ch</strong>reiben e<strong>in</strong>e mögli<strong>ch</strong>e Lösung.<br />
S<strong>ch</strong>a<strong>ch</strong>brett<br />
i < 4<br />
<strong>in</strong>t i ← 0<br />
reiheLegen1()<br />
nä<strong>ch</strong>steReihe()<br />
reiheLegen2()<br />
nä<strong>ch</strong>steReihe()<br />
i ← i + 1<br />
Die Methoden reiheLegen1() und reiheLegen2 unters<strong>ch</strong>eiden si<strong>ch</strong> nur ger<strong>in</strong>gfügig.<br />
reiheLegen1<br />
<strong>in</strong>t j ← 0<br />
(j < 4)<br />
putLeaf()<br />
move()<br />
move()<br />
j ← j + 1<br />
reiheLegen2<br />
<strong>in</strong>t j ← 0<br />
(j < 4)<br />
move()<br />
putLeaf()<br />
move()<br />
j ← j + 1<br />
Die Methode nä<strong>ch</strong>steReihe() wird dur<strong>ch</strong> folgendes Struktogramm bes<strong>ch</strong>rieben:<br />
nä<strong>ch</strong>steReihe()<br />
j < 8<br />
turnLeft()<br />
turnLeft()<br />
<strong>in</strong>t j ← 0<br />
move()<br />
j ← j + 1<br />
turnLeft()<br />
move()<br />
turnLeft()<br />
Das fertige Programm sieht dann so aus:<br />
1 public c l a s s S<strong>ch</strong>a<strong>ch</strong>brett extends <strong>JavaKara</strong>Program {<br />
2 private void reiheLegen1 ( ) {<br />
3 i n t j =0;<br />
4 while ( j
11 private void reiheLegen2 ( ) {<br />
12 i n t j =0;<br />
13 while ( j
Im Unters<strong>ch</strong>ied zu den bisherigen Def<strong>in</strong>itionen von Methoden steht hier <strong>in</strong> der Klammer h<strong>in</strong>ter<br />
dem Methodennamen e<strong>in</strong>e Paramaterdeklaration. Sol<strong>ch</strong>e Deklarationen bestehen aus zwei<br />
Teilen:<br />
• e<strong>in</strong>em Typnamen (hier <strong>in</strong>t), der angibt was für e<strong>in</strong>e Art von Werten die Methode erwartet.<br />
• e<strong>in</strong>em Namen für den Parameter (hier anzahl). Unter diesem Namen kann auf den übergebenen<br />
Wert <strong>in</strong>nerhalb der Methode zugegriffen werden.<br />
Man kann <strong>in</strong> die Klammer au<strong>ch</strong> mehrere Parameterdeklarationen s<strong>ch</strong>reiben. Diese werden<br />
dann dur<strong>ch</strong> Kommata vone<strong>in</strong>ander getrennt. Beim Aufruf e<strong>in</strong>er Methode mit Parametern müssen<br />
<strong>in</strong> die Klammern h<strong>in</strong>ter dem Parameternamen Ausdrücke für die Parameter e<strong>in</strong>getragen werden<br />
(dur<strong>ch</strong> Kommata getrennt, falls es mehrere Parameter gibt). Im Beispiel würde etwa move(5)<br />
KARA veranlassen, fünf Felder na<strong>ch</strong> vorn zu gehen. Den glei<strong>ch</strong>en Effekt kann man au<strong>ch</strong> mit<br />
move(3+2) errei<strong>ch</strong>en. Re<strong>ch</strong>enausdrücke s<strong>in</strong>d bei der Parameterübergabe erlaubt.<br />
Aufgaben:<br />
1. S<strong>ch</strong>reiben Sie e<strong>in</strong>e Methode turnLeft(<strong>in</strong>t anzahl) und e<strong>in</strong>e Methode turnRight(anzahl),<br />
die KARA veranlasst, si<strong>ch</strong> so oft na<strong>ch</strong> l<strong>in</strong>ks bzw. re<strong>ch</strong>ts zu drehen, wie anzahl angibt. Programmieren<br />
Sie e<strong>in</strong> passendes Verhalten für negative Werte von anzahl.<br />
2. Verändern Sie das S<strong>ch</strong>a<strong>ch</strong>brettprogramm (Seite 7) so, dass nur e<strong>in</strong>e Methode zum Legen<br />
der Reihen benötigt wird und die Größe des S<strong>ch</strong>a<strong>ch</strong>bretts variabel gehalten wird.<br />
In vielen Fällen mö<strong>ch</strong>te man s<strong>ch</strong>on für myProgram zur Laufzeit Daten e<strong>in</strong>geben können. Dazu<br />
stellt JAVAKARA unter anderen (Seite 21) die Methode <strong>in</strong>tInput(Str<strong>in</strong>g Titel) zur Verfügung.<br />
Diese Methode wird nun verwendet, um die Re<strong>ch</strong>teck-Klasse zu verallgeme<strong>in</strong>ern. <strong>in</strong>tInput<br />
benötigt als Parameter e<strong>in</strong>e E<strong>in</strong>gabeaufforderung <strong>in</strong> Form e<strong>in</strong>es Str<strong>in</strong>gs (Zei<strong>ch</strong>enkette). Str<strong>in</strong>gs<br />
werden e<strong>in</strong>gegeben, <strong>in</strong>dem man den gewüns<strong>ch</strong>ten Text <strong>in</strong> Anführungszei<strong>ch</strong>en e<strong>in</strong>s<strong>ch</strong>ließt. Außerdem<br />
hat die Methode e<strong>in</strong>en Rückgabewert vom Typ <strong>in</strong>t. Man kann deshalb Anweisungen<br />
wie<br />
<strong>in</strong>t anzahl = tools.<strong>in</strong>tInput("Geben Sie e<strong>in</strong>e Anzahl an!")<br />
s<strong>ch</strong>reiben. Dabei wird beim Lauf des Programms e<strong>in</strong> Fenster geöffnet und die dort e<strong>in</strong>gegebene<br />
Zahl der Variablen anzahl zugewiesen.<br />
1 public c l a s s Re<strong>ch</strong>teck2 extends <strong>JavaKara</strong>Program {<br />
2 private void reiheLegen ( i n t b r e i t e ){<br />
3 i n t j =0;<br />
4 while ( j
13 i n t j =0;<br />
14 while ( j
Will man Methoden s<strong>ch</strong>reiben, die Werte als Ergebnis liefern, so muss man den Typ des gelieferten<br />
Wertes <strong>in</strong> der Deklaration der Methode angeben. In der Methode muss dann mit return<br />
Wert e<strong>in</strong> Wert passenden Types zurückgegeben werden. Dazu e<strong>in</strong> e<strong>in</strong>fa<strong>ch</strong>es Beispiel:<br />
1 private boolean treeBack ( ) {<br />
2 kara . t u r n L e f t ( ) ;<br />
3 boolean baum = kara . t r e e L e f t ( ) ;<br />
4 kara . turnRight ( ) ;<br />
5 return baum ;<br />
6 }<br />
Aufgaben<br />
3. S<strong>ch</strong>reiben Sie e<strong>in</strong>e Methode boolean mushroomLeft() und e<strong>in</strong>e Methode<br />
boolean mushroomRight() und testen Sie diese <strong>in</strong> geeigneter Umgebung.<br />
6 S<strong>ch</strong>leifen<br />
Bisher s<strong>in</strong>d S<strong>ch</strong>leifen mit der while-Anweisung konstruiert worden:<br />
1 while ( Bed<strong>in</strong>gung ) {<br />
2 Anweisung ( en ) ;<br />
3 }<br />
Der Anweisungsblock wird dabei so lange wiederholt ausgeführt, wie die Bed<strong>in</strong>gung den Wert<br />
true liefert. Es kann also au<strong>ch</strong> vorkommen, dass der Block gar ni<strong>ch</strong>t ausgeführt wird, weil die<br />
Bed<strong>in</strong>gung s<strong>ch</strong>on zu Beg<strong>in</strong>n ni<strong>ch</strong>t erfüllt ist. Man nennt sol<strong>ch</strong>e S<strong>ch</strong>leifen deshalb au<strong>ch</strong> abweisende<br />
S<strong>ch</strong>leifen oder S<strong>ch</strong>leifen mit Vorbed<strong>in</strong>gung.<br />
Mit der Anweisung:<br />
1 do {<br />
2 Anweisung ( en ) ;<br />
3 } while ( Bed<strong>in</strong>gung ) ;<br />
def<strong>in</strong>iert man e<strong>in</strong>e S<strong>ch</strong>leife, deren Anweisungsblock immer e<strong>in</strong>mal ausgeführt wird. Dana<strong>ch</strong><br />
wird erst die Bed<strong>in</strong>gung für e<strong>in</strong>e weitere Wiederholung geprüft. Die Anweisungen sol<strong>ch</strong>er<br />
S<strong>ch</strong>leifen werden also m<strong>in</strong>destens e<strong>in</strong>mal ausgeführt. Diese S<strong>ch</strong>leife ist ni<strong>ch</strong>t abweisend, es ist<br />
e<strong>in</strong>e S<strong>ch</strong>leife mit Na<strong>ch</strong>bed<strong>in</strong>gung.<br />
Im Struktogramm hat die do-while-S<strong>ch</strong>leife folgende Form:<br />
do-while-S<strong>ch</strong>leife<br />
Anweisungsblock<br />
(Bed<strong>in</strong>gung)<br />
17
Beispiele:<br />
1 private void zumBaum ( ) {<br />
2 do {<br />
3 kara . move ( ) ;<br />
4 } while ( ! kara . t r e e F r o n t ( ) ) ;<br />
5 }<br />
KARA bewegt si<strong>ch</strong> zum nä<strong>ch</strong>sten Baum <strong>in</strong> se<strong>in</strong>er Ri<strong>ch</strong>tung und bleibt davor stehen. Man erhält<br />
e<strong>in</strong>e Fehlermeldung, wenn si<strong>ch</strong> KARA beim Methodenstart direkt vor e<strong>in</strong>em Baum bef<strong>in</strong>det.<br />
1 public c l a s s DoBeispiel extends <strong>JavaKara</strong>Program {<br />
2 public void myProgram ( ) {<br />
3 i n t e<strong>in</strong>gabe ;<br />
4 do {<br />
5 e<strong>in</strong>gabe = t o o l s . i n t I n p u t ( ” E<strong>in</strong>e Zahl zwis<strong>ch</strong>en 0 und 100? ” ) ;<br />
6 } while ( ! ( ( e<strong>in</strong>gabe >0)&&(e<strong>in</strong>gabe < 1 0 0 ) ) ) ;<br />
7 t o o l s . showMessage ( ” Ihre Zahl : ”+e<strong>in</strong>gabe ) ;<br />
8 }<br />
9 }<br />
In diesem Fall ma<strong>ch</strong>t die Verwendung e<strong>in</strong>er do-while-S<strong>ch</strong>leife S<strong>in</strong>n, der S<strong>ch</strong>leifenblock muss<br />
m<strong>in</strong>destens e<strong>in</strong>mal dur<strong>ch</strong>laufen werden, da der Benutzer m<strong>in</strong>destens e<strong>in</strong>e E<strong>in</strong>gabe tätigen<br />
muss. Bei Fehle<strong>in</strong>gaben wird die E<strong>in</strong>gabeaufforderung wiederholt.<br />
Sowohl bei der while- als au<strong>ch</strong> bei der do-while-S<strong>ch</strong>leife ist die Anzahl der Wiederholungen<br />
ni<strong>ch</strong>t im voraus festgelegt. In vielen Fällen weiß man aber von vornhere<strong>in</strong>, wie oft e<strong>in</strong> Anweisungsblock<br />
ausgeführt werden soll. Für sol<strong>ch</strong>e Fälle gibt es die for-S<strong>ch</strong>leife.<br />
1 for ( I n i t i a l i s i e r u n g ; Abbru<strong>ch</strong>bed<strong>in</strong>gung ; Inkrement ) {<br />
2 Anweisung ( en ) ;<br />
3 }<br />
Das zugehörige Struktogramm-Element hat folgende Form:<br />
for-S<strong>ch</strong>leife<br />
for Initialisierung; Abbru<strong>ch</strong>bed<strong>in</strong>gung; Inkrement<br />
Beispiele:<br />
1 private void umdrehen ( ) {<br />
2 for ( i n t i =0; i
Das zweite Beispiel ist natürli<strong>ch</strong> ni<strong>ch</strong>t si<strong>ch</strong>er, wenn Bäume oder Pilze existieren, weil KARA<br />
dann mögli<strong>ch</strong>erweise ni<strong>ch</strong>t die angegebene Zahl von S<strong>ch</strong>ritten ma<strong>ch</strong>en kann.<br />
Aufgaben<br />
1. S<strong>ch</strong>reiben Sie die Klasse Re<strong>ch</strong>teck2 (Seite 15) mit Hilfe von for-S<strong>ch</strong>leifen um.<br />
2. Fertigen Sie für das folgende Programm e<strong>in</strong> Struktogramm an und erläutern Sie se<strong>in</strong>e<br />
Funktion.<br />
1 public c l a s s WasIstDas extends <strong>JavaKara</strong>Program {<br />
2 public void move( i n t i ){<br />
3 for ( i n t j =0; j
5. S<strong>ch</strong>reiben Sie e<strong>in</strong>e Klasse Dreieck1 die vom Benutzer<br />
die Anzahl der gewüns<strong>ch</strong>ten Reihen erfragt<br />
und dann den Rand e<strong>in</strong>es entspre<strong>ch</strong>enden<br />
(glei<strong>ch</strong>s<strong>ch</strong>enklig re<strong>ch</strong>tw<strong>in</strong>kligen) Dreieck<br />
aus Blättern legt.<br />
6. S<strong>ch</strong>reiben Sie e<strong>in</strong>e Klasse Quadrat die vom Benutzer<br />
die Anzahl der gewüns<strong>ch</strong>ten Reihen erfragt<br />
und dann den Rand e<strong>in</strong>es entspre<strong>ch</strong>enden<br />
Quadrats aus Blättern legt.<br />
7 Vordef<strong>in</strong>ierte Methoden <strong>in</strong> JAVAKARA<br />
In der Umgebung von JAVAKARA stehen unters<strong>ch</strong>iedli<strong>ch</strong>e Methoden zur Verfügung. Man kann<br />
si<strong>ch</strong> e<strong>in</strong>e Kurzbes<strong>ch</strong>reibung der Methoden mit der Hilfe-S<strong>ch</strong>altflä<strong>ch</strong>e des Welt-Fensters anzeigen<br />
lassen. Die Methoden s<strong>in</strong>d <strong>in</strong> vers<strong>ch</strong>iedene Gruppen e<strong>in</strong>geteilt.<br />
Zunä<strong>ch</strong>st s<strong>in</strong>d e<strong>in</strong>ige der Methoden dazu da, KARA zu Aktionen zu veranlassen:<br />
void move() E<strong>in</strong> Feld vorwärts<br />
void turnLeft() Vierteldrehung na<strong>ch</strong> l<strong>in</strong>ks<br />
void turnRight() Vierteldrehung na<strong>ch</strong> re<strong>ch</strong>ts<br />
void putLeaf() Blatt ablegen<br />
void removeLeaf() Blatt aufnehmen<br />
Die Sensoren werden über Methoden abgefragt, die e<strong>in</strong> Ergebnis vom Typ boolean – also true<br />
oder false – zurückgeben.<br />
boolean treeFront() Baum vorn?<br />
boolean treeLeft() Baum l<strong>in</strong>ks?<br />
boolean treeRight() Baum re<strong>ch</strong>ts?<br />
boolean onLeaf() auf Blatt?<br />
boolean mushroomFront() vor Pilz?<br />
S<strong>ch</strong>ließli<strong>ch</strong> gibt es no<strong>ch</strong> Methoden, KARA direkt auf e<strong>in</strong>em bestimmten Feld zu positionieren<br />
und e<strong>in</strong>e Methode, Karas Position abzufragen.<br />
void setPosition (<strong>in</strong>t x, <strong>in</strong>t y) setzt KARA auf das Feld mit den Koord<strong>in</strong>aten (x; y)<br />
void setDirection(<strong>in</strong>t d) setzt KARAS Ri<strong>ch</strong>tung: 0: Nord, 1: West, 2: Süd, 3: Ost<br />
java.awt.Po<strong>in</strong>t getPosition() liefert KARAS Position <strong>in</strong> Form e<strong>in</strong>es Po<strong>in</strong>t-Objekts<br />
double getX() liefert die x-Komponente e<strong>in</strong>es Po<strong>in</strong>t-Objekts<br />
double getY() liefert die y-Komponente e<strong>in</strong>es Objekts<br />
Alle diese Methoden (außer getX() und getY()) müssen mit dem Prefix kara aufgerufen werden,<br />
also z. B. ni<strong>ch</strong>t move(), sondern kara.move(). Leider gibt es ke<strong>in</strong>e Methode zum Ermitteln von<br />
KARAS Ri<strong>ch</strong>tung.<br />
20
Es gibt au<strong>ch</strong> Methoden zur direkten Veränderung von KARAS Welt. Sie müssen mit dem Prefix<br />
world aufgerufen werden.<br />
void clearAll() Alles entfernen (au<strong>ch</strong> KARA ).<br />
void setLeaf (<strong>in</strong>t x, <strong>in</strong>t y, boolean legen?) legt oder entfernt e<strong>in</strong> Blatt bei (x;y)<br />
void setTree (<strong>in</strong>t x, <strong>in</strong>t y, boolean legen?) legt oder entfernt e<strong>in</strong>en Baum bei (x;y)<br />
void setMushroom (<strong>in</strong>t x, <strong>in</strong>t y, boolean legen?) legt oder entfernt e<strong>in</strong>en Pilz bei (x;y)<br />
void setSize (<strong>in</strong>t xMax, <strong>in</strong>t yMax) Neue Größe der Welt festlegen<br />
<strong>in</strong>t getSizeX() horizontale Weltgröße zurückgeben<br />
<strong>in</strong>t getSizeY() vertikale Weltgröße zurückgeben<br />
boolean isEmpty(<strong>in</strong>t x,<strong>in</strong>t y) true , falls Feld (x;y) leer ist<br />
boolean isTree(<strong>in</strong>t x,<strong>in</strong>t y) true , falls e<strong>in</strong> Baum auf Feld (x;y) ist<br />
boolean isLeaf(<strong>in</strong>t x,<strong>in</strong>t y) true , falls e<strong>in</strong> Blatt auf Feld (x;y) ist<br />
boolean isMushroom(<strong>in</strong>t x,<strong>in</strong>t y) true , falls e<strong>in</strong> Pilz auf Feld (x;y) ist<br />
Die nun folgenden Methoden s<strong>in</strong>d <strong>in</strong> der Klasse tools def<strong>in</strong>iert, müssen also mit dem Prefix<br />
tools aufgerufen werden. Diese Methoden s<strong>in</strong>d vor allem für E<strong>in</strong>- und Ausgaben nützli<strong>ch</strong>. Der<br />
Typ str<strong>in</strong>g ist für Zei<strong>ch</strong>enketten (also Texte) bestimmt.<br />
void showMessage(Str<strong>in</strong>g text) gibt text <strong>in</strong> e<strong>in</strong>em Dialogfenster aus<br />
Str<strong>in</strong>g str<strong>in</strong>gInput(Str<strong>in</strong>g Titel) fordert die E<strong>in</strong>gabe e<strong>in</strong>es Str<strong>in</strong>gs <strong>in</strong> e<strong>in</strong>em Dialogfenster.<br />
Titel liefert die Fensterübers<strong>ch</strong>rift.<br />
Die Rückgabe ist die Konstante null, falls<br />
die E<strong>in</strong>gabe abgebro<strong>ch</strong>en wird.<br />
<strong>in</strong>t <strong>in</strong>tInput(Str<strong>in</strong>g Titel) E<strong>in</strong>gabe e<strong>in</strong>er ganzen Zahl <strong>in</strong> e<strong>in</strong>em Dialogfenster<br />
mit der Übers<strong>ch</strong>rift Titel. Das Ergebnis ist<br />
Integer.MIN_VALUE, wenn die E<strong>in</strong>gabe abgebro<strong>ch</strong>en<br />
wird oder ke<strong>in</strong>e ganze Zahl e<strong>in</strong>gegeben wird.<br />
double doubleInput(Str<strong>in</strong>g Titel) E<strong>in</strong>gabe e<strong>in</strong>er Dezimalzahl <strong>in</strong> e<strong>in</strong>em Dialogfenster<br />
mit der Übers<strong>ch</strong>rift Titel. Das Ergebnis ist<br />
Double.MIN_VALUE, wenn die E<strong>in</strong>gabe abgebro<strong>ch</strong>en<br />
wird oder ke<strong>in</strong>e Dezimalzahl e<strong>in</strong>geben wird.<br />
<strong>in</strong>t random(<strong>in</strong>t Obergrenze) liefert e<strong>in</strong>e Zufallszahl aus dem<br />
Intervall [0; Obergrenze]<br />
void sleep(<strong>in</strong>t ms) stoppt die Programmausführung für ms Millisekunden<br />
void <strong>ch</strong>eckState() überprüft die Bedienungsleiste.<br />
Unter Verwendung dieser Methoden kann man viele <strong>in</strong>teressante kle<strong>in</strong>e Probleme behandeln.<br />
Aufgaben<br />
1. Erzeugen Sie e<strong>in</strong>e 20 × 20-Welt, umranden Sie sie mit Bäumen und setzen Sie KARA auf<br />
das Feld (10|10) mit Ri<strong>ch</strong>tung Norden.<br />
2. S<strong>ch</strong>reiben Sie e<strong>in</strong>e Klasse, die die Anzahl der Bäume e<strong>in</strong>er Welt ermittelt und <strong>in</strong> e<strong>in</strong>em<br />
Message-Fenster ausgibt.<br />
ANLEITUNG: Ermitteln Sie die Breite und Höhe der Welt und untersu<strong>ch</strong>en Sie <strong>in</strong> e<strong>in</strong>er<br />
doppelten for-S<strong>ch</strong>leife die Felder der Welt darauf, ob auf ihnen e<strong>in</strong> Baum steht. KARA<br />
wird dazu ni<strong>ch</strong>t benötigt!<br />
21
3. S<strong>ch</strong>reiben Sie e<strong>in</strong>e Klasse, die e<strong>in</strong>e leere 15 × 15-Welt erzeugt und <strong>in</strong> ihr per Zufall 25<br />
Bäume verteilt.<br />
HINWEIS: Verwenden sie die world- und tools-Funktionen. Erzeugen Sie zwei Zufallszahlen,<br />
um die Zeile und Spalte e<strong>in</strong>es Feldes für e<strong>in</strong>en Baum auszuwählen. Bea<strong>ch</strong>ten Sie,<br />
dass ke<strong>in</strong> Feld mehr als e<strong>in</strong>mal ausgewählt werden darf.<br />
4. Lassen Sie KARA auf e<strong>in</strong>em Feld beliebiger Größe e<strong>in</strong>e Zufallswanderung dur<strong>ch</strong>führen.<br />
Bei jedem S<strong>ch</strong>ritt geht KARA zufallsgesteuert e<strong>in</strong> Feld na<strong>ch</strong> vorn oder na<strong>ch</strong> l<strong>in</strong>ks oder<br />
na<strong>ch</strong> re<strong>ch</strong>ts und legt e<strong>in</strong> Blatt ab, falls dort ke<strong>in</strong>es liegt. Zählen Sie die Anzahl der S<strong>ch</strong>ritte,<br />
bis die Welt gefüllt ist.<br />
HINWEIS: Verwenden Sie <strong>in</strong>t random(<strong>in</strong>t n).<br />
5. Ändern Sie das vorige Programm so ab, dass KARA bei belegten Feldern auf se<strong>in</strong>em Weg<br />
das Blatt aufnimmt. Lassen Sie KARA etwa so viele S<strong>ch</strong>ritte tun, wie <strong>in</strong> der vorigen Aufgabe<br />
zum Füllen der Welt benötigt wurden und prüfen Sie, wieviel der Welt dann mit<br />
Blättern bedeckt ist.<br />
6. Man kann mit world.setLeaf(x,y,true) auf dem Feld (x|y) e<strong>in</strong> Blatt ablegen. Man kann<br />
dies verwenden, um Muster zu erzeugen. S<strong>ch</strong>reiben Sie e<strong>in</strong>e Klasse, die e<strong>in</strong>e 20 × 20-Welt<br />
erzeugt, im oberen l<strong>in</strong>ken Eck e<strong>in</strong> zufälliges 4 × 4-Muster aus Kleeblättern erzeugt und<br />
dieses Muster dann auf die ganze Welt kopiert.<br />
⇒<br />
7. Die angezeigten Ziffern sollen jeweils mit e<strong>in</strong>er eigenen Methode erzeugt werden.<br />
Dabei gibt es folgende Vorgaben:<br />
• Jede Ziffer beanspru<strong>ch</strong>t e<strong>in</strong> Re<strong>ch</strong>teck mit 6 × 8 Feldern.<br />
• In den seitli<strong>ch</strong>en Rändern des Re<strong>ch</strong>tecks liegen ke<strong>in</strong>e Blätter.<br />
• die Methode erhält als E<strong>in</strong>gabe die Koord<strong>in</strong>aten des l<strong>in</strong>ken unteren Eckfelds des<br />
Re<strong>ch</strong>tecks.<br />
Die E<strong>in</strong>s kann man beispielsweise wie folgt erzeugen:<br />
1 public void e i ns ( i n t x , i n t y ){<br />
2 for ( i n t i =2; i
8 world . s e t L e a f ( x +2 ,y−6, true ) ;<br />
9 world . s e t L e a f ( x +1 ,y−5, true ) ;<br />
10 }<br />
Analysieren Sie diese Methode und s<strong>ch</strong>reiben Sie Methoden für die restli<strong>ch</strong>en Ziffern.<br />
S<strong>ch</strong>reiben Sie damit e<strong>in</strong>e Klasse, die das oben gezeigte Bild erzeugt.<br />
HINWEIS: Es empfiehlt si<strong>ch</strong>, e<strong>in</strong>e allgeme<strong>in</strong>e Methode<br />
public void s<strong>ch</strong>reibe(<strong>in</strong>t ziffer,<strong>in</strong>t x,<strong>in</strong>t y)<br />
zu s<strong>ch</strong>reiben, die je na<strong>ch</strong> Ziffer die passende S<strong>ch</strong>reibmethode wählt. Dazu sollte man si<strong>ch</strong><br />
ansehen (Internet), wie man Fallunters<strong>ch</strong>eidungen <strong>in</strong> JAVA mit swit<strong>ch</strong> realisiert.<br />
8. S<strong>ch</strong>reiben Sie unter Verwendung der vorigen Aufgabe e<strong>in</strong>e Klasse, die e<strong>in</strong>e natürli<strong>ch</strong>e<br />
Zahl vom Benutzer erfragt und diese Zahl dann <strong>in</strong> e<strong>in</strong>e passende Welt s<strong>ch</strong>reibt.<br />
HINWEIS: Den Divisionsrest von a:b erhält man dur<strong>ch</strong> a % b. Im Berei<strong>ch</strong> der ganzen Zahlen<br />
liefert JAVA immer den ganzzahligen Quotienten ohne Rest, wenn man a/b bere<strong>ch</strong>net.<br />
anders ausgedrückt: Gilt a = q · b + r mit r < b, so ist a/b = q und a % b = r.<br />
9. Von Manfred Eigen (http://de.wikipedia.<br />
org/wiki/Manfred_Eigen) stammt die folgende<br />
Simulation zum Thema Evolution.<br />
Man nehme e<strong>in</strong> 8 × 8-Feld und belege es <strong>in</strong> jedem<br />
der vier Teilquadrate mit e<strong>in</strong>em Symbol,<br />
wie re<strong>ch</strong>ts gezeigt (das vierte ” Symbol“ ist hier<br />
ganz e<strong>in</strong>fa<strong>ch</strong> e<strong>in</strong> leeres Feld). Nun wird folgendes<br />
Verfahren wiederholt, bis nur no<strong>ch</strong> e<strong>in</strong>e<br />
Symbolsorte auf dem Feld ist: Man wählt per<br />
Zufall zwei vers<strong>ch</strong>iedene Felder des Quadrats.<br />
Das Symbol auf dem ersten Feld wird entfernt<br />
und dur<strong>ch</strong> e<strong>in</strong> Symbol von der Art des auf dem<br />
zweiten Feld bef<strong>in</strong>dli<strong>ch</strong>en ersetzt. Startbelegung<br />
S<strong>ch</strong>reiben Sie e<strong>in</strong>e Klasse, die diese Simulation dur<strong>ch</strong>führt.<br />
8 Arrays<br />
Wir wollen den verwendeten Zufallszahlengenerator tools.random(<strong>in</strong>t n) benutzen, um e<strong>in</strong>en<br />
Würfel zu simulieren. Dazu sollen hundert Zufallsszahlen im Berei<strong>ch</strong> von 1 bis 6 erzeugt<br />
werden. Wir wollen die Anzahlen festhalten, mit denen jede der Zahlen erzeugt wird.<br />
Die Zufallszahlen werden mit folgender Methode erzeugt (random(5) erzeugt Zahlen von 0 bis<br />
5):<br />
1 private i n t würfel ( ) {<br />
2 return (1+ t o o l s . random ( 5 ) ) ;<br />
3 }<br />
Zum Mitzählen der e<strong>in</strong>zelnen Ergebnisse könnte man jetzt se<strong>ch</strong>s Variablen def<strong>in</strong>ieren und diese<br />
mit e<strong>in</strong>er Fallunters<strong>ch</strong>eidung bei jedem Ergebnis um e<strong>in</strong>s erhöhen. Dies wäre äußerst umständli<strong>ch</strong>.<br />
Da sol<strong>ch</strong>e und ähnli<strong>ch</strong>e Probleme häufig auftau<strong>ch</strong>en, sehen die meisten Programmierspra<strong>ch</strong>en<br />
au<strong>ch</strong> Datenstrukturen vor, die sol<strong>ch</strong>e Aufgaben vere<strong>in</strong>fa<strong>ch</strong>en.<br />
23
Will man mehrere Daten glei<strong>ch</strong>en Typs gruppieren, verwendet man e<strong>in</strong>en Array (deuts<strong>ch</strong>:<br />
Feld). In e<strong>in</strong>em Array werden e<strong>in</strong>e feste Anzahl von Daten glei<strong>ch</strong>en Typs gespei<strong>ch</strong>ert. Auf die<br />
e<strong>in</strong>zelnen Daten kann man über e<strong>in</strong>en Index zugreifen. In JAVA werden Arrays beispielsweise<br />
wie folgt vere<strong>in</strong>bart:<br />
<strong>in</strong>t[] zahlen={1,2,3,4,5,6};<br />
Diese Anweisung deklariert e<strong>in</strong>e Array-Variable zahlen für 6 E<strong>in</strong>träge vom Typ <strong>in</strong>t, die mit<br />
den <strong>in</strong> den ges<strong>ch</strong>weiften Klammern stehenden Zahlen <strong>in</strong>itialisiert werden. Auf das dritte Element<br />
des Arrays wird mit dem Ausdruck zahlen[2] zugegriffen (die Zählung der Array-<br />
Elemente beg<strong>in</strong>nt mit 0).<br />
Alternativ kann man e<strong>in</strong> Array au<strong>ch</strong> ohne Initialisierung deklarieren und die Zuweisung von<br />
Werten später vornehmen. Mit der folgenden Methode wird die Anzahl der Elemente des Arrays<br />
festgelegt. Bei Grundtypen wie <strong>in</strong>t wird dabei automatis<strong>ch</strong> jedes Element mit e<strong>in</strong>em Standardwert<br />
<strong>in</strong>itialisiert. Für <strong>in</strong>t ist dies 0.<br />
<strong>in</strong>t[] werte=new <strong>in</strong>t[100];<br />
erzeugt e<strong>in</strong>en Array mit 100 Elementen vom Typ <strong>in</strong>t, die alle mit 0 <strong>in</strong>itialisiert werden. Das<br />
Programm könnte dann etwa so aussehen:<br />
1 public void myProgram ( ) {<br />
2 i n t [ ] z=new i n t [ 7 ] ;<br />
3 for ( i n t j =0; j
1 public c l a s s Zufallszahlen1 extends <strong>JavaKara</strong>Program {<br />
2 private i n t [ ] z0 = { 0 , 0 , 0 , 0 , 0 , 0 , 0 } ;<br />
3 / / w ü r f e l u n d a n z e i g e w i e b i s h e r . . .<br />
4 public void myProgram ( ) {<br />
5 for ( i n t i =0; i
Aufgaben<br />
1. S<strong>ch</strong>reiben Sie e<strong>in</strong>e Klasse, wel<strong>ch</strong>e die Bäume, Pilze und Blätter e<strong>in</strong>er Welt mit e<strong>in</strong>em Array<br />
zählt und das Ergebnis anzeigt.<br />
2. Simulieren Sie e<strong>in</strong> Galtonbrett mit Kara als ” Kugel“ und ” Bäumen“ als Stifte.<br />
(Informationen dazu unter http://de.wikipedia.org/wiki/Galtonbrett)<br />
9 Erweiterungen<br />
E<strong>in</strong>e Reihe von Problemen wären e<strong>in</strong>fa<strong>ch</strong>er lösbar, wenn KARA mehr Sensoren hätte. Man kann<br />
eigene Sensoren als Methoden lei<strong>ch</strong>t zusätzli<strong>ch</strong> def<strong>in</strong>ieren.<br />
Beispiel: Es soll e<strong>in</strong> Sensor def<strong>in</strong>iert werden, der e<strong>in</strong>en Pilz l<strong>in</strong>ks von KARA entdeckt.<br />
Dazu muss si<strong>ch</strong> KARA na<strong>ch</strong> l<strong>in</strong>ks drehen, si<strong>ch</strong> merken, ob jetzt vor ihm e<strong>in</strong> Pilz steht und si<strong>ch</strong><br />
dann zurück na<strong>ch</strong> re<strong>ch</strong>ts drehen.<br />
1 public boolean p i l z L i n ks ( ) {<br />
2 kara . t u r n L e f t ( ) ;<br />
3 boolean p i l z =kara . mushroomFront ( ) ;<br />
4 kara . turnRight ( ) ;<br />
5 return p i l z ;<br />
6 }<br />
Na<strong>ch</strong> diesem Verfahren kann man natürli<strong>ch</strong> au<strong>ch</strong> e<strong>in</strong>en Sensor für re<strong>ch</strong>ts von KARA stehende<br />
Pilze def<strong>in</strong>ieren. Allerd<strong>in</strong>gs hat das Verfahren den Na<strong>ch</strong>teil, dass KARA bewegt werden muss,<br />
was die Programmausführung verlangsamt. Will man entspre<strong>ch</strong>end Sensoren def<strong>in</strong>ieren, die<br />
erkennen, ob KARA l<strong>in</strong>ks von, re<strong>ch</strong>ts von oder vor e<strong>in</strong>em Blatt steht, so wird der Aufwand<br />
no<strong>ch</strong> höher, weil der vorhandene Sensor Blätter nur erkennt, wenn KARA auf ihnen steht. Um<br />
zu erkennen, ob KARA vor e<strong>in</strong>em Blatt steht, muss KARA daher e<strong>in</strong>en S<strong>ch</strong>ritt vorwärts ma<strong>ch</strong>en.<br />
Das geht aber ni<strong>ch</strong>t immer. KARA könnte vor e<strong>in</strong>em Baum stehen, dann kann er ke<strong>in</strong>en S<strong>ch</strong>ritt<br />
vorwärts ma<strong>ch</strong>en. Steht er vor e<strong>in</strong>em Pilz, so kann er viellei<strong>ch</strong>t e<strong>in</strong>en S<strong>ch</strong>ritt vorwärts ma<strong>ch</strong>en,<br />
vers<strong>ch</strong>iebt aber dabei den Pilz.<br />
Wenn man die Methoden der Klasse world verwendet, kann man alternativ etwa folgenden<br />
Sensor erzeugen:<br />
1 public boolean leafSouth ( ) {<br />
2 i n t y= ( i n t ) kara . g e t P o s i t i o n ( ) . getY ( ) ;<br />
3 i n t x= ( i n t ) kara . g e t P o s i t i o n ( ) . getX ( ) ;<br />
4 i n t ymax= world . getSizeY () −1;<br />
5 i f ( y==ymax) {<br />
6 return world . i s L e a f ( x , 0 ) ;<br />
7 }<br />
8 e lse {<br />
9 return world . i s L e a f ( x , y + 1 ) ;<br />
10 }<br />
11 }<br />
26
Hier wird zunä<strong>ch</strong>st KARAS Position abgefragt. Das <strong>in</strong> Klammern stehende (<strong>in</strong>t) ist notwendig,<br />
weil die Abfrage die Position als double (Dezimalzahlformat) liefert. Mit (<strong>in</strong>t) wird daraus<br />
(dur<strong>ch</strong> Abs<strong>ch</strong>neiden des hier ohneh<strong>in</strong> ni<strong>ch</strong>t vorhandenen) Na<strong>ch</strong>kommateils e<strong>in</strong>e ganze<br />
Zahl. Außerdem muss berücksi<strong>ch</strong>tigt werden, dass die Welt <strong>in</strong> form e<strong>in</strong>er Torus vorliegt. Wenn<br />
KARA auf der untersten Zeile steht, so ist die oberste Zeile ” südli<strong>ch</strong>“ von KARA . Dem wird mit<br />
der Fallunters<strong>ch</strong>eidung Re<strong>ch</strong>nung getragen.<br />
Entspre<strong>ch</strong>end kann man au<strong>ch</strong> Methoden s<strong>ch</strong>reiben, die KARA <strong>in</strong> e<strong>in</strong>e bestimmte Himmelsri<strong>ch</strong>tung<br />
drehen. Natürli<strong>ch</strong> kann das au<strong>ch</strong> direkt mit kara.setDirection bewerkstelligt werden,<br />
aber e<strong>in</strong>e passende Neudef<strong>in</strong>ition ist e<strong>in</strong>prägsamer:<br />
1 public void turnEast ( ) {<br />
2 kara . s e t D i r e c t i o n ( 3 ) ;<br />
3 }<br />
Wenn man e<strong>in</strong>e Reihe sol<strong>ch</strong>er Def<strong>in</strong>itionen häufiger verwenden will, kann man sie <strong>in</strong> e<strong>in</strong>er eigenen<br />
von <strong>JavaKara</strong>Program abgeleiteten Klasse def<strong>in</strong>ieren. Die ganzen Def<strong>in</strong>itionen der Sensoren<br />
und die Drehungen s<strong>in</strong>d beispielsweise <strong>in</strong> der Klasse KepiKara zusammengestellt. Die<br />
Methode myProgram() wird dabei leer gelassen. Spei<strong>ch</strong>ert man diese Klasse im Verzei<strong>ch</strong>nis der<br />
Datei javakara.jar, so kann man dana<strong>ch</strong> neue Klassen statt von <strong>JavaKara</strong>Program von KepiKara<br />
ableiten und hat dabei sowohl die zu JAVAKARA gehörenden als au<strong>ch</strong> die neudef<strong>in</strong>ierten<br />
Methoden zur Verfügung.<br />
Die folgende Klasse verwendet diese Methode, um e<strong>in</strong>e vere<strong>in</strong>fa<strong>ch</strong>te Fassung von Pacman zu<br />
erzeugen:<br />
1 import javakara . <strong>JavaKara</strong>Program ;<br />
2 public c l a s s PacmanNeu extends KepiKara {<br />
3 private void nextLeaf ( ) {<br />
4 i f ( l e a f E a s t ( ) ) {<br />
5 turnEast ( ) ;<br />
6 }<br />
7 e lse i f ( leafNorth ( ) ) {<br />
8 turnNorth ( ) ;<br />
9 }<br />
10 e lse i f ( leafWest ( ) ) {<br />
11 turnWest ( ) ;<br />
12 }<br />
13 e lse {<br />
14 turnSouth ( ) ;<br />
15 }<br />
16 kara . move ( ) ;<br />
17 kara . removeLeaf ( ) ;<br />
18 }<br />
19<br />
20 public void myProgram ( ) {<br />
21 kara . removeLeaf ( ) ;<br />
22 while ( ! kara . t r e e F r o n t ( ) ) {<br />
23 nextLeaf ( ) ;<br />
24 }<br />
25 }<br />
26 }<br />
27