|
|
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 - metrics - download
Length: 7648 (0x1de0)
Notes: Mikados TextFile, Mikados_K
Names: »HANOI«
└─⟦89d8689a3⟧ Bits:30003591 MIKADOS Pascal compiler (01.02.1982 E)
└─⟦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*).