Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

23
Einf ¨ uhrung in R UBY K ARA Gerhard Bitsch * Kepler-Gymnasium T ¨ ubingen 24. August 2008 1 Die RUBY KARA -Umgebung Die Programmierumgebung RUBYKARA erlaubt es, Kara mit der Programmiersprache RUBY zu steuern. Dazu stellt RUBYKARA einen kleinen Programmeditor zur Verf ¨ ugung, der beim Aufruf ei- nige Programmierhinweise und ein einfaches Programm enth¨ alt. Befehle f ¨ ur KARA ussen mit einem vorgestellten kara. ge- schrieben werden, also etwa kara.move, um KARA ein Feld nach vorn zu bewegen. Dieses Programm ist unmittel- bar ausf ¨ uhrbar. Man muss ledig- lich den entsprechenden Knopf in der KARA -Welt bet¨ atigen. Der gr ¨ un gef¨ arbte untere Teil des Programmfensters dient zur Ausgabe von Fehlermeldungen. Das im Bild dargestellte Programm zeigt schon einige Besonderheiten der Programmierung mit RUBY im Gegensatz zum Automatenmodell. Der grau dargestellte obere Fensterteil enth¨ alt Kommentare, die einige der zur Verf¨ ugung ste- henden Befehle darstellen. Ein Kommentar beginnt mit dem Zeichen #. Kommentare werden vom Programm w¨ ahrend des Ablaufs ignoriert. Sie sollen lediglich die Verst¨ andlichkeit von Code verbessern. Das im Beispiel angezeigte Programm lasst KARA bis zum n¨ achsten Baum laufen und dort stehen bleiben. * mailto:[email protected] 1

Transcript of Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

Page 1: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

Einfuhrung in RUBYKARA

Gerhard Bitsch∗

Kepler-Gymnasium Tubingen

24. August 2008

1 Die RUBYKARA -Umgebung

Die ProgrammierumgebungRUBYKARA erlaubt es, Kara mitder Programmiersprache RUBY

zu steuern.Dazu stellt RUBYKARA einenkleinen Programmeditor zurVerfugung, der beim Aufruf ei-nige Programmierhinweise undein einfaches Programm enthalt.Befehle fur KARA mussen miteinem vorgestellten kara. ge-schrieben werden, also etwakara.move, um KARA ein Feldnach vorn zu bewegen.Dieses Programm ist unmittel-bar ausfuhrbar. Man muss ledig-lich den entsprechenden Knopfin der KARA -Welt betatigen.

Der grun gefarbte untere Teil des Programmfensters dient zur Ausgabe von Fehlermeldungen.

Das im Bild dargestellte Programm zeigt schon einige Besonderheiten der Programmierungmit RUBY im Gegensatz zum Automatenmodell.

Der grau dargestellte obere Fensterteil enthalt Kommentare, die einige der zur Verfugung ste-henden Befehle darstellen. Ein Kommentar beginnt mit dem Zeichen #. Kommentare werdenvom Programm wahrend des Ablaufs ignoriert. Sie sollen lediglich die Verstandlichkeit vonCode verbessern.

Das im Beispiel angezeigte Programm lasst KARA bis zum nachsten Baum laufen und dortstehen bleiben.

∗mailto:[email protected]

1

Page 2: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

Das Bild zeigt ein Automatenprogramm mitder gleichen Wirkung. Die Anweisung, dassKARA , wenn er vor keinem Baum steht, einenSchritt machen soll und dann im ZustandFindeBaum bleiben soll, wird mit der while-Anweisung ubertragen (while ' solange). DerSchrittbefehl ist kara.move.

Mit kara.treeFront wird der Sensor abgefragt. Diese Abfrage liefert true, falls KARA voreinem Baum steht und false andernfalls. Der Operator not steht fur die Negation, d.h. ervertauscht die Werte true und false.

2 Einfache Anweisungen in RUBY

In diesem Abschnitt werden einfache RUBY -Anweisungen zur Strukturierung von Program-men vorgestellt. RUBY ist eine objektorientierte Sprache, die nicht kompiliert, sondern inter-pretiert wird. Das bedeutet, dass jeder Ausdruck in einem Programm unmittelbar vor derAusfuhrung in Anweisungen fur den Rechner ubersetzt wird. Das hat den Vorteil, dass manauch einzelne Anweisungen direkt austesten kann. Der Nachteil solcher Programme besteht inihrem gegenuber kompilierten Programmen deutlich langsameren Ablauf.

Die Objektorientierung hat in RUBY zur Folge, dass selbst Zahlen als Objekte definiert sind, diegewisse Methoden zur Verfugung stellen.

Bedingungen: Beim Automatenmodell wird ein unterschiedliches Verhalten von KARA durch die Zu-stande der Sensoren gesteuert. In RUBY kann man diese Sensoren abfragen. Sie lieferndabei einen der Werte true oder false . Ausdrucke mit der Eigenschaft, einen dieser Wertezu liefern, nennt man Bedingungen.

Bedingungen konnen mit aussagenlogischen Operatoren verknupft werden. Die folgen-de Tabelle gibt das Ergebnis einer solchen Verknupfung fur zwei Bedingungen a und bwieder:

a b not a a and b a or bnicht und oder

true true false true truetrue false false false truefalse true true false truefalse false true false false

An Stelle von not kann man auch !, fur and auch && und fur or auch || verwenden.

Beispiele:

not kara.onLeaf hat den Wert true , falls KARA auf einem leeren Feld steht.

kara.treeLeft and kara.treeRight hat den Wert true , falls links und rechts vonKARA ein Baum steht.

kara.treeFront or kara.onLeaf hat den Wert true , falls mindestens eine der beidenBedingungen zutrifft.

while: Die while-Schleife, die schon im vorigen Abschnitt angesprochen wurde, hat folgendeGestalt:

2

Page 3: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

while Bedingung

Anweisung1

... Diese Anweisungen bilden einen Block

Anweisungn

end

Bei der Ausfuhrung einer while-Anweisung wird zunachst die Bedingung uberpruft.Liefert sie den Wert true , so werden die Anweisungen (jeweils durch einen Zeilenwechselabgeschlossen) nacheinander ausgefuhrt. Anschließend beginnt der Vorgang mit der Uber-prufung der Bedingung neu. Dies wird so lange wiederholt, bis die Bedingung den Wertfalse liefert.

Verzweigung: Verzweigungen entstehen, wenn je nach dem Wert einer Bedingung unterschiedliche An-weisungen ausgefuhrt werden. Die allgemeine Form ist:

if Bedingung

Anweisungen falls true

else

Anweisungen falls false

end

Beispiel:

1 i f kara . onLeaf // f a l l s Kara auf einem B l a t t s t e h t2 kara . removeLeaf // B l a t t ent fernen3 e lse // a n d e r n f a l l s4 kara . putLeaf // B l a t t ablegen5 end

Soll keine Anweisung ausgefuhrt werden, wenn die Bedingung nicht erfullt ist, so kannman den else-Teil der Anweisung weglassen.

Beispiel:

1 i f kara . t r e e F r o n t // f a l l s Kara vor einem Baum s t e h t2 kara . t u r n L e f t // nach l i n k s drehen3 end // ansonsten n i c h t s tun ,4 // Programm f o r t s e t z e n

Methoden: Man kann auch eigenen Methoden definieren, die dann wie die in der Umgebung vor-handenen Methoden verwendet werden konnen. Es gibt dafur mehrere Moglichkeiten,die einfachste fuhren wir jetzt ein.

def Methodenname(Parameter)

Anweisungen

end

Der zwischen def und end eingeschlossene Programmtext wird bei der Ausfuhrung desProgramms zunachst nicht durchgefuhrt, sondern nur als Methode ”registriert“, die imweiteren Programm verwendet werden kann. Beim Aufruf der Methode muss fur ihre Pa-rameter jeweils ein Objekt ubergeben werden, das im Text der Methode fur den entspre-chenden Parameter eingesetzt wird. Danach erst wird die Methode durchgefuhrt. Dies ist

3

Page 4: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

vergleichbar zur Definition einer Funktion in der Mathematik in der Form f(x) = ...x...,bei der zur Berechnung bestimmter Funktionswerte fur x ein Wert eingesetzt wird, mitdem dann die rechte Seite der Definition ausgewertet wird.

Beispiel: KARA soll zum nachsten Baum gehen, sich dort umdrehen und weiter laufenund dies endlos wiederholen.

1 @kara=kara2 def drehen3 2 . t imes {@kara . t u r n L e f t }4 end5

6 while true7 drehen i f kara . t r e e F r o n t8 kara . move9 end

Das Programm muss gespeichert werden, ehe man es starten kann.

KARA ist (momentan) fur Methoden nicht verfugbar. Mit der ersten Zeile @kara=karawird KARA an die globale Variable @kara gebunden und kann auch von Methoden ver-wendet werden. Man sollte diese Zuweisung immer an den Anfang einer neuen Pro-grammdatei stellen.

Die Methode times wiederholt den durch geschweifte Klammern abgetrennten Block sooft, wie die ganze Zahl, fur die times aufgerufen wurde angibt.

Eine weitere Besonderheit ist die Verwendung von if in der while-Schleife als Modifika-tor. Der vor if stehende Ausdruck wird nur ausgewertet, wenn die hinter if stehendeBedingung erfullt ist.

Die Schleife lauft endlos, weil die hinter while stehende Schleifenbedingung nie falschwerden kann.

3 Struktogramme

Struktogramme ermoglichen es, den Ablauf eines Programms graphisch zu entwerfen. Das gan-ze Programm wird in einem Rechteck eingetragen. Schleifen, Fallunterscheidungen und Me-thodenaufrufe (fur selbstgeschriebene Methoden) werden wie folgt dargestellt:

• while-SchleifenSchleifenbedingung

Ausdruck1

· · ·Ausdruckn

4

Page 5: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

• FallunterscheidungenPPPPPPPPPPP

�����������

Bedingung

T FTrue-Teil False-Teil

• MethodenaufrufeMethode

Beispiel:

Hier ist ein einfaches Beispiel fur ein Struktogramm zu einem RUBYKARA -Programm. KARA

soll zum nachsten Baum laufen und unterwegs alle Felder invertieren, d.h. auf Feldern mit Blattdas Blatt wegnehmen und auf Feldern ohne Blatt ein Blatt ablegen.

ZumBauminvertiereFeld

not treeFrontmove

invertiereFeld

In diesem Struktogramm wird eine Anweisung verwendet, die KARA nicht kennt: invertiereFeld.Diese Anweisung wird als Methode implementiert. Das zugehorige Struktogramm ist:

invertiereFeld()PPPPPPPPPPP

�����������

onLeaf

T FremoveLeaf putLeaf

Diese Struktogramme ubersetzen sich in folgendes RUBYKARA -Programm:

1 @kara=kara2 def i n v e r t i e r e F e l d3 i f @kara . onLeaf4 @kara . removeLeaf5 e lse6 @kara . putLeaf7 end8 end9

10 i n v e r t i e r e F e l d11 while ! kara . t r e e F r o n t

5

Page 6: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

12 kara . move13 i n v e r t i e r e F e l d14 end

4 Variablen

Aufgabe: KARA soll zu einem Baum laufen, sich umdrehen und dann weiter laufen. Das soller funf mal wiederholen.

Im Automatenmodell wurden fur diese Aufgabe funf Zustande benotigt. Andert man die An-zahl der Wiederholungen, so andert sich die Anzahl der benotigten Zustande entsprechend. Esgibt im Automatenmodell keine einfache Moglichkeit, beliebig weit zu zahlen.

In RUBYKARA kann man zahlen, indem man Variablen verwendet. Variablen bieten eine Mog-lichkeit, Daten im Speicher des Rechners abzulegen und zu verandern. Dazu muss man sichden Speicherort merken, um auf die gespeicherten Daten zugreifen zu konnen. Zu diesemZweck werden Variablen verwendet. In RUBY erfolgt das durch die Angabe eines Namens undeines Anfangswertes:

zahler = 0

Diese Anweisung erzeugt eine Variable zahler und speichert 0 als Wert dieser Variablen.

Wenn man sich ein Gedankenmodell fur Variable machen will, kann man sich folgendes vorstel-len: mit einer Deklaration einer Variablen wird eine Schachtel passender Große angefertigt undmit einem Namensschild versehen. Ist ein Anfangswert angegeben, so wird dieser auf einenZettel geschrieben und der Zettel in die Schachtel gelegt. Die Schachtel kommt in ein Lager,wo sie uber den aufgeklebten Namen wieder gefunden werden kann.

Nun soll mit Hilfe einer Variablen das anfangs gestellte Problem gelost werden. Zunachst einStruktogramm:

FunfRundenint runden← 0

runden < 5hhhhhhhhhhhhhhhh

������

treeFrontW F

drehenrunden← runden + 1

move

Die Zuweisung eines Wertes zu einer Variablen symbolisiert man im Struktogramm durcheinen linksgerichteten Pfeil ←. Besonders interessant ist dabei die Zuweisung in der Fallun-terscheidung. Sie zeigt an, dass der Variable runden ihr um 1 erhohter alter Wert zugewiesenwerden soll. Da dies jedesmal geschieht, wenn KARA vor einem Baum steht, zahlt diese Va-riable die von KARA zuruckgelegten Runden. Nach 5 Runden hat die Variable den Wert 5, dieSchleifenbedingung ist also nicht mehr erfullt und KARA bleibt stehen.

Im zugehorige RUBYKARA -Programm wird die Zuweisung von Werten an die Variable rundenmit dem Gleichheitszeichen = geschrieben. Diese Verwendung entspricht naturlich nicht demGebrauch von = in der Mathematik, ist aber in vielen Programmiersprachen ublich. Fur Ver-gleiche von Zahlen kann man mit <, >, == Bedingungen formulieren (das doppelte Gleich-heitszeichen uberpruft die Gleichheit zweier Zahlen).

6

Page 7: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

1 z ah ler = 02

3 while z ah ler < 54 i f kara . t r e e F r o n t5 2 . t imes {kara . t u r n L e f t }6 z ah ler = z ah ler + 17 e lse8 kara . move9 end

10 end

AufgabenFertigen Sie fur die folgenden Aufgaben jeweils ein Struktogramm an, ehe Sie versuchen dasProgramm zu erstellen. verwenden Sie wo moglich eigene Methoden.

1. Bearbeiten Sie die Aufgabe Tunnelsucher II und die drei Aufgaben zur Kleeblattsuche imWald.

2. Bearbeiten Sie die Aufgabe Pacman.

3. KARA soll ein 4× 5-Rechteck mit Blattern belegen.

4. KARA soll ein Schachbrett (8×8) auslegen (weisse Felder leer, schwarze Felder mit Blatt).

LosungenAufgabe 1:

Tunnelsucher:

Den zwei benotigten Zustanden fur dieses Problem im Automatenmodell entsprechen hierzwei while-Schleifen.TunnelEnde

not(treeLeft and treeRight)move

treeLeft and treeRightmove

Das zugehorige Programm:

1 kara . move while not ( kara . t r e e L e f t and kara . t r e e R i g h t )2 kara . move while kara . t r e e L e f t and kara . t r e e R i g h t

Wald I

Das Struktogramm verwendet die Methode umBaum, die noch definiert werden muss.

Wald Inot onLeafXXXXXXXXXXX

�����������

treeFrontT F

umBaum moveremoveLeaf

7

Page 8: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

Das zugehorige Programm:

1 @kara=kara2 def umBaum3 @kara . t u r n L e f t4 @kara . move5 @kara . turnRight6 2 . t imes {@kara . move}7 @kara . turnRight8 @kara . move9 @kara . t u r n L e f t

10 end11

12 while not kara . onLeaf13 i f kara . t r e e F r o n t14 umBaum15 e lse16 kara . move17 end18 end19 kara . removeLeaf

Wald II

Hier muss lediglich die Methode umBaum angepasst werden. Der mittlere Teil mit den zweimove-Befehlen muss ersetzt werden durch eine Schleife, um beliebig viele Baume zu umgehen:

1 def umBaum2 @kara . t u r n L e f t3 @kara . move4 @kara . turnRight5 @kara . move6 @kara . move while @kara . t r e e R i g h t7 @kara . turnRight8 @kara . move9 @kara . t u r n L e f t

10 end

Wald III

Hier wird eine Unterscheidung von drei verschiedenen Fallen benotigt: Baum vorn, Baum linksund Baum rechts. Man erledigt das mit einer geschachtelten Fallunterscheidung. Man pruftzunachst, ob vorn ein Baum steht. Ist dies nicht der Fall, pruft man, ob rechts oder links einBaum steht.

Man erhalt folgendes Struktogramm:

8

Page 9: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

Wald3not onLeaf

PPPPPPPPPPPPPPPPPPPPP

��

���

��

treeFront

T FPPPPPPPPPPP

�����������

not treeLeft

T FturnLeft turnRight

moveremoveLeaf

Dies fuhrt zu folgendem Programm. Die geschachtelte Fallunterscheidung wird aus dem Struk-togramm so ubertragen, dass innerhalb der ersten Fallunterscheidung eine zweite eingefugtwird. Dies lasst sich beliebig oft wiederholen.

1 while not kara . onLeaf2 i f kara . t r e e F r o n t3 i f not kara . t r e e L e f t4 kara . t u r n L e f t5 e lse6 kara . turnRight7 end8 end9 kara . move

10 end11 kara . removeLeaf

Aufgabe 2:

Pacman

Dieses Programm benotigt eine Schleife und innerhalb der Schleife eine geschachtelte Fallun-terscheidung. Im ersten Fall ist nichts zu tun, falls KARA auf einem Blatt ist, im anderen Fallmuss KARA das nachste Blatt erst lokalisieren und sich auf das Feld mit dem Blatt begeben. DieSchleife hat also als Invariante die Bedingung, dass KARA auf einem Blatt stehen muss. Dieseswird am Ende jedes Schleifendurchgangs entfernt.

9

Page 10: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

PacmanremoveLeaf

not treeFrontmovehhhhhhhhhhhhhhhhhhhhhhhhh

�����

����

not onLeaf

T F

zuruckturnRight

movehhhhhhhhhhhhhhhhhhh

�������

not onLeafT F

zuruckmove ∅

removeLeaf

Um KARA auf das nachste Blatt zu bewegen wird die Methode zuruck verwendet. Das benotig-te Struktogramm fur die Methode zuruck ist:

zuruckturnLeft()turnLeft()

move()

Daraus erhalt man das folgende Programm:

1 @kara=kara2 def zuruck # u m d r e h e n u n d z u r u c k

3 2 . t imes {@kara . t u r n L e f t }4 @kara . move5 end6

7 kara . removeLeaf8 while not kara . t r e e F r o n t9 kara . move

10 i f not kara . onLeaf # k e i n B l a t t v o r n

11 zuruck12 kara . turnRight13 kara . move14 i f not kara . onLeaf # n i c h t s l i n k s

15 zuruck16 kara . move # n a c h r e c h t s !

17 end18 end19 kara . removeLeaf # h i e r m u s s w a s l i e g e n

20 end

10

Page 11: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

Aufgabe 3:

Fur das Rechteck erhalt man zunachst eine Programmstruktur mit zwei ineinander geschach-telten Schleifen. Eine außere Schleife ist fur die aufeinanderfolgende Anordnung der Reihendes Rechtecks zustandig, in einer inneren Schleife wird jeweils eine einzelne Reihe ausgege-ben.

Rechteck4 mal

reiheLegen()nachsteReihe()

Das Legen einer Reihe wird als Methode formuliert und mit einer Schleife realisiert:

reiheLegen

5 malputLeaf()move()

nachsteReihe()2 mal turnLeft()

5 malmove()

turnLeft()move()

turnLeft()

Der Wechsel zur nachsten Reihe ist ebenfalls als Methode realisiert. KARA geht zum Anfang dervorigen Reihe und wechselt dann in die zu legende neue Reihe. Das scheint umstandlich, aberfur abwechselnde Links- und Rechtsdurchgange benotigt man jetzt noch nicht besprocheneHilfsmittel. Das folgende Programm zeichnet das gewunschte Rechteck.

1 @kara=kara2 def reiheLegen3 5 . t imes do4 @kara . putLeaf5 @kara . move6 end7 end8

9 def nachsteReihe10 2 . t imes {@kara . t u r n L e f t }11 5 . t imes {@kara . move}12 @kara . t u r n L e f t13 @kara . move14 @kara . t u r n L e f t15 end16

17 4 . t imes do18 reiheLegen19 nachsteReihe20 end

Aufgabe 4

11

Page 12: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

Diese Aufgabe ist eine Variante des Rechteck-Problems. Allerdings mussen zwei aufeinanderfolgende Reihen um eins gegeneinander versetzt gelegt werden. Die folgenden Struktogrammebeschreiben eine mogliche Losung.

Schachbrett4 mal

reiheLegen1()nachsteReihe()reiheLegen2()nachsteReihe()

Die Methoden reiheLegen1() und reiheLegen2 unterscheiden sich nur geringfugig.

reiheLegen1

4 malputLeaf

2 mal move

reiheLegen2

4 malmove

putLeafmove

Die Methode nachsteReihe() wird durch folgendes Struktogramm beschrieben:

nachsteReihe()2 mal turnLeft

8 mal moveturnLeft

moveturnLeft

Das fertige Programm sieht dann so aus:

1 @kara=kara2 def reiheLegen13 4 . t imes do4 @kara . putLeaf5 2 . t imes {@kara . move}6 end7 end8

9 def reiheLegen210 4 . t imes do11 @kara . move12 @kara . putLeaf13 @kara . move14 end15 end16

17 def nachsteReihe18 2 . t imes {@kara . t u r n L e f t }19 8 . t imes {@kara . move}20 @kara . t u r n L e f t

12

Page 13: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

21 @kara . move22 @kara . t u r n L e f t23 end24

25 # H a u p t p r o g r a m m

26 4 . t imes do27 reiheLegen128 nachsteReihe29 reiheLegen230 nachsteReihe31 end

5 Methoden mit Parametern und Ruckgabewerten, Eingaben undAusgaben

Haufig will man einer Methode beim Aufruf Informationen ubergeben, die den Ablauf derMethode beeinflussen konnen. Bisher wurde nur das Objekt kara an Methoden ubergeben. Oftwill man aber weitere Informationen zur Steuerung der Methode ubergeben.

Als erstes Beispiel soll das erlautern. Es soll eine Methode reiheLegen(n) vorgestellt werden,die KARA veranlasst, n Schritte zu gehen und dabei auf nicht belegten Feldern ein Blatt abzu-legen.

1 def reiheLegen ( n )2 n . t imes do3 @kara . putLeaf i f not @kara . onLeaf4 @kara . move5 end6 end

Ruft man diese Methode beispielsweise mit reiheLegen(7) auf, so bewegt sich KARA 7 Felderin seiner gegenwartigen Richtung und belegt alle leeren Felder, die er passiert mit einem Blatt.Das letzte Feld, auf dem KARA stehen bleibt, wird nicht belegt. Das Ausgangsfeld hingegenwird belegt.

Im Unterschied zu den bisherigen Definitionen von Methoden steht hier in der Klammer hinterdem Methodennamen ein Parameter.

Beim Aufruf einer Methode mit Parametern mussen in die Klammern hinter dem Methoden-namen Ausdrucke fur die Parameter eingetragen werden (durch Kommata getrennt, falls esmehrere Parameter gibt). Rechenausdrucke sind bei der Parameterubergabe erlaubt.

Aufgaben:

1.1 def reiheLegen ( n )2 n . times do3 @kara . move4 @kara . putLeaf i f not @kara . onLeaf5 end6 end

Was andert sich bei der MethodereiheLegen(n), wenn sie wie ne-ben stehend formuliert wird?

13

Page 14: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

2. Schreiben Sie eine Methode turnLeft(int anzahl) und eine Methode turnRight(intanzahl), die KARA veranlasst, sich so oft nach links bzw. rechts zu drehen, wie anzahlangibt. Programmieren Sie ein passendes Verhalten fur negative Werte von anzahl.

3. Verandern Sie das Schachbrettprogramm (Seite 7) so, dass nur eine Methode zum Legender Reihen benotigt wird und die Große des Schachbretts variabel gehalten wird.

In vielen Fallen mochte man erst zur Laufzeit Daten eingeben konnen. Dazu stellt RUBYKARA

unter anderen (Seite 18) die Methode intInput(Titel) zur Verfugung. Diese Methode wirdnun verwendet, um das Rechteck-Programm zu verallgemeinern. intInput benotigt als Pa-rameter eine Eingabeaufforderung in Form eines Strings (Zeichenkette). Strings werden ein-gegeben, indem man den gewunschten Text in Anfuhrungszeichen einschließt. Außerdem hatdie Methode eine ganze Zahl als Ruckgabewert. Dazu wird durch die Methode ein Fenster mitdem Text als Eingabeaufforderung und einem Eingabefeld geoffnet. In dieses Feld wird diegewunschte Zahl eingegeben.

Man kann deshalb Anweisungen wie

anzahl = tools.intInput("Geben Sie eine Anzahl an!")

schreiben. Dabei wird beim Lauf des Programms ein Fenster geoffnet und die dort eingegebeneZahl der Variablen anzahl zugewiesen. Fur das Rechteckprogramm benotigt man nur kleineAnderungen:

1 @kara=kara2 def reiheLegen ( n )3 n . t imes do4 @kara . putLeaf5 @kara . move6 end7 end8

9 def nachsteReihe ( n )10 2 . t imes {@kara . t u r n L e f t }11 n . t imes {@kara . move}12 @kara . t u r n L e f t13 @kara . move14 @kara . t u r n L e f t15 end16

17 # H a u p t p r o g r a m m

18 hoehe = t o o l s . i n t I n p u t ( ”Hohe des Rechtecks ? ” )19 b r e i t e = t o o l s . i n t I n p u t ( ” B r e i t e des Rechtecks ? ” )20 hoehe . t imes do21 reiheLegen ( b r e i t e )22 nachsteReihe ( b r e i t e )23 end

KARA soll nun zu einem Baum laufen, die Anzahl der Schritte zahlen, zu seinem Ausgangs-punkt zuruckkehren und die Anzahl der Schritte bis zum Baum ausgeben.

Fur die Ausgabe verwenden wir die Methode (Seite 18) tools.showMessage(String Text).Die Schritte werden in einer Variablen mitgezahlt. Dies fuhrt zu folgendem Programm.

14

Page 15: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

1 s c h r i t t e =02 while not kara . t r e e F r o n t3 kara . move4 s c h r i t t e +=15 end6 2 . t imes {kara . t u r n L e f t }7 1 . upto ( s c h r i t t e ) {kara . move}8 2 . t imes {kara . t u r n L e f t }9 t o o l s . showMessage ( ”Zum Baum sind es #{ s c h r i t t e } S c h r i t t e . ” )

Besondere Beachtung verdient die Art, wie hier der Text der Meldung zusammengestellt wird.In RUBY wird Text (Datentyp: String) durch Anfuhrungszeichen begrenzt. Werte von Variablenoder Ausdrucken konnen mit dem Konstrukt #{...} in Text eingefugt werden. RUBY wandeltin diesem Fall die Ausdrucke mit der Methode to s in ihre Textdarstellung um.

Man kann auch Methoden schreiben, die Werte als Ergebnis liefern, das zu weiteren Berechnun-gen verwendet werden kann. In der Methode wird dann mit return Wert ein Wert passendenTypes zuruckgegeben. Dazu ein einfaches Beispiel. Die Methode treeBack? liefert true , fallshinter KARA ein Baum ist.

1 @kara=kara2 def t reeBack ?3 @kara . t u r n L e f t4 erg=@kara . t r e e L e f t5 @kara . turnRight6 return erg7 end

Aufgaben

3. Schreiben Sie eine Methode mushroomLeft? und eine Methode

mushroomRight? und testen Sie diese in geeigneter Umgebung.

6 Schleifen

Bisher sind Schleifen mit nicht vorherbestimmter Anzahl von Wiederholungen mit der while-Anweisung konstruiert worden

1 while Bedingung do2 Anweisung ( en )3 end

Der Anweisungsblock zwischen do und end wird dabei so lange wiederholt ausgefuhrt, wie dieBedingung den Wert true liefert. Es kann also auch vorkommen, dass der Block gar nicht aus-gefuhrt wird, weil die Bedingung schon zu Beginn nicht erfullt ist. Man nennt solche Schleifendeshalb auch abweisende Schleifen oder Schleifen mit Vorbedingung.

Fur Schleifen mit einer festen Anzahl n von Wiederholungen wurde die Iteration

1 n . t imes {Anweisung}

15

Page 16: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

oder

1 1 . upto{n} do | i |2 # A n w e i s u n g e n d i e d e n j e w e i l i g e n W e r t v o n i v e r w e n d e n

3 end

verwendet. An Stelle der Konstruktion

while not Bedingung do ... kann man auch

until Bedingung do ... verwenden. Beide Schleifenkonstrukte konnen auch als Modifikato-ren verwendet werden:

Beispiele:

kara.move until kara.treeFront

x=0x=x+1 while x<100

eingabe=-1eingabe=tools.intInput("Zahl eingeben") until (eingabe>0) and (eingabe<100)

ACHTUNG: Die Initialisierung von x und eingabe ist dabei notwendig!

Aufgaben

1. Fertigen Sie fur das folgende Programm ein Struktogramm an und erlautern Sie seineFunktion.

1 @kara = kara2

3 def reiheLegen ( r e c h t s )4 4 . t imes do5 @kara . putLeaf6 2 . t imes {@kara . move}7 end8 i f r e c h t s then9 @kara . turnRight

10 @kara . move11 @kara . turnRight12 @kara . move13 e lse14 @kara . t u r n L e f t15 @kara . move16 @kara . t u r n L e f t17 @kara . move18 end19 end20

21 4 . t imes do22 reiheLegen ( t rue )23 reiheLegen ( f a l s e )24 end

16

Page 17: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

2. Schreiben Sie ein Programm, das vom Benutzer die Anzahl der Strecken und die Anzahlder Blatter erfragt, die bei jeder Strecke im Vergleich zur vorigen mehr gelegt werdensollen und dann entsprechend Blatter legt.

3. Schreiben Sie ein Programm das vom Benut-zer die Anzahl der gewunschten Reihen erfragtund dann ein entsprechendes (gefulltes) Drei-eck aus Blattern legt.

4. Schreiben Sie ein Programm, das vom Benut-zer die Anzahl der gewunschten Reihen er-fragt und dann den Rand eines entsprechen-den (gleichschenklig rechtwinkligen) Dreieckaus Blattern legt.

5. Schreiben Sie ein Programm, das vom Benut-zer die Anzahl der gewunschten Reihen erfragtund dann den Rand eines entsprechenden Qua-drats aus Blattern legt.

7 Vordefinierte Methoden in RUBYKARA

In der Umgebung von RUBYKARA stehen unterschiedliche Methoden zur Verfugung. Mankann sich eine Kurzbeschreibung der Methoden mit der Hilfe-Schaltflache des Welt-Fenstersanzeigen lassen. Die Methoden sind in verschiedene Gruppen eingeteilt.

Zunachst sind einige der Methoden dazu da, KARA zu Aktionen zu veranlassen:

move Ein Feld vorwartsturnLeft Vierteldrehung nach linksturnRight Vierteldrehung nach rechtsputLeaf Blatt ablegenremoveLeaf Blatt aufnehmen

Die Sensoren werden uber Methoden abgefragt, die als Ergebnis true oder false zuruckgeben.

treeFront Baum vorn?treeLeft Baum links?treeRight Baum rechts?onLeaf auf Blatt?mushroomFront vor Pilz?

Schließlich gibt es noch Methoden, KARA direkt auf einem bestimmten Feld zu positionierenund eine Methode, Karas Position abzufragen.

17

Page 18: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

setPosition (x,y) setzt KARA auf das Feld mit den Koordinaten (x; y)setDirection(d) setzt KARAS Richtung: 0: Nord, 1: West, 2: Sud, 3: OstgetPosition.getX liefert KARAS x-KoordinategetPosition.getY liefert KARAS y-Koordinate

Alle diese Methoden mussen mit dem Prafix kara aufgerufen werden, also z. B. nicht move,sondern kara.move. Leider gibt es keine Methode zum Ermitteln von KARAS Richtung.

Es gibt auch Methoden zur direkten Veranderung von KARAS Welt. Sie mussen mit dem Prefixworld aufgerufen werden.

clearAll Alles entfernen (auch KARA ).setLeaf (x,y,legen?) legt (legen? = true ) oder entfernt (legen? = false ) ein Blatt bei (x;y)setTree (x,y,legen?) legt oder entfernt einen Baum bei (x;y)setMushroom (x,y,legen?) legt oder entfernt einen Pilz bei (x;y)setSize (xMax,yMax) Neue Große der Welt festlegengetSizeX horizontale Weltgroße zuruckgebengetSizeY vertikale Weltgroße zuruckgebenisEmpty(x,y) true , falls Feld (x;y) leer istisTree(x,y) true , falls ein Baum auf Feld (x;y) istisLeaf(x,y) true , falls ein Blatt auf Feld (x;y) istisMushroom(x,y) true , falls ein Pilz auf Feld (x;y) ist

Die nun folgenden Methoden sind in der Klasse tools definiert, mussen also mit dem Prefixtools aufgerufen werden. Diese Methoden sind vor allem fur Ein- und Ausgaben nutzlich. DerTyp string ist fur Zeichenketten (also Texte) bestimmt.

showMessage(text) gibt text in einem Dialogfenster ausstringInput(Titel) fordert die Eingabe eines Strings in einem Dialogfenster.

Titel liefert die Fensteruberschrift.Die Ruckgabe ist die Konstante null, fallsdie Eingabe abgebrochen wird.

intInput(Titel) Eingabe einer ganzen Zahl in einem Dialogfenstermit der Uberschrift Titel. Das Ergebnis istInteger.MIN_VALUE, wenn die Eingabe abgebrochenwird oder keine ganze Zahl eingegeben wird.

doubleInput(Titel) Eingabe einer Dezimalzahl in einem Dialogfenstermit der Uberschrift Titel. Das Ergebnis istDouble.MIN_VALUE, wenn die Eingabe abgebrochenwird oder keine Dezimalzahl eingeben wird.

random(Obergrenze) liefert eine ganze Zufallszahl aus demIntervall [0; Obergrenze]

sleep(ms) stoppt die Programmausfuhrung fur ms MillisekundencheckState uberpruft die Bedienungsleiste.

Unter Verwendung dieser Methoden kann man viele interessante kleine Probleme behandeln.

Aufgaben

1. Erzeugen Sie eine 20 × 20-Welt, umranden Sie sie mit Baumen und setzen Sie KARA aufdas Feld (10|10) mit Richtung Norden.

18

Page 19: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

2. Schreiben Sie ein Programm, das die Anzahl der Baume einer Welt ermittelt und in einemMessage-Fenster ausgibt.

ANLEITUNG: Ermitteln Sie die Breite und Hohe der Welt und untersuchen Sie in einergeschachtelten Schleife die Felder der Welt darauf, ob auf ihnen ein Baum steht. KARA

wird dazu nicht benotigt!

3. Schreiben Sie ein Programm, das eine leere 15× 15-Welt erzeugt und in ihr per Zufall 25Baume verteilt.

HINWEIS: Verwenden sie die world- und tools-Funktionen. Erzeugen Sie zwei Zufalls-zahlen, um die Zeile und Spalte eines Feldes fur einen Baum auszuwahlen. Beachten Sie,dass kein Feld mehr als einmal ausgewahlt werden darf.

4. Lassen Sie KARA auf einem Feld beliebiger Große eine Zufallswanderung durchfuhren.Bei jedem Schritt geht KARA zufallsgesteuert ein Feld nach vorn oder nach links odernach rechts und legt ein Blatt ab, falls dort keines liegt. Zahlen Sie die Anzahl der Schritte,bis die Welt gefullt ist.

HINWEIS: Verwenden Sie random.

5. Andern Sie das vorige Programm so ab, dass KARA bei belegten Feldern auf seinem Wegdas Blatt aufnimmt. Lassen Sie KARA etwa so viele Schritte tun, wie in der vorigen Auf-gabe zum Fullen der Welt benotigt wurden und prufen Sie, wieviel der Welt dann mitBlattern bedeckt ist.

6. Man kann mit world.setLeaf(x,y,true) auf dem Feld (x|y) ein Blatt ablegen. Man kanndies verwenden, um Muster zu erzeugen. Schreiben Sie eine Klasse, die eine 20× 20-Welterzeugt, im oberen linken Eck ein zufalliges 4 × 4-Muster aus Kleeblattern erzeugt unddieses Muster dann auf die ganze Welt kopiert.

⇒7. Die angezeigten Ziffern sollen jeweils mit einer eigenen Methode erzeugt werden.

Dabei gibt es folgende Vorgaben:

• Jede Ziffer beansprucht ein Rechteck mit 6× 8 Feldern.

• In den seitlichen Randern des Rechtecks liegen keine Blatter.

• die Methode erhalt als Eingabe die Koordinaten des linken unteren Eckfelds desRechtecks.

Die Eins kann man beispielsweise wie folgt erzeugen:

19

Page 20: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

1 def e ins ( x , y )2 2 . upto ( 4 ) { | i | @world . s e t L e a f ( x+i , y , t rue )}3 1 . upto ( 7 ) { | i | @world . s e t L e a f ( x +3 ,y−i , t rue )}4 1 . upto ( 2 ) { | i | @world . s e t L e a f ( x+i , y−4−i , t rue )}5 end

Analysieren Sie diese Methode und schreiben Sie Methoden fur die restlichen Ziffern.Schreiben Sie damit ein Programm, welches das oben gezeigte Bild erzeugt.

HINWEIS: Es empfiehlt sich, eine allgemeine Methode

public void schreibe(int ziffer,int x,int y)

zu schreiben, die je nach Ziffer die passende Schreibmethode wahlt. Dazu sollte man sichansehen (Internet), wie man Mehrfachfallunterscheidungen in RUBY mit case realisiert.

8. Schreiben Sie unter Verwendung der vorigen Aufgabe ein Programm, das eine naturlicheZahl vom Benutzer erfragt und diese Zahl dann in eine passende Welt schreibt.

HINWEIS: Den Divisionsrest von a:b erhalt man durch a % b. Im Bereich der ganzen Zah-len liefert RUBY immer den ganzzahligen Quotienten ohne Rest, wenn man a/b berech-net. anders ausgedruckt: Gilt a = q · b + r mit r < b, so ist a/b = q und a % b = r.

9. Von Manfred Eigen (http://de.wikipedia.org/wiki/Manfred_Eigen) stammt die folgen-de Simulation zum Thema Evolution.Man nehme ein 8 × 8-Feld und belege es in je-dem der vier Teilquadrate mit einem Symbol,wie rechts gezeigt (das vierte ”Symbol“ ist hierganz einfach ein leeres Feld). Nun wird fol-gendes Verfahren wiederholt, bis nur noch eineSymbolsorte auf dem Feld ist: Man wahlt perZufall zwei verschiedene Felder des Quadrats.Das Symbol auf dem ersten Feld wird entferntund durch ein Symbol von der Art des auf demzweiten Feld befindlichen ersetzt. Startbelegung

Schreiben Sie ein Programm, das diese Simulation durchfuhrt.

8 Erweiterungen

Eine Reihe von Problemen waren einfacher losbar, wenn KARA mehr Sensoren hatte. Man kanneigene Sensoren als Methoden leicht zusatzlich definieren.

Beispiel: Es soll ein Sensor definiert werden, der einen Pilz links von KARA entdeckt.

Dazu muss sich KARA nach links drehen, sich merken, ob jetzt vor ihm ein Pilz steht und sichdann zuruck nach rechts drehen.

1 def pi lzL inks2 @kara . t u r n L e f t3 p i l z =@kara . mushroomFront4 @kara . turnRight

20

Page 21: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

5 return p i l z6 end

Nach diesem Verfahren kann man naturlich auch einen Sensor fur rechts von KARA stehendePilze definieren. Allerdings hat das Verfahren den Nachteil, dass KARA bewegt werden muss,was die Programmausfuhrung verlangsamt. Will man entsprechend Sensoren definieren, dieerkennen, ob KARA links von, rechts von oder vor einem Blatt steht, so wird der Aufwandnoch hoher, weil der vorhandene Sensor Blatter nur erkennt, wenn KARA auf ihnen steht. Umzu erkennen, ob KARA vor einem Blatt steht, muss KARA daher einen Schritt vorwarts machen.Das geht aber nicht immer. KARA konnte vor einem Baum stehen, dann kann er keinen Schrittvorwarts machen. Steht er vor einem Pilz, so kann er vielleicht einen Schritt vorwarts machen,verschiebt aber dabei den Pilz.

Wenn man die Methoden der Klasse world verwendet, kann man alternativ etwa folgendenSensor erzeugen:

1 def l ea fSouth2 y=@kara . g e t P o s i t i o n . getY3 x=@kara . g e t P o s i t i o n . getX4 ymax= @world . getSizeY−15 i f y==ymax6 return @world . i s L e a f ( x , 0 )7 e lse8 return @world . i s L e a f ( x , y + 1 ) ;9 end

10 end

Hier wird zunachst KARAS Position abgefragt. Dabei muss berucksichtigt werden, dass dieWelt in form einer Torus vorliegt. Wenn KARA auf der untersten Zeile steht, so ist die obersteZeile ”sudlich“ von KARA . Dem wird mit der Fallunterscheidung Rechnung getragen.

Entsprechend kann man auch Methoden schreiben, die KARA in eine bestimmte Himmelsrich-tung drehen. Naturlich kann das auch direkt mit kara.setDirection bewerkstelligt werden,aber eine passende Neudefinition ist einpragsamer:

1 def turnEast2 @kara . s e t D i r e c t i o n ( 3 )3 end

Wenn man eine Reihe solcher Definitionen haufiger verwenden will, kann man sie in einer eige-nen von JavaKaraProgram abgeleiteten Klasse definieren. Die ganzen Definitionen der Senso-ren und die Drehungen sind beispielsweise in der Datei Kepi.rb zusammengestellt. Die Dateienthalt nur Definitionen und kein Programm. Speichert man diese Datei im Verzeichnis derDatei rubykara.jar, so kann man danach mit dem Befehl require ’Kepi.rb’ zu Beginn einerProgrammdatei diese Definitionen einschließen und verwenden.

Das folgende Programm verwendet diese Methode, um eine vereinfachte Fassung von Pacmanzu erzeugen:

1 requi re ’ Kepi . rb ’2

3 @kara . removeLeaf i f @kara . onLeaf4 while not @kara . t r e e F r o n t

21

Page 22: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

5 i f l e a f E a s t6 turnEast7 e l s i f leafWest8 turnWest9 e l s i f l ea fSouth

10 turnSouth11 e l s i f leafNorth12 turnNorth13 e lse r a i s e ”Kein B l a t t weit und b r e i t :−( ”14 end15 @kara . move16 @kara . removeLeaf17 end

Aufgaben

1. Schreiben Sie nach den Beispielen in diesem Abschnitt die vollstandige Datei Kepi.rbund testen Sie das pacman-Programm.

9 Arrays

Wir wollen den verwendeten Zufallszahlengenerator tools.random(n) benutzen, um einenWurfel zu simulieren. Dazu sollen hundert Zufallsszahlen im Bereich von 1 bis 6 erzeugt wer-den. Wir wollen die Anzahlen festhalten, mit denen jede der Zahlen erzeugt wird.

Die Zufallszahlen werden mit folgender Methode erzeugt (random(5) erzeugt Zahlen von 0 bis5):

1 def wurfel2 return (1+ @tools . random ( 5 ) ) ;3 }

Zum Mitzahlen der einzelnen Ergebnisse konnte man jetzt sechs Variablen definieren und diesemit einer Fallunterscheidung bei jedem Ergebnis um eins erhohen. Dies ware außerst umstand-lich. Da solche und ahnliche Probleme haufig auftauchen, sehen die meisten Programmierspra-chen auch Datenstrukturen vor, die solche Aufgaben vereinfachen.

Will man mehrere Daten gleichen Typs gruppieren, verwendet man einen Array (deutsch:Feld). In einem Array werden eine feste Anzahl von Daten gleichen Typs gespeichert. Auf dieeinzelnen Daten kann man uber einen Index zugreifen. In RUBY werden Arrays beispielsweisewie folgt vereinbart:

zahlen=[1,2,3,4,5,6];

Diese Anweisung definiert eine Array-Variable zahlen mit 6 Eintrage vom Typ int, die mitden in den eckigen Klammern stehenden Zahlen initialisiert werden. Auf das dritte Elementdes Arrays wird mit dem Ausdruck zahlen[2] zugegriffen (die Zahlung der Array-Elementebeginnt mit 0).

Alternativ kann man ein Array auch ohne Initialisierung definieren und die Zuweisung vonWerten spater vornehmen. Mit der folgenden Methode wird die Anzahl der Elemente des Ar-rays festgelegt. Dabei wird automatisch jedes Element mit einem Standardwert nil initialisiert.

22

Page 23: Einfuhrung in R¨ UBYKARA - Unterrichtsmaterialien

werte=Array.new(100);

erzeugt einen Array mit 100 Elementen , die alle mit nil initialisiert werden. Man kann auchBlocke zur Initialisierung verwenden:

zahlen=Array.new(6) {|i| i+1}

erzeugt ebenfalls den Array [1,2,3,4,5,6]. Der Variablen i des Blocks wird dabei fur jedesneue Arrayelement dessen Index ubergeben. Das Ergebnis der Berechnung des Blocks wirddann diesem Element zugewiesen. Mit

zahlen=Array.new(10){|i| [i,i*i]}

erhalt man einen Array von 10 zweielementigen Arrays die jeweil eine der Zahlen von 0 bis 9und ihr Quadrat enthalten.

Das Programm fur die 100 Wurfe des Wurfels konnte so aussehen:

1 ergebnis=Array . new ( 6 , 0 )2 1 0 0 . t imes { ergebnis [ @tools . random ( 5 ) ] +=1}3 @tools . showMessage ( ergebnis . i n s p e c t )

Der Array ergebnis wird mit 6 Elementen definiert, die alle den Wert 0 erhalten. So kann manfur jede Zahl i des Wurfels ganz einfach das ite Element von ergebnis als Zahler verwenden.Da die Array-Indizes von 0 bis 5 gehen, verwendet man einen ”Wurfel“ mit den Augenzahlenvon 0 bis 5. Man kann naturlich leicht auch großere Anzahlen von Wurfen simulieren. Mitinspect wird der Array fur die Ausgabe in einen String umgewandelt.

Aufgaben

1. Schreiben Sie ein Programm, das vom Benutzer den Funktionsterm einer Funktion (Funk-tionsvariable: x) anfordert und fur diesen Funktionsterm eine Wertetabelle fur die ganz-zahligen Werte von x von -5 bis 5 ausgibt.

HINWEIS: @tools.stringInput kann zur Eingabe des Terms verwendet werden. Die Me-thode eval kann einen String auswerten, wenn dieser einen gultigen RUBY -Ausdruckdarstellt.

BEISPIEL x=3; eval("x**2+2*x+1") liefert als Ergebnis 16.

2. Schreiben Sie ein Programm, welches die Baume, Pilze und Blatter einer Welt mit einemArray zahlt und das Ergebnis anzeigt.

3. Simulieren Sie ein Galtonbrett mit Kara als ”Kugel“ und ”Baumen“ als Stifte.

(Informationen dazu unter http://de.wikipedia.org/wiki/Galtonbrett)

23