Magic Disk 64

home to index to text: MD8911-KURSE-BASIC_KURS_TEIL_9-1_:_VON_ADAM_UND_EVA...(TEIL_9).txt
 ASICKurs: "Von Adam und Eva..."(Teil 9)

Hallihallo, da sind wir wieder. Entgegen allen Gerüchten, die ich das letzte Mal aufgestellt habe, ist der Basickurs jetzt doch noch einen Teil länger. Wir haben uns dazu entschlossen, daß es doch besser ist, wenn dieser Kurs hier komplett abgeschlossen ist, so daß es keiner langwierigen Erklärungen mehr benötigt, wenn wir uns ab nächten Monat an die Grafik machen werden.
Heute kommen nun noch die ultimativ letzten Basicbefehle an die Reihe, mit denen sich auch noch einiges anfangen läßt. . .

1.) Die Stringfunktionen :              

Wie diese Überschrift schon verrät, bietet uns BASIC V2 .0 eine Fülle von Funktionen, mit denen wir auf einfachste Art und Weise Stringvariablen verändern und manipulieren können. Was kann man darunter verstehen? Nun, vielleicht ist Ihnen ja schon im letzten Teil aufgefallen, daß ich dort ein sequentielles File mit dem Befehl :

OPEN 1,8,2,NA$+",S,W"                   

zum Schreiben geöffnet hatte. Vielleicht haben Sie sich gefragt, was dieses "+"- Zeichen bewirken soll. Nunja, wie wir dann ja feststellten, diente es dazu, die beiden Stringketten ( zum einen der String in NA$ und zum anderen das ", S, W") miteinander zu verknüpfen. Stünde beispielsweise der String " FILENAME" in NA$, so hieße das für den OPEN-Befehl, daß er hier die Gesamtzeichenkette " FILENAME, S, W" vor sich hat. Der notwendige Appendix ist somit direkt an den veränderbaren oder variablen Text in NA$ angehängt worden. Genau dies ist auch als Variablenzuweisung möglich, wie es das folgende Programm demonstriert :

10 A$="STRINGS KOENNEN "                
20 B$="MIT '+' VERKETTET "              
30 C$=A$+B$+"WERDEN!"                   
Nach  Ablauf des Programms haben wir nun
also in A$ den Text  "STRINGS KOENNEN ",
in  B$ den Text "MIT ↑+↑ VERKETTET " und
in  C$  "STRINGS KOENNEN MIT '+' VERKET-
TET WERDEN!" stehen.                    

Umgekehrt, beim Zerlegen eines Strings, verhält sich dies allerdings etwas schwieriger. Sie können hier leider nicht mit dem Minuszeichen ("-") arbeiten. Dazu haben wir allerdings die Stringfunktionen LEFT$, RIGHT$ und MID$ zur Verfügung, die sogar noch viel besser arbeiten, als es mit "-" möglich wäre. Mit Ihnen kann man nämlich einen String gezielt in Stücke zerhacken, ohne dabei großen Aufwand zu haben.
Zum einen wäre da LEFT$ . Mit dieser Funktion können wir einen Teil aus einer Stringvariablen isolieren, der von LINKS nach RECHTS reicht. Hierzu übergeben wir LEFT$ ganz einfach den zu bearbeitenden String und, durch ein Komma voneinander getrennt, die Anzahl der zu übernehmenden Buchstaben an. Dies geschieht etwa folgendermaßen :

A$="BASIC IST TOLL"                     
PRINT LEFT$(A$,5)                       

Nach dieser Befehlssequenz sollten Sie dann nur die 5 Buchstaben " BASIC" auf dem Bildschirm stehen haben. Es wurden also die ersten 5 Buchstaben aus dem String A$ herausisoliert.
Ebenso verhält es sich nun mit RIGHT$, nur daß nun die Buchstaben von RECHTS nach LINKS isoliert werden, wobei sie ihre Reihenfolge jedoch beibehalten, nicht also rückwärts geschrieben sind !
Hier ein Beispiel :

A$="BASIC IST TOLL"                     
PRINT RIGHT$(A$,4)"                     

Nun erhalten Sie also die 4 letzten Buchtaben des Strings A$, den Text " TOLL" .
Wem das noch nicht genügt, der kann auf MID$ zurückgreifen. MID$ stellt quasi eine Mischung aus LEFT$( von " Links") und RIGHT$( von " Rechts") dar. Sie können hiermit, wie der Befehl schon sagt, eine Zeichenkette " aus der Mitte" eines Strings herausisolieren. Hierbei müssen wir, wie bei den beiden Verwandten von MID$ auch, erst einmal den zu Untersuchenden Stringnamen angeben, gefolgt von der Nummer des Buchstabens, von dem an wir die folgenden Buchstaben übernehmen möchten, und der Anzahl der Buchstaben, die übernommen werden sollen; alle Parameter jeweils durch Kommata getrennt.
Den Text " IST" aus unserem Beispielstring " BASIC IST TOLL" können wir also folgendermaßen isolieren :

A$="BASIC IST TOLL"                     
PRINT MID$(A$,7,3)                      

Hier werden also ab dem 7 . Buchstaben des Strings A$,3 Buchstaben herausisoliert: das Wort " IST" .
Jetzt werden Sie sicher sagen," Na schön und gut, doch wofür kann man denn so etwas brauchen ?" Zugegeben, viele Anwendungen finden die Stringfunktionen vielleicht nicht, doch kann ich Ihnen ein höchst wichtiges Problem aufzeigen, das geradezu " wie geschaffen" für unser Thema ist : die Eingaberoutine eines Textadvetures zum Beispiel.
Wenn Sie diese Art von Spielen kennen, so werden Sie sicher wissen, daß die Eingaben an das Programm meist mit Hilfe einer Kommandozeile abgewickelt werden, über die die einzelnen Befehle an das Programm gehen. Sie wissen sicher auch, daß solche Befehle in aller Regel aus Verben und Objekten bestehen, wie zum Beispiel " NIMM BUCH" . Hier haben wir also ein Verb, das angibt WAS getan werden soll und ein Objekt MIT DEM wir etwas tun wollen. Nun gilt es also diesen Kommandostring in seine einzelnen Unterworte aufzusplitten, damit wir keine Probleme bei der Erkennung der Worte bekommen. Wir müssen also in unserem String nach Leerzeichen suchen, die die Worte ja voneinander trennen, und bis zu dieser Stelle ein Wort isolieren. Damit unser Beispiel nicht komplizierter wird, als es in diesem Rahmen sein soll, setzen wir einmal vorraus, daß nur 2 Worte in der Eingabe vorkommen, daß also der Anfang eines Strings, bis zum Leerzeichen, ein Wort bildet, und alles, was danach folgt, ein weiteres. Erschwerend kommt noch hinzu, daß wir ja nicht wissen WIE LANG der gesamte Eingabestring ist. Doch dieses Problem können wir mit Hilfe einer weiteren Stringfunktion lösen, der LEN-Funktion. Diese funktioniert denkbar einfach, wir müssen nämlich lediglich den Namen des zu untersuchenden Strings, in Klammern gesetzt, nach dem Befehlswort LEN angeben. Etwa so:

10 A$="OEFFNE TRUHE"                    
20 A=LEN(A$)                            

Danach steht in A der Wert 12, denn soviele Buchstaben enthält die Variable A$ . Nun können wir uns um die Analyse des Strings kümmern. Zunächst einmal eine Schleife, mit deren Hilfe wir feststellen wollen, an welcher Stelle in unserem String sich das Leerzeichen befindet. Hierzu bedienen wir uns dann MID$ . Er holt sich jeweils nur EINEN Buchstaben aus unserem String, damit wir prüfen können welches Zeichen wir vor uns haben :

30 FOR I=1 TO A                         
40 X$=MID$(A$,I,1) :REM NUR EIN ZEICHEN 
50 IF X$<>" "THEN NEXT                  

Die Schleife holt sich hier also nur solange Zeichen aus dem String, wie diese ungleich dem Leerzeichen ("") sind.
Ist dies nicht mehr der Fall, so sind wir an dem Punkt angelangt, wo die Worte getrennt werden. In der Laufvariable I ist nun die Stelle des Leerzeichens in unserem String gespeichert. Wir brauchen uns die einzelnen Komponenten nur noch mit Hilfe von LEFT$ und RIGHT$ in eigenen Variablen zuweisen. Hierbei ist noch zu beachten, daß wir beim ersten Wort auch das Leerzeichen am Ende mitbekommen würden, würden wir I so benutzen. Da dies jedoch nur behindernd ist brauchen wir also lediglich alle Buchstaben bis I-1 herauszuisolieren. Bei dem zweiten Wort müssen wir dann auch erst noch berechnen, wieviele Stellen wir von Rechts gebrauchen können, das tun wir mit Hilfe der Formel A-I. Das ganze sieht dann folgendermaßen aus :

60 W1$=LEFT$(A$,I-1)                    
70 W2$=RIGHT$(A$,A-I)                   
80 PRINT"DAS ERSTE WORT IST  : ";W1$    
90 PRINT"DAS ZWEITE WORT IST : ";W2$    

Wir haben also nun ein kleines Anwendungsbeispiel für die bisherigen Stringfunktionen durchgeführt. Nebenbei haben wir da dann auch noch LEN kennengelernt. BASIC kennt aber noch 4 weitere Stringfunktionen. Zwei davon kennen wir bereits, CHR$ und ASC, weshalb ich nicht mehr auf diese eingehen werde, doch es gibt noch zwei weitere.
Zum einen wäre da STR$ . STR$ liefert ganz einfach den String einer numerischen Variablen, so wie sie mit PRINT ausgedruckt worden wäre. So können Sie zum Beispiel auf einfache Art und Weise eine INTEGERoder FLOAT-Variable einer Stringvariablen zuweisen, wobei der String dann halt die ASCII-Werte der einzelnen Ziffern enthält. Zum Rechnen können Sie diesen String natürlich nicht mehr verwenden, jedoch kann diese Funktion manchmal ganz von nutzen sein. Hier einmal ein Beispiel :

A=1989                                  
X$=STR$(A):REM IDENTISCH MIT 'X$="1989"'

Hiermit hätten wir also der Stringvariablen X$ den String "1989" zugewiesen und können diesen nun weiterverarbeiten.
Beispielsweise gibt es da eine Formel zur Berechnung des Wochentages anhand des reinen Datums die mit Parametern wie " Jahrhundert" oder " Jahrzehnt" arbeitet.
Hierzu bietet es sich dann an mit LEFT$ und RIGHT$ eben jene Parameter zu isolieren und mit der nun folgenden Stringfunktion wieder in eine Zahl zurückzuwandeln.
Die Funktion von der ich rede heißt VAL und tut genau das umgekehrte wie STR$ .
Angenommen, wir hätten das Jahrhundert aus "1989" mittlerweile herausisoliert und fein säuberlich in der Variablen JH$ gespeichert. Dann könnten wir den String "19" mit folgendem Befehl ganz einfach zur Zahl 19 machen:
JH= VAL( JH$) Das wars schon. Sie können nun wie gewohnt mit JH rechnen, denn dort haben wir nun tatsächlich den numerischen Wert 19 stehen, und nicht etwa die Zeichenkette "19" .
Soviel zum Thema Stringfunktionen, machen wir nun weiter mit den ominösen Befehlen, die eigentlich erst im Grafikkurs gekommen wären, ich werde Sie Ihnen hier jedoch anhand eines anderen Beispiels erläutern:

2.) Datenhandling im Programm :         

Bestimmt haben Sie schon einmal ein Basicprogramm aus einer Zeitschrift abgetippt, die NICHT über den Vorteil der Magic Disk 64 verfügte, daß die Programme zum Heft alle auf einer Diskette mitgeliefert werden. Dabei mußten Sie mit ziemlicher Sicherheit ( denn dies kommt häufig vor) auch lange Kolonnen von Zeilen abtippen, in denen am Anfang das Befehlswort DATA stand, gefolgt von vielen Zahlen, alle durch Kommata voneinander getrennt. Wie dieser Befehl schon sagt, werden hier DAT( A) enwerte abgelegt. Auf ein Programm selbst hat er eigentlich wenig Einfluß - er wird ganz einfach von BASIC überlesen. Nur in Zusammenhang mit einem weiteren Basicbefehl hat DATA überhaupt einen Sinn, ich spreche von dem READ-Befehl. Im übrigen könnte dieser ohne DATA auch wenig anrichten, die beiden hängen also fest zusammen und voneinander ab. READ ist( wie immer) englisch und heißt " LESE" .
Wir können den Computer also hiermit anweisen ein Datenelement zu LESEN - und woher nimmt er sich dieses Datenelement? Natürlich von einem DATA-Statement! READ liest nun also das erste Datenelement hinter der ersten DATA-Anweisung im Programm in eine Variable ein, die wir ihm schlicht und einfach nachstellen.
Ich gebe zu, daß es langsam vielleicht etwas langweilig erscheint immer wieder das Beispiel eines Textadventures durchzukauen, doch paßt dieses Beispiel hier genau hin und erklärt hoffentlich eindeutig, wozu READ und DATA notwendig sind.
Also angenommen, Sie wollten ein Textadventure schreiben, das mehrere Verben und mehrere Objekte ( wie das ja, schon oben beschrieben, zu JEDEM Textadventure gehört) verstehen soll. Zuerst haben wir einmal die Eingabe vom Spieler in seine Einzelteile zerlegt und in W1$ das Verb und in W2$ das Objekt gespeichert. Nun geht es darum zuerst einmal das eingegebene Verb zu analysieren und mit dem Programmwortschatz zu vergleichen. Hierzu benutzen wir ein Variablenfeld ( Sie erinnern sich an das letzte Mal. . .) in dem alle Verben gespeichert werden sollen. Damit das bei einem Programm, das vielleicht 100 Verben verstehen soll nicht in Arbeit ausartet, wollen wir die einzelnen Verbdaten mit Hilfe einer Schleife den Variablen zuordnen. Hierzu legen wir alle Verben in DATA-Zeilen ab und lesen sie, eins nach dem anderen, ein und weisen sie somit einer Variablen in unserem Feld zu. READ liest also immer das nächste Element aus einem DATA-Statement aus, solange bis es nichts mehr zu lesen gibt. Das sollten Sie wissen, damit READ nicht zuviele Daten einzulesen versucht. Hier einmal ein Beispiel, bei dem ich 7 Verben in dem Variablenfeld VE$( X) speichern möchte. Wie die Schleife schon zeigt, werden hier auch nur 7 Datenelemente gelesen,(6 Elemente plus das 0 . Element) .

10 DIM VE$(6)                           
20 FOR I=0 TO 6:READ VE$(I):NEXT        
30 DATA NIMM,GIB,OEFFNE,SCHLIESSE,SCHLAG
E,DRUECKE,RUFE                          

Somit hätten wir uns also das mühsehlige Auflisten von Variablenzuweisungen gespart. Sie müssen doch zugeben, daß folgendes etwas umständlicher wäre :

10 VE$(0)="NIMM"                        
20 VE$(1)="GIB"                         
30 VE$(2)="OEFFNE"                      
40 VE$(3)="SCHLIESSE"                   
und so fort...                          

Doch nicht genug, in DATA-Statements kann man nicht nur Strings ablegen, sondern auch INTEGERoder FLOAT-Werte und das dann noch bunt gemischt:

100 DATA 100,3.14,HALLO,2.689,BASIC,12  

Alles worauf wir dann beim Lesen achten müssen, ist, daß die einzelnen Elemente auch den entsprchenden Variablentypen zugeordnet werden. Es ist Ihnen ja mit Sicherheit klar, daß wir nicht einfach so einen Text einer INTEGER-Variablen zuweisen können oder ähnliches.
Allerdings gibt es noch zwei Besonderheiten, die man in Zusammenhang mit DATA erwähnen muß. Sie werden nämlich ganz schöne Probleme bekommen, sollten Sie einmal versuchen, ein Komma (",") in Ihren Strings zu verwenden, die bei DATA abgelegt sind. Wie wir wissen dient das Komma ja zur Trennung der einzelnen Elemente, was für den Computer heißt, daß wir ihm da zwei einzelne Elemente, anstatt nur einem gegeben haben. Machen Sie also niemals folgenden Fehler:

100 DATA HALLO,IHR!                     

Hier haben wir nämlich die beiden Strings " HALLO" und " IHR" abgelegt, anstatt dem eigentlich gewollten Text " HAL-LO, IHR!" In diesem Fall müssen wir den abzulegenden String dann ganz einfach in Anführungszeichen setzen, damit er richtig erkannt wird, also :

100 DATA "HALLO,IHR!"                   

Und schon bekommen wir auch das, was wir wollen. Es bleibt noch zu erwähnen, daß dies derselbe Fall bei dem Doppelpunkt (" :") und bei Leerzeichen ("") der Fall ist. Sollten Sie also einmal in einem Stringelement ein Komma, einen Doppelpunkt oder ein Leerzeichen enthalten haben, so müssen Sie dieses Element UN-BEDINGT in Gänsefüßchen setzen. Bei Strings, wo dies nicht zutrifft können Sie sie auch weglassen ( müssen aber nicht) .
Das zweite, was noch zu sagen wäre, ist, daß man manche Datenelemente auch abkürzen kann. Das spart zum einen Speicherplatz und zum anderen läuft das Programm dann später auch schneller ab. Wenn man nach einem Komma, das ja zur Trennung der einzelnen Datenelemente dient, ein weiteres Komma nachstellt, also praktisch KEIN Datenelement angibt, so interpretiert unser 64 er diesen Datensatz als den Wert 0 . Hier ein kleines Beispiel:

100 DATA 200,,,10,,,                    

Diese Zeile entspicht haargenau dem folgenden Ausdruck und bewirkt auch genau dasselbe:

100 DATA 200,0,0,10,0,0,0               

Der Unterschied ist, daß wir weniger Tipparbeit hatten und somit Speicherplatz gespart haben, UND daß die erste DATA-Zeile auch noch schneller abgear- beitet werden kann - mit einem Wort, nur Vorteile.
Als Nächstes sollte ich vielleicht noch erwähnen, daß READ grundsätzlich immer das ERSTE Datenelement aus dem ERSTEN DATA-Statement zuerst liest. Es ist dabei egal, WO sie Ihre DATAs im Programm unterbringen, READ liest rigoros alles durch, solange bis es keine Daten mehr finden kann. Hierauf sollten Sie immer achten, denn sonst kann es zu einem " OUT OF DATA ERROR" kommen. Sie sollten auch wissen, daß READ sich quasi " merkt" bis zu welchem Datenelement es schon gelesen hat. Dieser Merkspeicher ändert sich solange nicht, bis Sie das Programm wieder mit RUN starten. Es wird hierbei also der Merkspeicher wieder auf das allererste Datenelement zurückgesetzt, so daß Sie die Daten wieder von vorne lesen können.
Für diese Funktion gibt es übrigens sogar einen eigenen BASIC-Befehl. Er heißt RESTORE, was soviel heißt wie " zurücksetzen" . Er tut haargenau dasselbe was auch unter anderem bei RUN passiert ( nämlich das Zurücksetzen des DATA-Merkspeichers), nur daß Sie ihn mitten im Programm aufrufen können, ohne hierbei das Ganze von vorne starten zu müssen. RESTORE braucht übrigens keine Parameter.

Valid HTML 4.0 Transitional Valid CSS!