3 ' Hanoi_HK.BAS :Nicht-rekursiver ( iterativer ) Algorithmus, der zeigt, ' wie die Umsetzung des TURMs VON HANOI der Erzeugung eines einschrit- ' tigen, binären und zyklischen Codes äquivalent ist.(C) W.D.Meisel, 1986. '
4 ' Eine Arbeit über die Struktur und Erzeugung derartiger Algorithmen wird ' an anderer Stelle veröffentlicht werden. '
5 ' Hierarchisches Programm in WHILE-BASIC ( ohne GOTO und GOSUB nur mit ' Zielzeile 100 -- (mit zwei, die Iteration zeitoptimierenden Ausnahmen). ' Die Ausgaben sind zusätzlich durch Umstellen beschleunigt. '
6 ' Verschiedene Tips und Tricks sind im Quelltext knapp dokumentiert. U.a. ' finden Sie Verfahren zum Abbruch auch beim EXE-File, für "standfeste" Ein- ' gaben, zur BOOLE-Algebra bei BASIC, zur Kombination von Bewegungsabläufen ' usw.
10 WHILE NOT PROGRAMM% :PROGRAMM% =-1 'Einleitung'
11 KEY OFF :WIDTH 80 :CLS '=========='
12 DEFINT A - Z :TRUE= -1 :FALSE= 0 :DEF SEG 'Besitzt 'ne INTEGER-Variable x% =-1 als Wert, so ist 'while x% "wahr" und für x% = 0 "falsch"
13 KEY 17, CHR$(4) +CHR$(70) 'Key 11 - 14 sind von BASIC definiert !!!!
15 IF NOT K12 THEN K12=TRUE :ON KEY(12) GOSUB 15 ELSE LINKSPFEIL =TRUE :GOSUB 100: RETURN
16 IF NOT K13 THEN K13=TRUE :ON KEY(13) GOSUB 16 ELSE RECHTSPFEIL=TRUE :GOSUB 100: RETURN
17 IF NOT K17 THEN K17=TRUE :ON KEY(17) GOSUB 17 ELSE ABBRUCH =TRUE
18 IF ABBRUCH THEN Z$ = "Abbruch des Programms durch Benutzer !" : IF A.NR =2 THEN CLS :END ELSE LOCATE 21,1 :PRINT Z$ :END : LOCATE 21, 1:PRINT SPACE$(40) :PRINT" " :PRINT" ";:RETURN
19 ERSTMALS =TRUE
20 WEND 'Vorbereitung:Programm% als implizite Definition ist notwendig, weil ' noch keine explizite Definition erfolgt ist - wie z.B. DEFINT A-Z '
21 ' KEY 17 weist dem CTRL+BREAK nach KEY(17) ON eine neue Rolle zu : ' Das Programm wird sofort beendet -- Mit CONT kann bei GW - BASIC ' nach END fortgesetzt werden !!!!, im compilierten Programm nicht '
100 : 'Unterprogramm-Sprünge erfolgen (fast) immer auf 100 ! 'Ausgeführt wird dann der durch <Name> =TRUE aktivierte 'WHILE..WEND-Block und dort Desaktivierung sowie RETURN
223 COLOR 15,0 :PRINT"A,B,C" ;:COLOR 7,0 :PRINT " }
224 LOCATE 8,57 :PRINT"Vorschlag A =" ; A.EIN
225 LOCATE 9,57 :PRINT"Ihre Wahl ? "
226 LOCATE 13,57 :PRINT"Vorschlag T =" ; T.EIN
227 LOCATE 14,57 :PRINT"Ihre Wahl ? "
228 LOCATE 16,57 :PRINT"Vorschlag P : " ;S.EIN$","Z.EIN$
229 LOCATE 17,57 :PRINT"Ihre Wahl ? "
230 LOCATE 20, 7 :PRINT"Mit der Eingabe " ;
231 COLOR 15,0 :PRINT"E";:COLOR 7,0:PRINT"nde wird der V" ;
232 PRINT"orschlag durch Ihre Wahl ergänzt.
233 LOCATE 22, 2 :PRINT"Bitte wählen Sie .. :" ;
234 LOCATE 22,49 :PRINT"und drücken Sie die Taste ENTER
235 AUSWAHL=TRUE :A.MAX = 4 : GOSUB 100 : RETURN
239 WEND 'Menue ruft jeweils Auswahl samt anschließender Auswertung auf ' End.Auswahl setzt dann die restlichen Programmparameter und ruft ' den zweiten Hauptteil HANOI im PROGRAMM '
250 WHILE END.AUSWAHL :END.AUSWAHL = FALSE : UNZULAESSIG =FALSE
251 IF ERSTMALS THEN DIM HOEHE%(2), FUNDAMENT%(9) ,WEGWEISER% (9) ,HOCH%(2) ,PLATZ$(2), DREHUNG%(1) ,ZEILE$(18)
252 N =T.EIN:START$ = S.EIN$ : ZIEL$ = Z.EIN$
253 A.NR =A.EIN:START =ASC(START$)-65 : ZIEL = ASC(ZIEL$) - 65
255 FOR J=0 TO 2 :HOEHE% (J) =0:NEXT : HOEHE% (START) = N
256 ECHTZEIT.LFD!=0
257 KEY (12) ON :KEY (13) ON :KEY (17) ON
258 DEF SEG = 0 :POKE 1050 ,PEEK(1052): DEF SEG : RETURN 'Tastaturpuffer jetzt leer :vergleiche hierzu die Zeilen 5018 - 5019
259 WEND 'End.Auswahl und Anpassung an Ausgabe und Algorithmus ' Dim Platz$ hier (statt in 6000 ff.) für konsekutive Compilation !! '
299 ' '----------------- Nun folgt der nichtrekursive Algorithmus ------------- ' zum Umsetzen des Turm's von HANOI '
300 WHILE HANOI :HANOI =FALSE
310 STOCKWERK=9 :ANFANG = 3-ZIEL+START: MITTE = 3 - ZIEL - START : DREHUNG%(1) =ANFANG *(1 +N MOD 2) : DREHUNG%(0) =ANFANG *(2 -N MOD 2)'abhängig v. Ziel,Start u. N
320 FOR J=1 TO N :FUNDAMENT%(J) =START: WEGWEISER%(J)= 1 : NEXT
330 BESCHRIFTUNG = TRUE : GOSUB 100
335 'Abwechselnd werden immer das ursprünglich N -te Stock- 'werk und dann dasjenige umgesetzt, dessen übergeordne- 'tes eine gerade Zahl von Umsetzungen hinter sich hat.
340 ECHTZEIT! = TIMER
350 FOR SCHRITT =1 TO 2^N - 1
351 IF STOCKWERK>1 THEN STOCKWERK=1 : ELSE STOCKWERK= 2 : WHILE WEGWEISER%(STOCKWERK-1)> 0 : STOCKWERK= STOCKWERK+1 : WEND
352 DREHUNG =DREHUNG% (STOCKWERK MOD 2)
353 VON =FUNDAMENT%(STOCKWERK) : NACH =(VON+DREHUNG)MOD 3
389 WEND 'Hanoi Zeit-Optimierung mit GOSUB 900 in Zeile 356 ' Die Wegweiser ergeben den in Zeile 3 erwähnten ' einschrittigen, binären zyklischen Code !!!!!!!!
399 ' '----------------- Das Ausgabeende führt zurück nach PROGRAMM ------------ ' und dort in den 3.Hauptabschnitt ABSCHLUSS '
499 '************************************************************************* '----------------- Nun folgt die E I N G A B E der Parameter ----------- ' und deren Prüfung auf Zulässigkeit lt.MENUE '
500 WHILE AUSWAHL : AUSWAHL =FALSE
501 OK= FALSE : EINGABE = TRUE :GOSUB 100
502 ZEICHEN$ = LEFT$(EINGABE$,1)
503 IF ZEICHEN$ > "`" THEN ZEICHEN$ = CHR$(ASC(ZEICHEN$)-32)
504 IF ZEICHEN$ < > "E" THEN LOCATE 22,23 : PRINT SPACE$(21) : LOCATE 23, 1 : PRINT SPACE$(79)
505 IF ZEICHEN$ = "A" THEN AUSGABEFORM= TRUE :OK = TRUE
506 IF ZEICHEN$ = "T" THEN TURMHOEHE = TRUE :OK = TRUE
507 IF ZEICHEN$ = "P" THEN PLAETZE = TRUE :OK = TRUE
508 IF ZEICHEN$ = "E" THEN END.AUSWAHL= TRUE :GOSUB 100 : RETURN
509 IF NOT OK THEN UNZULAESSIG= TRUE ELSE UNZULAESSIG= FALSE
510 GOSUB 100 : AUSWAHL = TRUE
519 WEND 'Auswahl End.Auswahl führt zu PROGRAMM, nachdem ' die Parameter notiert worden sind '
602 WHILE E$="" :E$=INKEY$ :IF (E$ ="E" OR E$="e") AND Z = 0 THEN E =-1 ELSE E= 0
603 IF E THEN EINGABE = 0 :LOCATE 22 ,49 :PRINT SPACE$(31) : LOCATE 22,23 :COLOR 0 , 7 :PRINT "Eingabeende" ; : COLOR 7 , 0 : EINGABE$="E" :RETURN
604 WEND :E.=-ASC(E$) *(LEN(E$) = 1) : IF E.= 8 THEN IF Z > 0 THEN Z = Z - 1 :OL = CSRLIN : OS=POS(0) : LOCATE OL,OS -1 : PRINT" ";:EINGABE$= LEFT$(EINGABE$, LEN (EINGABE$)-1): LOCATE OL,OS -1
605 IF 32< E. AND E.<127 THEN IF Z < 5 THEN EINGABE$ = EINGABE$+E$:PRINT E$; :Z=Z+1 ELSE BEEP
606 E$="" :IF E.=13 THEN IF Z > 0 THEN PRINT CHR$(13): ZZ= 0 :EINGABE =FALSE ELSE BEEP
607 WEND'Vor Compilation bitte in 603 For hz= 0 to 7000 : next: 'vor color 7,0 einfügen, um das Eingabeende etwas länger anzuzeigen
608 RETURN
609 WEND 'Eingabe zeichenweise und zwischenraumfrei ' mit Steuerung durch backspace und carriage-return ' (LEN(E$) = 1) hat den Wert -1, falls WAHR, sonst 0 '
610 WHILE UNZULAESSIG :UNZULAESSIG = FALSE
611 LOCATE 22,23 :PRINT SPACE$(21);
612 LOCATE 23, 2 :PRINT"U N Z U L Ä S S I G !! - Bitte neue Eingabe " ; : PRINT" statt "; :COLOR 0,7 : PRINT" "EINGABE$" ";:COLOR 7,0
613 RETURN
619 WEND 'Unzulässig '
700 WHILE AUSGABEFORM :AUSGABEFORM = FALSE 'liefert A aus (1,2,3,4)
701 A =VAL (MID$(EINGABE$,3))
702 IF A<1 OR A>A.MAX THEN UNZULAESSIG= TRUE :GOSUB 100 : RETURN
703 IF 0<A AND A<A.MAX+1 THEN LOCATE 9,67 : PRINT"A =" ;A :A.EIN=A
704 RETURN
709 WEND 'Ausgabeform '
710 WHILE TURMHOEHE :TURMHOEHE = FALSE 'liefert 0 < T < 10
711 T =VAL (MID$(EINGABE$,3))
712 IF T<1 OR T>9 THEN UNZULAESSIG= TRUE :GOSUB 100 : RETURN ELSE LOCATE 14,67 : PRINT"T =" ;T :T.EIN=T
713 RETURN
719 WEND 'Turmhoehe '
720 WHILE PLAETZE :PLAETZE = FALSE 'liefert s$<>z$ε (A,B,C)
721 P$ = MID$(EINGABE$,3)
722 IF LEN(P$) <>3 THEN UNZULAESSIG= TRUE :GOSUB 100 : RETURN
725 IF S$ = Z$ OR S$<"A" OR S$>"C" OR Z$<"A" OR Z$> "C" THEN UNZULAESSIG= TRUE :GOSUB 100 : RETURN ELSE LOCATE 17,67 : PRINT "P : " S$"," Z$
726 S.EIN$ =S$ :Z.EIN$ = Z$
727 RETURN
729 WEND 'Plaetze ' '
899 '************************************************************************* '---- Ab hier beginnt die Zusammenstellung der A U S G A B E N ----------- ' aufgeteilt in AUSGABE A(uswahl).Nr und BESCHRIFTUNG A.Nr '
900 WHILE AUSGABE AND NOT A.NR.ABHAENGIG : A.NR.ABHAENGIG = TRUE
909 WEND 'gemeinsame Ausgabe ( z.B. Zeitmessung für Ausgaben) ' Zeit-Optimierung mit GOSUB 1000 in Zeile 903 '
999 '------------------------------------------------------------------------- ' Ausgabe 1 zeigt ein textgrafisches Umsetzen des Turm's '------------------------------------------------------------------------- '
1000 WHILE AUSGABE AND A.NR=1 : AUSGABE =FALSE
1001 FOR J=12 TO 17 ' ************* Schiebefenster
1010 '**************************************** Optimierung der Überflughöhe !
1011 IF HOEHE%(0) <=HOEHE%(1) AND HOEHE%(2)<=HOEHE%(1) AND VON<>1 AND NACH<>1 THEN UEBERFLUG=HOEHE%(1)+1 ELSE IF HOEHE%(NACH) < HOEHE%(VON) THEN UEBERFLUG=HOEHE%(VON) ELSE UEBERFLUG=HOEHE%(NACH)+1 '
2004 FOR J=N TO 1 STEP -1 : PRINT WEGWEISER%(J);:NEXT :PRINT
2005 FOR J=2 TO DL:NEXT : RETURN
2009 WEND 'Ausgabe für A.Nr.2 2002 u. 6005 anstelle 2003 u. 6006 ' ordnen die Plätze als A,B,C statt nach Start, Mitte und Ziel ' Die Wegweiser sind der in Zeile 3 erwähnte Binärcode !!!!!!!!!!! '
2999 '------------------------------------------------------------------------- ' Ausgabe 3 druckt Umsetzungen und deren zyklischen Binärcode '------------------------------------------------------------------------- '
3000 WHILE AUSGABE AND A.NR=3 : AUSGABE =FALSE
3001 FOR J=0 TO 2:HOCH%(J) =HOEHE%(J) :NEXT : HOCH%(VON) =HOEHE%(VON)-1:HOCH%(NACH)=HOEHE(NACH)+1
3005 FOR J=1 TO N :DRUCKZEILE$=DRUCKZEILE$+" "+STR$((1-WEGWEISER%(J))\2) : NEXT 'Die Wegweiser sind der durch die Umsetzung erzeugte Binärcode !!!! 'Vergleiche Programmzeile 3
3006 LPRINT DRUCKZEILE$
3007 RETURN
3009 WEND 'Ausgabe für A.Nr 3 Anstelle Hoch%(..) kann man ebenso ' in 3001 Hoehe%(..) ändern und in 3007 rücksetzen! '
3999 '------------------------------------------------------------------------- 'Ausgabe 4 kombiniert die Ausgaben 1 und 3 : ÜBERSICHT durch WHILE Basic '------------------------------------------------------------------------- '
4000 WHILE (BESCHRIFTUNG OR AUSGABE) AND A.NR=4
4001 A.NR=3 :GOSUB 100
4002 IF NOT LFD. THEN BESCHRIFTUNG=TRUE : LFD.=TRUE ELSE AUSGABE =TRUE
4003 A.NR=1 :GOSUB 100 : A.NR=4
4004 RETURN
4009 WEND 'Beschriftung o. Ausgabe für A.Nr.4 '
4999 '------------------------------------------------------------------------- ' Die Beschriftungen sind aus Zeitoptimierungsgründen hintenangestellt '------------------------------------------------------------------------- '
5000 WHILE BESCHRIFTUNG AND A.NR=1 :CLS: BESCHRIFTUNG =FALSE
5018 LOCATE 22 ,1:COLOR 0,7 : PRINT" Start durch ENTER " ; : WHILE INKEY$<>"":WEND:COLOR 7,0 : E$= "" :WHILE NOT E$ = CHR$(13) : E$ = INKEY$ :WEND:LOCATE 22,1 : PRINT SPACE$(25) : RETURN
5019 WEND 'Beschriftung für A.Nr.1 Anstelle ENTER auch CONT+chr$(13) ' Zeile 5018 löscht den Tastaturpuffer adreßunabhängig !!!!!!!! '
6000 WHILE BESCHRIFTUNG AND A.NR=2 :CLS :BESCHRIFTUNG =FALSE
6001 PLATZ$(START)=S.EIN$+": " :PLATZ$(ZIEL)=Z.EIN$+": " : PLATZ$(MITTE)=CHR$(MITTE+65) +": " : FOR J=1 TO N :PLATZ$(START) =PLATZ$(START) +CHR$(J+48): NEXT
6002 PRINT " Umsetzung des "CHR$(N+48)"-stöckigen Turms von START ( " START$ " ) nach ZIEL ( "ZIEL$" )" :PRINT
7010 LPRINT " Schritt Stockwerk Stockwerkshöhe Drehung Wegweiser - Positionen" 'Die Wegweiser sind der erzeugte Binärcode (vgl.Zeile 3) '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7011 LPRINT " von auf (1 2 3 4 usw. )
7012 LPRINT " nach A B C" : LPRINT
7013 LPRINT " 0"SPACE$(23)HOEHE(0); HOEHE(1);HOEHE(2)SPACE$(15) ; : FOR J=1 TO N :LPRINT 1-WEGWEISER%(J) ;: NEXT
7014 RETURN
7019 WEND 'Beschriftung für A.Nr.3 '
8999 '------------------------------------------------------------------------- ' Das Ende der Ausgabe berichtet über Zeitmessung und führt zu ABSCHLUSS '------------------------------------------------------------------------- '
9000 WHILE END.AUSGABE:END.AUSGABE =FALSE
9001 IF A.NR=4 THEN ZEIT =TRUE :GOSUB 100 : LPRINT:LPRINT" >> Text-Grafik u n d Listendruck <<" : LPRINT : DRUCK=TRUE :GOSUB 100
9002 IF A.NR=4 THEN LOCATE 21,1 : PRINT " >> Text-Grafik u n d Listendruck <<" : LOCATE 17,66 : PRINT ZEILE$(17):LOCATE 23,1 : BILD =TRUE :GOSUB 100
9003 IF A.NR=3 THEN LPRINT:LPRINT :CLS : ZEIT =TRUE :GOSUB 100 : DRUCK=TRUE :GOSUB 100
9004 IF A.NR=2 THEN PRINT : ZEIT =TRUE :GOSUB 100 : BILD =TRUE :GOSUB 100
9005 IF A.NR=1 THEN ZEIT =TRUE :GOSUB 100 : LOCATE 17,66 : PRINT ZEILE$(17):LOCATE 21,1 : BILD =TRUE :GOSUB 100