|
DataMuseum.dkPresents historical artifacts from the history of: MIKADOS |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about MIKADOS Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 7616 (0x1dc0) Notes: Mikados TextFile, Mikados_K Names: »HANOI«
└─⟦ec8c1e0b0⟧ Bits:30007442 8" floppy ( MIKPROG vol. 1-3, MIKREL vol. 1-3, PCSE 4.7.80 vol 1-3, GL.SYS ) └─ ⟦this⟧ »HANOI«
PROGRAM HANOI; (*****************************************************) (* *) (* T O W E R S O F H A N O I *) (* *) (* MOVE A TOWER COMPOSED OF N DISCS OF SIZES 1..N *) (* FROM THE LEFTMOST TO THE CENTER PEG OF 3 PEGS. *) (* ONLY ONE DISC MAY BE MOVED AT A TIME. A DISC *) (* MUST NEVER BE PLACED ON TOP OF A SMALLER DISC *) (*******************************************RM-790725*) CONST MAXTOWER = 13; YLEVEL = 18; (*MAXTOWER+5*) MAXLEVEL = 15; (*MAXTOWER+2*) DISCMAX = 26; (* 2 * MAXTOWER *) BLANKDISC = ' '; (* DISCMAX BLANKS *) TYPE PEG = ( LEFT, CENTER, RIGHT ); VAR HEIGHT, XADDRESS: ARRAY( LEFT..RIGHT ) OF INTEGER; TOWERSIZE: INTEGER; PROCEDURE CURSOR( X, Y: INTEGER ); BEGIN GOTOXY( X, YLEVEL-Y ); END (*CURSOR*); PROCEDURE MOVEDISC( DISCSIZE: INTEGER; FROM, TILL: PEG ); VAR DISCIMAGE: STRING(DISCMAX); I, STARTLEVEL, ENDLEVEL, X, XDISTANCE, LEVEL: INTEGER; BEGIN DISCIMAGE := BLANKDISC; FOR I:=MAXTOWER+1-DISCSIZE TO DISCSIZE+MAXTOWER DO DISCIMAGE(I) := '*'; STARTLEVEL := HEIGHT(FROM); ENDLEVEL := HEIGHT(TILL)+1; (* RAISE DISC FROM OLD PEG *) FOR LEVEL:=STARTLEVEL+1 TO MAXLEVEL DO BEGIN CURSOR( XADDRESS(FROM), LEVEL-1 ); WRITE( ' ':DISCMAX ); CURSOR( XADDRESS(FROM), LEVEL ); WRITE( DISCIMAGE ) END; HEIGHT(FROM) := HEIGHT(FROM) - 1; (* MOVE DISC HORIZONTALLY *) XDISTANCE := XADDRESS(TILL) - XADDRESS(FROM); X := XADDRESS(FROM) - DISCSIZE + MAXTOWER; IF XDISTANCE>0 THEN FOR X:=X TO X+XDISTANCE-1 DO BEGIN CURSOR( X, MAXLEVEL ); WRITE( ' ' ); CURSOR( X+DISCSIZE+DISCSIZE, MAXLEVEL ); WRITE( '*' ) END ELSE FOR X:=X-1 DOWNTO X+XDISTANCE DO BEGIN CURSOR( X+DISCSIZE+DISCSIZE, MAXLEVEL ); WRITE( ' ' ); CURSOR( X, MAXLEVEL ); WRITE( '*' ) END; (* LOWER DISC ONTO NEW PEG *) FOR LEVEL:= MAXLEVEL DOWNTO ENDLEVEL+1 DO BEGIN CURSOR( XADDRESS(TILL), LEVEL ); WRITE( ' ':DISCMAX ); CURSOR( XADDRESS(TILL), LEVEL-1 ); WRITE( DISCIMAGE ) END; HEIGHT(TILL) := ENDLEVEL; END (*MOVEDISC*); PROCEDURE MOVETOWER( SUBTOWERSIZE: INTEGER; FROM, TILL: PEG ); VAR HELPPEG: PEG; FUNCTION FIND( FIRST, SECOND: PEG): PEG; VAR HELP: PEG; BEGIN IF FIRST > SECOND THEN BEGIN HELP:=FIRST; FIRST:=SECOND; SECOND:=HELP END; IF FIRST=LEFT THEN IF SECOND=CENTER THEN FIND:=RIGHT ELSE FIND:=CENTER ELSE FIND:=LEFT; END (*FIND*); BEGIN (*MOVETOWER*) IF SUBTOWERSIZE=1 THEN MOVEDISC( 1, FROM, TILL ) ELSE BEGIN HELPPEG := FIND( FROM, TILL ); MOVETOWER( SUBTOWERSIZE-1, FROM, HELPPEG ); MOVEDISC( SUBTOWERSIZE, FROM, TILL ); MOVETOWER( SUBTOWERSIZE-1, HELPPEG, TILL ); IF EOF(OUTPUT) THEN BEGIN GOTOXY(1,24); EXIT( HANOI ) END; END; END (*MOVETOWER*); PROCEDURE INITIALIZE; PROCEDURE SETUPARRAYS; VAR PIN: PEG; BEGIN FOR PIN:=LEFT TO RIGHT DO BEGIN XADDRESS(CENTER) := 41 - MAXTOWER; XADDRESS(LEFT) := 41 - MAXTOWER*3; XADDRESS(RIGHT) := 41 + MAXTOWER; IF PIN=LEFT THEN HEIGHT(PIN):=TOWERSIZE ELSE HEIGHT(PIN):=0; END; END (*SETUPARRAYS*); PROCEDURE DRAW; VAR DISCLEVEL: INTEGER; I: INTEGER; DISCIMAGE: STRING(DISCMAX); BEGIN DISCIMAGE := BLANKDISC; FOR DISCLEVEL:=1 TO TOWERSIZE DO BEGIN FOR I:=MAXTOWER+1-DISCLEVEL TO DISCLEVEL+MAXTOWER DO DISCIMAGE(I) := '*'; CURSOR( XADDRESS(LEFT), TOWERSIZE-DISCLEVEL+1 ); WRITE( DISCIMAGE ) END; END (*DRAW*); BEGIN (*INITIALIZE*) WRITELN; WRITELN; REPEAT BEGIN WRITE('TOWERS OF HANOI -- ENTER TOWER SIZE (1-',MAXTOWER,'): '); READ( TOWERSIZE ) END; UNTIL TOWERSIZE IN (.1..MAXTOWER.); SETUPARRAYS; CLEARSCREEN; GOTOXY( 22,1 ); WRITE( 'T O W E R S O F H A N O I'); DRAW; END (*INITIALIZE*); BEGIN INITIALIZE; MOVETOWER( TOWERSIZE, LEFT, CENTER ); GOTOXY( 1, 24 ); END (*TOWERS OF HANOI*).