PROGRAM Springer ;               { (ac) 08/1992 Turbo Pascal ab Version 4.0 }

  USES Crt ;    { ohne diese Zeile auch lauff„hig ab Version 3.0 }

  CONST
    BrettGroesse  = 5 ;                        { Seitenl„nge des Bretts }
    FelderAnzahl  = BrettGroesse * BrettGroesse ;
    { Es folgt die Zugliste. Sie gibt an, in welcher Reihenfolge die acht
      erreichbaren Felder besprungen werden sollen.                        }
    ZugListeX : ARRAY[1..8] OF Integer = ( 2,1,-1,-2,-2,-1,1,2 );
    ZugListeY : ARRAY[1..8] OF Integer = ( -1,-2,-2,-1,1,2,2,1 );

  TYPE
    BrettBereich        = 1..BrettGroesse ;
    FelderBereich       = 0..FelderAnzahl ;
    NachfolgerBereich   = 0..9 ; { Zuglistenindex eines erreichbaren Feldes }
    BrettTyp            = ARRAY[ BrettBereich,BrettBereich ] OF
                          RECORD
                            Besetzt:Boolean; NachfolgerAnz:NachfolgerBereich;
                          END;
    PositionsTyp        = RECORD x , y : -1..Brettgroesse+2 ; END;

  VAR
    Brett          : BrettTyp ;
    ZugListenIndex : FelderBereich ;  { Anzahl der aktuell besetzen Felder }
    StartPos       : PositionsTyp ;   { Startfeld }
    Erfolg         : Boolean ;        { Alle Felder besprungen ? }

  FUNCTION Erlaubt ( Pos : PositionsTyp ; i : NachfolgerBereich;
                     VAR NeuPos : PositionsTyp ) : Boolean;
    {Fhrt der i-te Sprung von Pos auf ein freies Feld innerhalb des Brettes ?}
    BEGIN
      WITH NeuPos DO BEGIN
        x := Pos.x + ZugListeX[i] ; y := Pos.y + ZugListeY[i] ;
        IF (x>0) AND (x<=BrettGroesse) AND
           (y>0) AND (y<=BrettGroesse) THEN Erlaubt := NOT Brett[x,y].Besetzt
        ELSE Erlaubt := False ;
      END; { With }
    END;  { Erlaubt }

  { Hier werden die Includdateien mit den Bewertungsfunktionen eingebunden.
    Die Programmzeilen aus diesen Dateien k”nnen auch hier eingesetzt werden.
    In diesem Fall oder wenn die Bewertungsfunktionen nicht ben”tigt werden,
    k”nnen (bzw. mssen) die folgenden zwei Zeilen gel”scht werden. }
  {$i Warnsdorf.Pas }
  {$i Luecke.Pas }

  PROCEDURE SucheWeg (pos:PositionsTyp;counter:FelderBereich;VAR erfolg:Boolean);
    VAR i      : NachfolgerBereich  ;
        NeuPos : PositionsTyp ;
    BEGIN
      { Feld besetzen, d.h. markieren und Nachfolger inkrementieren : }
      Inc ( ZugListenIndex );
      WITH Brett[Pos.x, Pos.y] DO BEGIN
        Besetzt := true ; GotoXY (Pos.x*3,Pos.y); Write (ZugListenIndex:2);
        FOR i := 1 TO 8 DO IF Erlaubt (Pos,i,NeuPos) THEN
          Dec (Brett[NeuPos.x,NeuPos.y].NachfolgerAnz);
      END; { With }

      { Noch nicht alle Sprnge ausgefhrt ? }
      IF counter < FelderAnzahl THEN BEGIN
        i := 1 ;   { Mit der ersten Sprungm”glichkeit anfangen }
        WHILE ( i <= 8 ) AND NOT erfolg DO BEGIN
          { An dieser Stelle kann "Erlaubt" durch "KeineLuecke" oder
            "MinGefunden" ersetzt werden. }
          IF Erlaubt ( Pos , i , NeuPos ) THEN BEGIN
            SucheWeg ( NeuPos , counter + 1 , erfolg );   { Rekursion }
          END;  { If }
          Inc ( i );  { N„chste Sprungm”glichkeit ausprobieren }
        END;  { While }

        IF NOT Erfolg THEN BEGIN { Feld wieder freigeben }
          Dec ( ZugListenIndex );
          Brett[ Pos.x , Pos.y ].Besetzt := false ;
          GotoXY ( Pos.x * 3 , Pos.y ); Write ( '  ' ); { Ausgabe }
          FOR i := 1 TO 8 DO IF Erlaubt ( Pos , i , NeuPos ) THEN
            Inc ( Brett[ NeuPos.x,NeuPos.y ].NachfolgerAnz);
        END; { If }
      END ELSE erfolg := true ;    { Ziel erreicht }
    END;  { SucheWeg }

  PROCEDURE Init ;
    VAR Hilf , Count : PositionsTyp ;
        i            : NachfolgerBereich ;
    BEGIN
      FOR Count.x := 1 TO BrettGroesse DO
        FOR Count.y := 1 TO BrettGroesse DO
          Brett[Count.x,Count.y].Besetzt:=false;
      FOR Count.x := 1 TO BrettGroesse DO
        FOR Count.y := 1 TO BrettGroesse DO
          WITH Brett[Count.x,Count.y] DO BEGIN
            NachfolgerAnz := 0 ;
            FOR i:=1 TO 8 DO IF Erlaubt(Count,i,Hilf) THEN Inc(NachfolgerAnz);
          END; { For }
      ZugListenIndex := 0 ; Erfolg := False ;
    END;  { InitBrett }

  BEGIN  { HauptProgramm }
    ClrScr ; Init ;
    StartPos.x := 1 ; StartPos.y := 1 ; { Startposition festlegen }
    SucheWeg ( StartPos , 1 , erfolg ); Readln ;
  END.   { HauptProgramm }
