Die "QBasic-Times"



Ausgabe Nr.6 (5-2000)


 
Übersicht
 

DirectQB Tutorial Teil 5 Keyboard
Wie Benutzt man das Keyboard in DirectQB?

3D-Grunglagen in QBasic
3D für QBasic

ASM Tutorial Teil 2 Interrupts
Kurze Erklärung zu Interrupts

ASM Tutorial Teil 3 Der Stack
Alles über den Stack

Turbo Pascal Tutorial 1 Grundaufbau
Wie müssen Turbo-Pascal Programme aufgebaut sein?

Turbo Pascal Tutorial 2 Ein- und Ausgabe von Text
Wie gibt man Text aus und ein?

Turbo Pascal Tutorial 3 Auswahlstrukturen
Alles über IF THEN und CASE

Anfängerkurs 2
Diesmal geht es um Rekursion

Bonus
Keyboardroutine ohne Assembler
 
 



 
 

Hallo QBasic-Times-Leser.

Auch in dieser Ausgaber der QBasic Times gibt es wieder viel zu entdecken.
Neben einem DirectQB Tutorial geht es diesmal um Assembler und Turbo-Pascal.
Wer sich für 3D interessiert sollte sich das 3D Grundlagen Tutorial nicht entgehen lassen.
Im Anfänger Tutorial geht es diesmal um Rekursion.
Und wer immer noch nicht genug hat, kann sich den Bonus ansehen, in dem es ums Keyboard geht.

Also viel Spaß beim stöbern.


 





 

DirectQB Tutorial Teil 5 Keyboard

Habt ihr euch nicht auch manchmal eine richtig gute Inkeyroutine gewünscht. Ich meine, Inkey$ ist zwar zum eingeben einzelner Buchstaben nicht schlecht aber für ein Spiel, bei welchem man die Cusortasten benötigt, ist es der absolute Schwachsinn. Man kann immer nur eine Taste drücken, es kommt immer zu einer Verzögerung und wenn man zu lange drückt, schreit der Computer herum, dass man doch gefälligst die Tasten los lassen soll (das BEEP).
Wie wäre es den mit einer Routine, bei der man immer genau weiß, welche Taste gerade gedrückt wird und welche gerade nicht gedrückt wird?
Nun, DirectQB bietet diese Routine. Leider hat diese einige Nachteile aber dazu komme ich später.
Das wichtigste ist der Befehl
DQBinstallKeyboard
Dabei wird die Routine in den Speicher geladen und ist gleich aktiv.
Mit der Funktion
DQBkey(X)
Kann man dann in Erfahrung bringen, welche Taste gerade gedrückt wird.
Das X ist die Zahl der Taste, der Status man ermitteln möchte.
Es ist zum Beispiel die 1 für ESC.
DQBkey liefert dann einen Wert ungleich Null zurück wenn die Taste gedrückt wird. Wenn die taste nicht gedrückt wird, wird der Wert gleich Null zurück geliefert.
Um die Keyboardroutine wieder zu deaktivieren muß man einfach nur
DQBremoveKeyboard
Ausführen.
Das wars eigentlich schon. Aber kommen wir nun zu den Problemen.
So lange die Routine aktiv ist, das heißt, nachdem DQBinstallKeyboard ausgeführt wurde, kann QBasic keine Tasten basierenden  Funktionen mehr starten. Es funktioniert weder INKEY$ noch SLEEP 0 oder Input.
Das QBasic-Program kann  auch nicht mehr durch STRG + Pause beendet werden.
Man hat dann auch keine Kontrolle mehr über QBasic selbst.
Es ist dann so, als ob das Keyboard nicht mehr angeschlossen ist.
Es ist also unbedingt zu beachten, dass immer DQBremoveKeyboard vor dem Beenden des Programms ausgeführt wird. Wenn man dieses vergißt, kann man den PC nur noch neu starten.

Hier jetzt die List für die Tasten

    1  =   ESC
    2  =   1
    3  =   2
    4  =   3
    5  =   4
    6  =   5
    7  =   6
    8  =   7
    9  =  9
    10 =  0
    11 =  - oder _
    12 =   = oder +
    13 =   Backspace
    14 =   Tab
    15 =   Q
    17 =   W
    18 =   E
    19 =   R
    20 =  T
    21 =   Y
    22 =   U
    23 =   I
    24 =   O
    25 =   P
    26 =   [ oder {
    27 =   ] oder }
    28 =   Enter
    29 =   Control
    30 =     A
    31 =   S
    32 =   D
    33 =   F
    34 =   G
    35 =   H
    36 =   J
    37 =   K
    38 =   L
    39 =   ; oder :
    40 =   ' oder "
    41 =   \ oder ~
    42 =   linkes Shift
    44 =   Z
    45 =   X
    46 =   C
    47 =   V
    48 =   B
    49 =   N
    50 =   M
    51 =   , oder <
    52 =   . oder >
    53 =   / oder ?
    54 =   rechtes Shift
    55 =   * oder Druck
    56 =   ALT
    57 =   Leer
    58 =   Caps Lock
    59 =   F1
    60 =   F2
    61 =   F3
    62 =   F4
    63 =   F5
    64 =   F6
    65 =   F7
    66 =   F8
    67 =   F9
    68 =   F10
    69 =   Num lock
    70 =   Rollen
    71 =   7 oder Home
    72 =   8 oder Hoch
    73 =   9 oder Page up
    74 =    -
    75 =   4 oder Links
    76 =   5
    77 =   6 oder Rechts
    78 =   +
    79 =   1 oder END
    80 =   2 oder Runter
    81 =   3 oder Seite runter
    82 =   0 oder Einfg
    83 =   . oder Entf
    87 =   F11
    88 =   F12

Diese List ist für ein Amerikanisches Keyboard.
 

Hier noch ein Beispiel:

' All Integer für die Geschwindigkeit
DEFINT A-Z

'$INCLUDE:'DIRECTQB.BI'

' Es wird DQB ohne Extras geladen
IF DQBinit(0, 0, 0) THEN DQBclose: PRINT DQBerror$: END

' Keyboardroutine wird installiert
DQBinstallKeyboard

CLS
PRINT "Keyboard DEMO drücke eine Taste für seinen Scanncode. Es sind auch mehrere Tasten gleichzeitig erlaubt ; Drücke ESC zum Beenden."

DO
    LOCATE 3, 1

    ' Suche nach allen Tasten
FOR i = 0 TO 127
    ' Wenn eine Taste gedrückt wird dann zeige sie an
    IF DQBkey(i) THEN PRINT "[" + LTRIM$(STR$(i)) + "] ";
NEXT i

' Löscht ein Stück das Bildschirms
PRINT SPACE$(40)

' Schleife verlasen wenn ESC gedrückt wird
LOOP UNTIL DQBkey(KEYESC)

' Beende KeyboardRoutine
DQBremoveKeyboard

' Beende Programm
DQBclose
 

Ich denke, dass das das Wichtigste war.

Soeren Dressler
 



 
 

3D-Grunglagen in QBasic
 

Das wichtigste was man zur 3D Programmierung wissen muß, ist die Tatsache, dass man auf dem Bildschirm keine dreidimensionalen Objekte darstellen kann. Der Bildschirm ist dafür ein bißchen zu flach.
Aber man kann einen Trick ausnutzen. Nämlich je weiter Etwas vom Beobachter entfernt steht, um so kleiner ist es.

So kann man sich den 3D Raum vorstellen.


 

Y ist die horizontale Achse
Z ist die vertikale Achse
X ist die Achse die aus dem Bildschirm kommt
a ist der XY Ebene
b ist der Winkel der Z-Achse
 

Also wie erzeuge ich den Effekt der Tiefe?

Wir haben von dem Objekt die X, Y und Z Koordinaten. Diese müssen in X und Y Koordinaten des Bildschirms um gewandelt werden. Das geht mit folgenden Formeln:

x2D = 256 * (x3D / (z3D + zCenter)) + xCenter
y2D = 256 * (y3D / (z3D + zCenter)) + yCenter

x2D und y2D sind die Koordinaten des Punktes der auf dem Bildschirm dargestellt wird.
x3D , y3D und z3D sind die Koordinaten des Objekts im dreidimensionalen Raum
xCenter , yCenter und zCenter sind Zentumwerte des Objekts.
 

Nun soll sich das Objekt aber auch bewegen und vielleicht sogar drehen.
Wie geht das?

Als erstes brauchen wir zwei Winkel a und b und diese Formeln:

xR = -xO * SIN(a) + yO * COS(a)
yR = -xO * COS(a) * SIN(b) - yO * SIN(a) * SIN(b) - zO * COS(b)
zR = -xO * COS(a) * COS(b) - yO * SIN(a) * COS(b) + zO * SIN(b)

xO , yO , und zO stehen für die Originalkoordinaten des Punktes im Raum
xR , yR , und zR stehen für den gedrehten Punkt.
a und b sind die Winkel der horizontalen und vertikalen Rotation

Kompliziert?

Vielleicht wird es mit diesem Beispiel verständlicher.
 

*************************

3D Beispiel von Soeren Dressler
e-mail: soeren01@t-online.de
url: fly.to/qmystic

*************************

DIM S!(359)
DIM C!(359)

DIM x3d(100, 1)
DIM y3d(100, 1)
DIM z3d(100, 1)
DIM x2d(100, 1)
DIM y2d(100, 1)
DIM ox3d(100, 1)
DIM oy3d(100, 1)
DIM oz3d(100, 1)

DIM olx2d(100, 1)
DIM oly2d(100, 1)
DIM olz2d(100, 1)
 

CONST PI = 3.141592

FOR i = 0 TO 359
   S!(i) = SIN(i * (PI / 180))
   C!(i) = COS(i * (PI / 180))
NEXT
 

SCREEN 13
zCenter = 100
xCenter = 150
yCenter = 100
 

FOR n% = 1 TO 20
FOR nn% = 0 TO 1
READ ox3d(n%, nn%), oy3d(n%, nn%), oz3d(n%, nn%)
NEXT nn%
NEXT n%

u = 0  ' erster Winkel
i = 0  ' zweiter Winkel
a = 1  ' Rotation fuer u
b = 1  ' Rotation fuer i

DO
LOCATE 1, 1: PRINT "Taste druecken zum beenden"

q = q + 1

IF q = 1 THEN
u = u + a
i = i + b
q = 0
IF u >= 360 THEN u = u - 360
IF u < 0 THEN u = u + 360
IF i >= 360 THEN i = i - 360
IF i < 0 THEN i = i + 360

END IF

FOR n% = 1 TO 20
olx2d(n%, 0) = x2d(n%, 0)
oly2d(n%, 0) = y2d(n%, 0)
olx2d(n%, 1) = x2d(n%, 1)
oly2d(n%, 1) = y2d(n%, 1)

'Rotation
     x3d(n%, 0) = -ox3d(n%, 0) * S!(u) + oy3d(n%, 0) * C!(u) + l
     y3d(n%, 0) = -ox3d(n%, 0) * C!(u) * S!(i) - oy3d(n%, 0) * S!(u) * S!(i) - oz3d(n%, 0) * C!(i)
     z3d(n%, 0) = -ox3d(n%, 0) * C!(u) * C!(i) - oy3d(n%, 0) * S!(u) * C!(i) + oz3d(n%, 0) * S!(i)

     x3d(n%, 1) = -ox3d(n%, 1) * S!(u) + oy3d(n%, 1) * C!(u) + l
     y3d(n%, 1) = -ox3d(n%, 1) * C!(u) * S!(i) - oy3d(n%, 1) * S!(u) * S!(i) - oz3d(n%, 1) * C!(i)
     z3d(n%, 1) = -ox3d(n%, 1) * C!(u) * C!(i) - oy3d(n%, 1) * S!(u) * C!(i) + oz3d(n%, 1) * S!(i)

' Umwandeln von 3D in 2D
x2d(n%, 0) = 256 * (x3d(n%, 0) / (z3d(n%, 0) + zCenter)) + xCenter
y2d(n%, 0) = 256 * (y3d(n%, 0) / (z3d(n%, 0) + zCenter)) + yCenter
x2d(n%, 1) = 256 * (x3d(n%, 1) / (z3d(n%, 1) + zCenter)) + xCenter
y2d(n%, 1) = 256 * (y3d(n%, 1) / (z3d(n%, 1) + zCenter)) + yCenter

'Alte Linien loeschen
IF olx2d(n%, 0) > -100 AND olx2d(n%, 0) < 420 AND olx2d(n%, 1) > -100 AND olx2d(n%, 1) < 320 THEN
LINE (olx2d(n%, 0), oly2d(n%, 0))-(olx2d(n%, 1), oly2d(n%, 1)), 0
END IF

'Neue Linien zeichnen
IF x2d(n%, 0) > -100 AND x2d(n%, 0) < 420 AND x2d(n%, 1) > -100 AND x2d(n%, 1) < 320 THEN
LINE (x2d(n%, 0), y2d(n%, 0))-(x2d(n%, 1), y2d(n%, 1)), 15
END IF
NEXT n%

LOOP UNTIL INKEY$ <> ""
 

DATA -20, -20, -20
DATA 20, -20, -20
DATA 20, -20, -20
DATA 20, 20, -20
DATA 20, 20, -20
DATA -20, 20, -20
DATA -20, 20, -20
DATA -20, -20, -20
DATA -20, -20, 20
DATA 20, -20, 20
DATA 20,-20, 20
DATA 20, 20, 20
DATA 20, 20, 20
DATA -20, 20, 20
DATA -20, 20, 20
DATA -20,-20,20
DATA -30, -30, 30
DATA 30, -30, 0
DATA 30, -30, 0
DATA 30, 30, -30
DATA 30,30,-30
DATA -30,30,0
DATA -30,30,0
DATA -30,-30,30
DATA 30,30,30
DATA 30,-30,0
DATA 30,30,30
DATA 30,30,-30
DATA 30,30,30
DATA -30,30,0
DATA 30,30,30
DATA -30,-30,30
DATA -30,-30,-30
DATA 30,-30,0
DATA -30,-30,-30
DATA 30,30,-30
DATA -30,-30,-30
DATA -30,30,0
DATA -30,-30,-30
DATA -30,-30,30
 

Soeren Dressler
 



 

ASM Tutorial Teil 2 Interrupts

Es ist natürlich war, das man mit den Grundlagen, die ich im ersten ASM Tutorial beschrieben habe, noch nicht besonders viel anfangen kann.

Wie funktioniert das nun, mit der Mouse?

Für solche Dinge gibt es so genannte Interrupts. Die Interrupts sind DOS Funktionen.
Es gibt insgesamt 256 davon und sie werden mit
INT (Interrupnummer)
aufgerufen.
INT 33h ist zum Beispiel der Mouseinterrupt.
Gesteuert werden die Interrupts meistens mit dem Register AX.
Bei Interrupt 33h bedeutet 1h in AX, dass die Mouse aktiviert wird und 2h, dass die Mouse deaktiviert wird.
Ein Beispiel:

MOV AX, 1h
INT 33h

AX wurde gleich 1h gesetzt und dann Interrupt 33h aufgerufen.
Die Folge ist, das Sichtbar werden der Mouse.

Das wars schon zum Interrupt

Soeren Dressler



 
 

ASM Tutorial Teil 3 Der Stack
 

Eine sehr wichtige Bedeutung in der Assembler Programmierung, hat der Stack.
Wie schon erwähnt, kann man in Assembler nur 4 Variablen verwenden. Wenn man nun aber mehr Variablen benötigt und den Inhalt der Register für später noch bracht, kann man diese in den Stack zwischen speichern.
QBasic kann den Stack auch verwenden. Zum Beispiel bei der Rekursion.
Der Stack ist eine Art Kellerspeicher oder Stapelspeicher.
Man kann eine Variable nach der anderen in ihm abspeichern. Man kann es sich wie einen Stapel vorstellen.
Die Werte werden übereinander gestapelt. Beim herauslesen wiederum, wird immer der oberste Wert gelesen.
Wenn man zum Beispiel  erst eine 1, dann eine 2 und danach eine 3 abspeichert, dann erhält man beim aus lesen erst die 3, dann die 2 du zum Schluß die 1.
Also wie macht man das nun.
Um den Inhalt eines Registers in de Stack zu kopieren, verwendet man
PUSH
Hinter PUSH steht das Register. z.B:
PUSH AX
Um den obersten Wert im Stack in ein Register zu schieben, gibt es:
POP
Hinter POP steht das REGISTER in welches der Wert abgelegt werden soll. Z.B:
POP AX

Hier mal ein kleines Programmbeispiel:

MOV AX, 1h
MOV BX, Fh
PUSH BX
PUSH AX
POP BX
POP AX

Wen ich mich nicht irre, ist nun in AX das Fh und in BX die 1h .
Die Werte wurden ohne eine dritte Variable vertauscht.

Es gibt natürlich noch mehr, was man mit dem Stack machen kann.
Man kann gezieht einen tieferen Wert aus dem Stack lesen.
Zum Beispiel
MOV AX, [BP + 2]
Was ist den nun BP und was bedeuten die eckigen Klammern?
Nun die Eckigen Klammern sagen, dass ein Speicherbereich an gewählt wird.
BP ist ein Base Pointer.
Das ist ja ganz schön und gut, hat nur zwei Hacken.
1. Muß BP erst mal wissen, wo der Stack eigentlich ist.
2. Darf man BP gar nicht benutzten da es vom Computer schon benutzt wird.

Aber dafür gibt es wie immer eine Lösung.
Es gibt noch einen weiteren Pointer, der immer genau weiß, wo der Stack gerade ist.
Es ist SP Stack Pointer.
Der Inhalt von SP muß also nur in BP kopiert werden.
MOV BP, SP
SP selbst darf unter keinen Umständen verändert werden, weil sonst der Computer stehen bleibt.
Das zweite Problem war  BP selbst.
Es ist so, dass der Assembler sich die Variablen nur ausleiht und sie dann wieder unverändert zurückgeben muß.
Also wie speichert man eine  Variable ab wenn man den Inhalt noch für später bracht.
Genau!
Mit PUSH und POP.
Das heißt, am Anfang sollte zuerst BP abgespeichert werden
PUSH BP
Dann wird die Stackposition ermittelt.
MOV BP, SP
Zum ende muß dann nur noch PB zurückgegeben werden
POP BP

Der Computer hat nun sein BP zurück ohne das er etwas gemerkt  hat.

Wichtig ist vielleicht noch, dass sich die Position des Stacks bei jeden PUSH um 2 verschiebet.
Das heißt , dass nach PUSH das BP aktualisiert  werden sollte.

Das wars zum Stack

Soeren Dressler
 



 
 

Turbo Pascal Tutorial 1 Grundaufbau

Für die meisten Qbasicprogrammierer ist Turbo Pascal ein Buch mit sieben Siegeln. Das liegt wo hauptsächlich an dem anderen Syntax und dem Programmaufbau.

Einer der Hauptunterschiede zwischen TP und QB ist das Ende jeder Zeile.
QBasic erkennt selbst wann eine  Zeile zu ende ist.
TP kann das nicht. Jede Zeile muß mit einem ; beendet werden.
Ein weiterer Unterschied ist die Struckturierung des Programms.

Der Grundaufbau sieht so aus:

PROGRAM ProgrammName;
USES crt, dos;
VAR

BEGIN
.
.
.
END.

Die erste Zeile ist immer
PROGRAM.
Daran weiß TP, dass es sich bei der Software ein normales Programm handelt.
Das ist wichtig, denn es gibt auch noch andere Struckturen.
Hinter PROGRAM kommt der Name der Software.

Als nächstes kommt
USES
Hier werden alle benötigten Uses aufgerufen. Bei QBasic sind das Libraries.
Welche Uses benötigt werden kann man aus der Hilfe zu den einzelnen Befehlen erfahren.
Die am häufigsten vorkommenden sind CRT und DOS. Es gibt zwar noch viel mehr, aber dazu später.

Nun kommt der Befehl
VAR
Hier müssen alle Globalen Variablen, die man in seinem Programm verwenden will, aufgelistet sein.
Das sieht dann wie folgt aus
Variablenname : Variablentyp;
Der Variablentyp ist teilweise schon aus QBasic bekannt.
Da gibt es zum Beispiel: STRING, INTEGER, LONGINT, uvm.
Aus der Hilfe von TP kann man auch erfahren, welche Variblentypen es noch gibt.

Dr Bereich zwischen
BEGIN
und
END.
Ist das Hauptprogramm. Hier können  nun alle Befehle stehen.

Alles klar?

Soeren Dressler



 
 

Turbo Pascal Tutorial 2 Ein- und Ausgabe von Text

Wie in QBasic, gibt es auch in Turbo-Pascal, Befehle wie PRINT und INPUT.
Der Printbefehl ist in Turbo-Pascal
Write(text);
und
Writeln(text);

Write schreibt den Text ganz normal. Dabei bleibt der Cursor hinter dem Text stehen.
Bei Writeln hingegen springt der Cursor in die nächste Zeile.
Ein Text muß immer in den Hochkommas stehen. Wenn eine Variable auf den Bildschirm gebracht werden soll, dürfen keine Hochkommas benutzt werden.

Der Inputbefehl in TP ist
Read(variable);
und
Readln(variable);

Read wartet auf die Eingabe und speichert sie in der Variable ab. Bei Readln sprint der Cursor wieder in die nächste Zeile.

Um den Bildschirm zu löschen benutzt man
CLRSCR;
Um den Cursor an eine bestimmte Stelle zu bringen kann man
GOTOXY(spalte, zeile);
Verwenden.
Die letzen beiden Befehle benötigen die Uses CRT

Wichtig: {Kommentare können bei TP in geschweifte Klammern gestellt werden.}

Hier nun ein kleinen Beispiel:
 

PROGRAM eingabe;

USES
     crt;

VAR
     textvar : STRING;

BEGIN
     clrscr;
     writeln('Bitte geben Sie etwas ein und druecken ENTER');
     readln(textvar);
     gotoxy(10,10);
     write('Sie haben ',textvar,' eingegen');
     readln;
END.

Das sollte es zur Ein und Ausgabe von Text fürs erste gewesen sein.

Soeren Dressler



 
 

Turbo Pascal Tutorial 3 Auswahlstrukturen

Auswahlstrukturen sollten eigentlich schon aus QBasic bekannt sein. Es sind zum Beispiel IF THEN oder SELECT CASE.

In Turbo-Pascal ist es etwa genauso einfach.

IF (Bedingung) THEN
BEGIN
.
.
END;

Die Bedingung ist genauso wie bei QBasic. Es können auch mehrere Bedingungen eingebaut werden.
Die müssen jeweils durch eine Klammer begrenzt werde und durch AND oder OR verbunden werden.
Alle Anweisungen die ausgeführt werden sollen, wenn die Bedingung war ist müssen BEGIN und END; eingeklammert sein.

Beispiel:

PROGRAM Auwahl1;

USES
    crt;

VAR
    Zahl : Longint;

BEGIN

Clrscr;

Write(Bitte Zahl eingeben:);
Readln(zahl);

IF (Zahl = 0) THEN Write(Es wurde Null eingeben.);

IF (Zahl < 0) THEN
    BEGIN
    Writeln(Es wurde eine Zahl eingegeben die kleiner ist als Null);
    END;

IF (Zahl > 0) AND (Zahl <> 10) THEN
    BEGIN
    Writeln(Es wurde eine Zahl eingegeben die großer ist als Null);
    Writeln(Die Zahl ist aber auch nicht 10 );
    END;

Readln;

END;
 

Eine CASE Auswahlstruktur  gibt es in Turbo-Pascal auch.

Die erste Zeile ist

CASE Ausdruck OF
Ausdruck ist eine Variable.
Dann kommt die Liste mit en Konstanten, die jeweils in Hochkommas stehen.
Konstante :
BEGIN
.
.
.
END;
Hinter dem Doppelpunkt kommen dann die Befehle die bei der Auswahl ausgeführt werden.
Sind es mehr als eine Anweisung, müssen sie wieder von BEGIN und END; eingeklammert werden.
Zum Schluss kommt nur noch das END; womit die CASE Auswahl zu ende ist.

Beispiel:

PROGRAM XCASE;

USES crt;

VAR zahl: word;
 

BEGIN

{Bildschirm loeschen}
clrscr;

{Text ausgabe}
write('Geben Sie bitte eine Zahl von 1 bis 10 ein:');

{Eingabe}
readln(zahl);

{Fallauswahl}
case zahl of
     1:
       begin
       Write('Sie haben die Eins gedrueckt.')
       end;
     2:
       begin
       write('Sie haben die Zwei gedrueckt.');
       end;
     3..5:
       begin
       writeln('Sie haben eine Zahl');
       writeln('zwischen 3 und 5 gedrueckt');
       end;
     6..9:
       begin
       writeln('Die Zahl ist groá');
       end;
     10:
       begin
       writeln('Die 10');
       end;
     else
       begin
       Writeln('Keine ', zahl, ' sollte gedrueckt werden');
       end;
end;

{Ausgabe}
writeln('Enter Druecken');

{Warte auf ENTER}
readln;

END.

So schwer ist es eigetlich nicht.

Soeren Dressler
 



 

Anfängerkurs 2

Thema: Rekursion

Den meisten dürfte Rekursion nicht bekannt sein. Vielleicht aber doch. Es gibt in der Mathematik etwas ähnliches. Es sind die rekursiven Zahlenfolgen  Bei diesen Zahlenfolgen kann man ein Glied nur ermitteln wen man dessen Vorgänger kennt.
Und genauso ist es bei der Rekursiven Programmierung.
 Das Problem wird solange auf sich selbst zurückgeführt , bis sich das Problem von selbst löst.
Wenn man das so hört, kann man sich nicht vorstellen, was damit gemeint ist. Es ist aber sehr einfach.
Die Funktion ruft sich einfach immer wieder selbst auf, bis die Abbruchbedingung erfüllt ist.
Dabei legt es alle Werte im Stack ab und holt sie wieder heraus wenn Abbruchbedingung erfolgt ist.

Ein einfaches Beispiel.
Ich möchte die Xte Zahl ermitteln, die doppelt so groß ist wie ihr Vorgänger.
Anders gesagt, die Zahl 2 hoch X mal.
 

DECLARE FUNCTION fkt! (Nr%)

CLS
INPUT "Welche Zahl"; n%
PRINT fkt(n%)

FUNCTION fkt (Nr%)

IF Nr% > 0 THEN
fkt = fkt(Nr% - 1) * 2
ELSE
fkt = 1
END IF

END FUNCTION
 

Wie man sehen kann ruft sich die Funktion immer wieder selbst auf, bis die Abbruchbedingung nämlich
Nr% = 0 erfüllt ist.
In diesem Fall erhält die Fkt ihren Startwert 1 und fällt dann wieder rückwerts aus dem Stack heraus.

Das Problem bei dieser Technik ist, dass es viel Stackspace benötigt wird und es relativ langsam ist.
Dafür kann ein Problem sehr leicht erklärt werden, dass heißt der Quellcode ist nicht sehr kompliziert.
 

Soeren Dressler
 



 

Bonus
 

Hier ist ein Beispiel das die Tasten des Keyboards in Echtzeit lesen kann.
Es weiß immer genau, welche Taste gerade gedrückt wird. Selbst wenn mehrere Tasten gleichzeitig gedrück werden. Das besondere ist, dass es ohne Assembler arbeitet.
Es ist aber wichtig, das NumLock ausgeschaltet ist, da es sonst zu Fehlern kommt.

Viel Spaß!
 

'#################################################################
'
'  xKey
'
'  Dieses Programm demonstriert die Tastatur-Direkt-Eingabe.
'  Es erkennt in Echtzeit, ob eine Bestimmte Taste gedrueckt wird
'  oder nicht.
'  Und es arbeitet ganz ohne Assembler
'
'  Wichtig!!!! [NumLock] muss AUS sein, da es sonst zu Problemen mit den
'  Cursortasten kommt.
'
'  Autor : Soeren Dressler
'  eMail : soeren01@t-online.de
'  WWW   : http://qmystic.xxn.de
'
'
'#################################################################
 

DIM SHARED xkey%(128)

DIM SHARED tasten AS STRING * 300

CLS
DO
 

        ' Rountine zum ermiteln der Tasten
        ii% = i%
        i% = INP(&H60)
        IF ii% <> i% AND i% < 128 THEN xkey%(i%) = -1
        IF ii% <> i% AND i% >= 128 THEN xkey%(i% - 128) = 0
        ' Das war's schon
 

        ' Ausgabe der Tasten
        tasten$ = ""
        FOR n% = 1 TO 128
        IF xkey%(n%) = -1 THEN MID$(tasten$, n% * 3, 3) = STR$(n%)
        NEXT
        LOCATE 1, 1
        PRINT tasten$
 

' Verlasse Schleife wenn ESC gedrckt wird.
LOOP UNTIL INKEY$ = CHR$(27)
 
 



So, das wars für diese Ausgabe. Ich hoffe das die QBasic-Times in Zukunft genauso gut ankommt wie bisher.
Also, wenn ihr etwas habt, was unbedingt mit in die nächste Ausgabe soll (Werbung für eurer Spiel oder Tool oder ein Tuturial  ...) , dann schick es mir einfach.

Bis zum nächsten Mal!

Soeren D.