DataMuseum.dk

Presents historical artifacts from the history of:

MIKADOS

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about MIKADOS

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦2025b68b1⟧

    Length: 7616 (0x1dc0)
    Notes: Mikados TextFile, Mikados_K
    Names: »HANOI«

Derivation

└─⟦ec8c1e0b0⟧ Bits:30007442 8" floppy ( MIKPROG vol. 1-3, MIKREL vol. 1-3, PCSE 4.7.80 vol 1-3, GL.SYS )
    └─ ⟦this⟧ »HANOI« 

Text

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*).