skoczek

Szalone czasy początku lat 90-tych, w których komputer z podpiętą do niego myszką i charakterystycznym ekranem z okienkami i koszem stawał się dopiero standardem… kto by to jeszcze dzisiaj pamiętał? Kto dzisiaj jeszcze zdaje sobie sprawę, że kiedyś wszystkie polecenia wydawało się komputerowi wciskając mniej lub bardziej złożone sekwencje klawiszy? Kto by pomyślał, że na ekranie o rozdzielczości 640x480 pikseli można było wyświetlić aż 16 kolorów, a o piskliwych dźwiękach, które mógł wydobyć z siebie komputerowy głośniczek nawet nie warto wspominać.

W takich to właśnie szalonych czasach, w 1994 roku, napisałem program „SKOCZEK”, do symulacji ruchu konika szachowego. Była to praca dyplomowa, na zakończenie studiów informatycznych na Uniwersytecie Warszawskim, na wydziale Matematyki i Informatyki Stosowanej.

Żeby dzisiaj uruchomić program należy odpowiednio przygotować komputer: nie może być zbyt szybki i zbyt nowoczesny, a najlepiej by było, gdyby miał zainstalowany co najwyżej Windows XP!

Co program potrafi (kiedyś potrafił)?
  • Można ustawić dowolną (nawet prostokątną) szachownicę o maksymalnych rozmiarach 20x20 pól i minimalnych 4x4 pola
  • Można ustawić początkowe położenie skoczka na szachownicy
  • Można recznie wybierać kolejne pola, na które skoczy „Skoczek”
  • Można zdać się na automat, który będzie skakał Skoczkiem po wolnych polach
  • Po wyczerpaniu się wolnych pól na szachownicy, cofamy ruch o jedno pole (automatycznie lub ręcznie) i następuje próba kolejnego skoku
  • Program zatrzymuje się gdy znajdzie rozwiązanie - wypełnione wszystkie pola szachownicy
  • Można zapisać na dysku plik z kolejnymi skokami Skoczka.
  • Można ustawić początkowe parametry w pliku tekstowym, który program wczytuje na początku

Co ciekawego?

  • Program jest pisany w „starym” stylu – zwyczajne procedury, bez obiektów i innych wymyślnych konstrukcji programistycznych, które zaczęły się niebawem pojawiać.
  • W części głównej – tej, w której skoczek wybiera pole i skacze – mamy rekurencję w rekurencji! Już sama rekurencja jest dość trudna do wytłumaczenia (coś jakby spoglądać na odpowiednio ułożone lustra - taki obraz w obrazie), a podwójna, to już czyste umysłowe szaleństwo.
  • W graficznej części wykorzystane są odpowiednio zasymulowane instrukcje przeniesione wprost z języka LOGO – dla niewtajemniczonych, chodzi o wygodniejsze rysowanie kresek.
  • Na początku pojawia się animowana czołówka w trybie tekstowym!
Dla wszystkich zainteresowanych moduły TURTLE i WIN do pobrania

 Wacław Libront


{****************************************************************************}
{****************************************************************************}
{***                                                                      ***}
{***                       S  K  O  C  Z  E  K                            ***}
{***                                                                      ***}
{****************************************************************************}
{************************************** Libront Wacław  Bobowa  1994 ********}
program skoczek;
uses crt,win,turtle,graph;
{
 moduł WIN dołączany jest do pakietu Borland Pascal. W programie
 wykorzystywana jest tylko jedna procedura przyspieszające wyprowadzanie
 tekstów na ekran, w procedurze WSTAWKA:
  WRITESTR(x,y,n,a); gdzie:
	x,y - współrzędne ekranu tekstowego
	  n - napis
	  a - atrybuty wyprowadzanego napisu
 moduł TURTLE został opracowany samodzielnie i zawiera podstawowe komendy
 sterujące żółwiem zaczerpnięte z języka LOGO, wersja angielska:
 PU      - podnieś pisak
 PD      - opuść pisak
 FD(bok) - skok do przodu na odległość BOK
 BK(bok) - skok wstecz na odległość BOK
 RT(kąt) - obrót w prawo o kąt KĄT
 LT(kąt) - obrót w lewo o kąt KĄT
 a także zainicjowanie i zakończenie pracy w trybie graficznym.
}


const
  dx:array[1..8] of integer=(-1, 1, 2, 2, 1,-1,-2,-2);
  dy:array[1..8] of integer=( 2, 2, 1,-1,-2,-2,-1, 1);
  min    =4;                   {minimalna liczba wierszy i kolumn       }
  max    =20;                  {maksymakna liczba wierszy i kolumn      }
  bialy  =15;                  {numer koloru białego - rysowanie        }
  czarny =15;                  {numer koloru czarnego- wymazanie piona  }
  brzeg  :integer=20;          {odległość od brzegu ekranu do rysowania }
  poziomo:integer=8;           {początkowa liczba kolumn                }
  pionowo:integer=8;           {początkowa liczba wierszy               }
  pocz_po:integer=1;           {początkowe ustawienia piona             }
  pocz_pi:integer=1;           {                                        }
  pocz_ki:integer=1;           {jeśli 0 to losowanie kierunków skoków   }
  bok    :integer=54;          {początkowy bok pola szachownicy         }
  i_zapis:integer=0;           {ilość objechanych całych plansz         }
  dzwiek :boolean=true;        {sygnalizowane d¦więkiem jeśli TRUE      }
  krok   :boolean=true;        {jeśli true to po każdym skoku STOP      }
  ok     :boolean=true;        {zakończenie rekurencji w pętli głównej  }
  koniec :boolean=false;       {zakończenie skoków po ESC               }
  a_zapis:boolean=true;        {automatyczny zapis na dysk gdy wszystkie}
  ile_brakuje:integer=0;       {jeśli tyle wolnych pól zostało to koniec}
  ile_pionow :integer=64;      {ile pól należy obejść by skończyć       }
  gr_lini    :integer=3;       {grubość linii - wektor skoku konika     }
  gr_pion    :integer=3;       {grubość piona -                         }
  wzorek     :byte=11;         {wzorek wypełnienia pola szachownicy     }
  nazwa_p:string='skoczek.app';{nazwa pliku do którego zapisujemy wyniki}
type
  tszachy=array[1..max,1..max] of integer;
var
  szachy    :tszachy;       {tablica na numery kolejnych posunięć konika}
  
procedure bip;{************************************************************}
begin
  sound(100);delay(20);nosound;delay(100);
end;

procedure Libront;
var i:byte;
const
  l:string='"SKOCZEK"  W.Libront  Bobowa 1994';  {plik EXE zabezpieczony  }
  s:string='gcovig{`EN^CBXnCNC[M';  {przed zmianami napisu   }
begin
  for i:=1 to length(l) do
    if chr(byte(s[i]) xor 44) <> l[i] then
    begin                                {sprawdzenie czy nie grzebano    }
      koniec_graf;
      textmode(lastmode);
      textcolor(15);
      randomize;
      repeat
        poziomo:=random(80)+1;
        pionowo:=random(24)+1;
        gotoxy(poziomo,pionowo);
        write('   Ha   ');
        delay(20);
      until keypressed;
      czekaj;halt;
    end;
  outtextxy(brzeg,brzeg-10,l);           {wypisanie na ekranie właściciela}
end;

procedure szachownica(                   {*** rysowanie szachownicy ****}
                      po,                {ilość pól w poziomie          }
                      pi,                {ilość pól w pionie            }
                      bok,               {długość boku pola szachownicy }
                      wz,                {numer wzorka do wypełnienia   }
                      ko:integer);       {numer koloru pól szachownicy  }
var
  i,j,k:byte;
  x,y  :integer;
  napis:string;
begin
  setcolor(ko);
  setfillstyle(wz,ko);                {rodzaj wypełnieni pól szachownicy}
  for i:=1 to pi do
  begin
    for j:=1 to po do
    begin
      for k:=1 to 4 do
      begin
        fd(bok);rt(90);
      end;
      rt(90);fd(bok);lt(90);
      if (i+j) mod 2=0 then           {wypełniamy co drugie pole szachownicy}
        floodfill(getx-5,gety-5,ko);
    end;
    lt(90);
    for k:=1 to po do fd(bok);
    rt(90);fd(bok);
  end;
  for i:=1 to po do                  {numeracja wierszy i kolumn szachownicy}
  begin
    str(i,napis);
    outtextxy(xsro+(i-1)*bok+bok div 2,ysro+10,napis);
  end;
  for i:=1 to pi do
  begin
    str(i,napis);
    outtextxy(xsro-20,ysro-(i-1)*bok-bok div 2,napis);
  end;
end;{szachownica}

procedure pionek(bok,gr:integer);{***** rysowanie kwadracika **************}
var i:byte;
begin
  setlinestyle(0,0,gr);
  setwritemode(xorput);
  for i:=1 to 4 do
    begin
      fd(bok); rt(90)
    end;
  setwritemode(copyput);
  setlinestyle(0,0,1);
end;

procedure pion(po,pi,bok,kolor,gr:integer);{rysowanie na szachownicy piona}
var
  i,j,odstep :byte;
  pop_x,pop_y:real;
begin                              {!!! zawsze kolor biały bo XORPUT       }
  setcolor(kolor);                 {poprzednia wersja była z czarnym       }
  odstep:=bok div 3;               {odległość od brzegu pola szachownicy   }
  pop_x:=xcor;                     {poprzednie współrzędne żółwia          }
  pop_y:=ycor;
  xcor:=(po-1)*bok+odstep;         {nowe współrzędne żółwia                }
  ycor:=(pi-1)*bok+odstep;
  pionek(bok-2*odstep,gr);            {narysowanie piona                      }
  xcor:=pop_x;                     {powrót do poprzedniich ustawień żółwia }
  ycor:=pop_y;
  setcolor(bialy);
end;

procedure zeruj(po,pi:integer);{*** zerowanie tablicy na numery skoków *****}
var i,j:byte;
begin
  for i:=1 to po do
    for j:=1 to pi do
      szachy[i,j]:=0;
end;

function wsp(pocz,pole,bok:integer):integer;{** przeliczanie współrzędnych *}
begin
  wsp:=pocz+(pole-1)*bok+(bok div 2);
end;

procedure linia(x,y,x1,y1,bok,kolor,gr:integer);{* linia skoku konika *****}
begin
  setcolor(kolor);
  setwritemode(xorput);              {wykonuje inwersję przy nakładaniu}
  setlinestyle(0,0,gr);
  line(wsp(xsro,x ,bok),             {narysowanie lini skoku           }
       wsp(ysro,y ,-bok),
       wsp(xsro,x1,bok),
       wsp(ysro,y1,-bok));
  setwritemode(copyput);             {powrót do normalnego nakładania  }
  setlinestyle(0,0,1);
end;


procedure sprawdz_plik(nazwa:string);{************************************}
var plik:text;
begin
  assign(plik,nazwa);                 {jeśli plik jest to go zostaw}
  {$I-} reset(plik); {$I+}            {jeśli go nie ma to go załóż }
  if IOResult <> 0 then rewrite(plik);
  close(plik);
end;

function parametr:string;{*************************************************}
var nazwa:string;
begin                             {sprawd¦ parametr z jaki wywołani program}
  if paramstr(1)=''               {i sprawd¦ plik związany z tym parametrem}
    then nazwa:='skoczek.app'
    else nazwa:=paramstr(1);
  sprawdz_plik(nazwa);
  parametr:=nazwa;
end;

procedure dopisz_skoki(nazwa:string);{************************************}
var
  i,j,k:integer;
  ok   :boolean;
  out  :text;                              {do zapisania wyników na dysku}
begin
  assign(out,nazwa);
  append(out);
  writeln(out,'plansza  ',poziomo,'x',pionowo,i_zapis:6);
  writeln(out);
  for i:=poziomo downto 1 do
  begin
    {write(out,i:4);}
    for j:=1 to pionowo do
      if szachy[j,i]<>0
        then write(out,szachy[j,i]:4)
        else write(out,'  úú');
    writeln(out);
  end;
  {
  write(out,'    ');
  for j:=1 to pionowo do
    write(out,j:4);
  }
  writeln(out);
  writeln(out,'nr':5,'po':6,'pi':4);
  k:=1;
  repeat                                      {w pętlach szukamy kolejnych}
    ok:=false;                                {numerów skoków po tablicy  }
    for i:=1 to poziomo do                    {i jeśli są to je zapisujemy}
     for j:=1 to pionowo do                   {do pliku                   }
      if szachy[i,j]=k then
        begin
          writeln(out,k:5,i:6,j:4);
          ok:=true;
        end;
    inc(k);
  until ok=false;
  writeln(out);
  close(out);
end;

procedure zapisz_skoki;{******** Zapis wyników na końcu ******************}
var
  plik   :string;
  znak   :char;
begin
  write('Zapisać na dysk ? (t/n) ');
  writeln;
  while keypressed do znak:=readkey;
  znak:=readkey;
  if not(znak in ['t','T']) then
  begin
    writeln('Nie zapisano wyników na dysk');
    exit;
  end;
  plik:=parametr;
  if plik='skoczek.app'
  then
    begin
      write('Podaj nazwę pliku: ');
      readln(plik);
      if not(length(plik) in [1..12])
        then plik:='skoczek.app';
    end;
  sprawdz_plik(plik);
  writeln('Zapisuję wyniki do pliku: ',plik);
  dopisz_skoki(plik);
end;

procedure komunikat;{***** opis głównych opcji programu - ruch konika ******}
var x,y:integer;
begin
  x:=500;
  y:=brzeg;
  outtextxy(x,y+10,'F10 -krok/automat');
  outtextxy(x,y+20,'F9  -dzwiek');
  outtextxy(x,y+30,'F8  -losuj kier.');
  outtextxy(x,y+40,'F2  -zapis');
  outtextxy(x,y+50,'SPACE i ENTER');
  outtextxy(x,y+60,'    -krok/STOP');
  outtextxy(x,y+70,'   -krok wstecz');
  outtextxy(x,y+80,' -kierunek');
  outtextxy(x,y+90,'ESC-koniec');
end;

procedure wspolrzedne(i_zapis,nr,po,pi,ki:integer);{***********************}
var
  z,r,i,o,k:string;
  x,y      :integer;
begin                                  {wypisujemy na ekranie dane o skoku}
  x:=getmaxx-250;
  y:=10;
  str(i_zapis:3,z);
  str(nr:3,r);
  str(po,o);
  str(pi,i);
  str(ki,k);
  setviewport(x,y,x+200,y+10,true);
  clearviewport;                    {wymazujemy poprzedni obszar z napisem}
  setviewport(0,0,getmaxx,getmaxy,true);
  outtextxy(x,y,z+' '+r+' h:'+o+' v:'+i+' k:'+k);
end;

procedure skok(                {********* główna procedura skoków *********}
               i,              {numer skoku                                }
               x,              {współrzędne pola szachownicy na które skok }
               y:integer;      {poziomo X i pionowo Y                      }
               var ok:boolean);{jeśli true to koniec rekurencji            }
var
  ile_k,kierunek,x1,y1:byte;
  znak                :char;
  i_mem,k_mem         :integer;

  procedure stop;{****** obsługa klawiatury podczas skoków konika **********}
  begin
    znak:=readkey;
    case znak of
     #13,
     #32:krok:=true;                   {przechodzimy do trybo krokowego     }
     #27:begin                         {koniec skoków, opuszczamu procedurę }
           ok:=true;                   {symulujemy sytuację końcową         }
           i:=ile_pionow+1;              {                                    }
           koniec:=true;               {koniec                              }
           {a_zapis:=false;}             {nie zapisujemy na końcu bo automat  }
         end;
     #0 :begin
           znak:=readkey;
           case znak of
      {pra} #77,                       {kursory prawy i lewy służą do wyboru}
      {lew} #75:begin                  {kierunku następnego skoku           }
                  linia(x,y,x1,y1,bok,bialy,gr_lini);{wymazujemy poprzednią }
                  pion(x1,y1,bok,czarny,gr_pion);    {i piona z szachownicy }
                  szachy[x1,y1]:=0;
                  repeat
                    if znak=#77 then inc(kierunek);   {ustawiamy następny   }
                    if kierunek=9 then kierunek:=1;   {kierunek             }
                    if znak=#75 then dec(kierunek);
                    if kierunek=0 then kierunek:=8;
                    x1:=x+dx[kierunek];               {obliczany współrzędne}
                    y1:=y+dy[kierunek];               {skoku wg kierunku    }
                    wspolrzedne(i_zapis,i,x1,y1,kierunek);
                    if (x1 in [1..poziomo]) and       {sprawdzamy czy skok  }
                       (y1 in [1..pionowo]) and       {na nowe pole jest    }
                       (szachy[x1,y1]=0)    then      {możliwy  i           }
                       begin
                         linia(x,y,x1,y1,bok,bialy,gr_lini);{rysujemy linię }
                         pion(x1,y1,bok,bialy,gr_pion);{i piona             }
                         repeat                       {czekamy na następny  }
                           znak:=readkey;             {sygnał z klawiatury  }
                           if znak=#0 then znak:=readkey;
                         until znak in [#75,#77,#32,#13,#27];
                         linia(x,y,x1,y1,bok,bialy,gr_lini);{wymazanie pop- }
                         pion(x1,y1,bok,czarny,gr_pion);{rzedniego pola,lini}
                       end;                           {koniec wyboru kierunku}
                  until znak in [#32,#13,#27];        {gdy ESC,CPACE,ENTER  }
                  szachy[x1,y1]:=i;                   {ostateczne ustalenie }
                  linia(x,y,x1,y1,bok,bialy,gr_lini); {pozycji piona i lini }
                  pion(x1,y1,bok,bialy,gr_pion);
                end;
      {dół} #80:begin                   {cofnięcie ruchu konika             }
                  ok:=false;            {ustawiamy tak odpowiednie parametry}
                  i_mem:=i;             {żeby procedura rekurencyjna się nie}
                  k_mem:=ile_k;         {zorientowała że kombinujemy        }
                  i:=ile_pionow+1;      {opuszczamy rekurencyjny skok dalej }
                  ile_k:=8              {symulujemy przebadanie wszystkich  }
                end;                    {kierunków bez pozytywnego efektu   }
      {F10} #68:krok:=not(krok);        {automatycznie-krokowo przełącznik  }
      {F9 } #67:dzwiek:=not(dzwiek);    {sygnalizacja d¦więkowa             }
      {F8 } #66:if pocz_ki=0            {sposób wybierania kierunku do skoku}
                  then pocz_ki:=random(8)+1    {zgodnie ze schematem od...  }
                  else pocz_ki:=0;             {losowo wybierane            }
      {F2 } #60:dopisz_skoki(nazwa_p);
           end;
         end;
    end;
  end;  {stop}

begin                                   {początek procedury rekurencyjnej   }
  i_mem:=i;                             {zapamiętujemy aktualny numer skoku }
  if pocz_ki=0                          {potrzebne przy cofaniu             }
    then kierunek:=random(8)            {ustawiamy kolejny kierunek skoku   }
    else kierunek:=pocz_ki-1;           {losowo lub kolejny                 }
  ile_k:=0;                             {ilość przebadanych kierunków       }
  ok:=false;
  repeat
    inc(ile_k);                         {zapamiętujemy ilość przebadanych   }
    k_mem:=ile_k;                       {kierunków-potrzebne przy cofaniu   }
    kierunek:=(kierunek mod 8)+1;       {ustawiamy kolejny kierunek         }
    x1:=x+dx[kierunek];                 {ustalamy współrzędne kolejnego skoku}
    y1:=y+dy[kierunek];
    if (x1 in [1..poziomo]) and         {sprawdzamy czy skok jest możliwy   }
       (y1 in [1..pionowo]) and
       (szachy[x1,y1]=0)    then
    begin                               {jest wolne pole                    }
      szachy[x1,y1]:=i;                 {numer skoku do tablicy             }
      linia(x,y,x1,y1,bok,bialy,gr_lini);{rysujemy linię skoku              }
      pion(x1,y1,bok,bialy,gr_pion);    {rysujemy piona                     }
      wspolrzedne(i_zapis,i,x1,y1,kierunek);{współrzędne skoku na ekran     }
      if (krok) or (keypressed)         {jeśli praca krokowa lub naciśnięto }
        then stop;                      {klawisz to obsługa                 }
      if i1       then dec(po) else po:=poziomo;
    {p }   #77:if po1       then dec(pi) else pi:=pionowo;
         end;
       end;
  end;
 until znak in [#13,#32,#27];
end; {ustaw_piona}

procedure ustaw_szachy(var poziomo,pionowo,bok:integer;wz,ko:integer);
const hop=5;
var                                       {ustalamy wymiary szachownicy}
  znak       :char;
  p_i,p_o,b_o:byte;
  b1,b2      :integer;
  x,y        :integer;

  procedure komunikat;
  begin
    outtextxy(x,y+10,'USTAW SZACHOWNICE');
    outtextxy(x,y+30,'    KURSORY');
    outtextxy(x,y+40,'   zmiana o 1');
    outtextxy(x,y+50,' SHIFT + KURSORY');
    outtextxy(x,y+60,'   zmiana o 5');
    outtextxy(x,y+70,'ENTER - koniec');
    outtextxy(x,y+90,'maksymalnie - 400 pól');
  end;

  procedure oblicz_bok;
  begin
    b1:=(getmaxx-2*brzeg) div poziomo;
    b2:=(getmaxy-2*brzeg) div pionowo;
    if b1min+hop then dec(poziomo,hop) else poziomo:=min;
{S+p}#54:if poziomomin+hop then dec(pionowo,hop) else pionowo:=min;
   #0 :begin
         znak:=readkey;
         case znak of              {skok co jedno pole                 }
    { l }   #75:if poziomo>min then dec(poziomo) else bip;
    { p }   #77:if poziomomin then dec(pionowo) else bip;
         end;
       end;
  end;                             {obliczenie nowej długości boku     }
  oblicz_bok;
 until znak in [#13,#32,#27];
 xcor:=0;ycor:=0;
end; {ustaw_szachy}

procedure konfiguracja;{***************************************************}
var
  plik:text;                         {wczytujemy z dysku parametry programu}
  i:byte;
begin
  assign(plik,'skoczek.cfg');
  {$I-} reset(plik); {$I+}
  if IOResult=0 then                 {jeśli plik nie istnieje to nie wczyta}
  begin                              {sprawdzamy poprawność parametrów     }
    readln(plik,i);if i in [4..20] then pionowo:=i;
    readln(plik,i);if i in [4..20] then poziomo:=i;
    readln(plik,i);if i in [1 , 3] then gr_pion:=i;
    readln(plik,i);if i in [1 , 3] then gr_lini:=i;
    readln(plik,i);if i in [0..11] then wzorek:=i;
    readln(plik,i);if i in [0 , 1] then a_zapis:=boolean(i);
    close(plik);
  end;
end;

procedure wstawka;{*********************************************************}
const
  ile_w =16;      {ile wierszy}
  ile_k =8 ;      {ile kolumn }
  szer_l=2;       {jaki odstęp}
  ile_l =7;       {ile liter  }
  n:array[1..ile_w,1..70] of char=
  (
  ' SSSSSSSS  KK    KK  OOOOOOOO  CCCCCCCC  ZZZZZZZZ  EEEEEEEE  KK    KK ',
  ' SSSSSSSS  KK   KK   OOOOOOOO  CCCCCCCC  ZZZZZZZZ  EEEEEEEE  KK   KK  ',
  ' SS    SS  KK   KK   OO    OO  CC    CC  ZZ    ZZ  EE    EE  KK   KK  ',
  ' SS        KK  KK    OO    OO  CC              ZZ  EE        KK  KK   ',
  ' SS        KK  KK    OO    OO  CC             ZZ   EE        KK  KK   ',
  ' SS        KK KK     OO    OO  CC             ZZ   EE        KK KK    ',
  ' SS        KKKKK     OO    OO  CC            ZZ    EE        KKKKK    ',
  ' SSSSSSSS  KKK       OO    OO  CC            ZZ    EEEEEEE   KKK      ',
  ' SSSSSSSS  KKK       OO    OO  CC           ZZ     EEEEEEE   KKK      ',
  '       SS  KKKKK     OO    OO  CC          ZZ      EE        KKKKK    ',
  '       SS  KK KK     OO    OO  CC         ZZ       EE        KK KK    ',
  '       SS  KK  KK    OO    OO  CC         ZZ       EE        KK  KK   ',
  '       SS  KK  KK    OO    OO  CC        ZZ        EE        KK  KK   ',
  ' SS    SS  KK   KK   OO    OO  CC    CC  ZZ    ZZ  EE    EE  KK   KK  ',
  ' SSSSSSSS  KK   KK   OOOOOOOO  CCCCCCCC  ZZZZZZZZ  EEEEEEEE  KK   KK  ',
  ' SSSSSSSS  KK    KK  OOOOOOOO  CCCCCCCC  ZZZZZZZZ  EEEEEEEE  KK    KK '
  );
  {kolejność wlatujących wierszy}
  kol:array[1..ile_w] of byte=(1,16,2,15,3,14,4,13,5,12,6,11,7,10,8,9);
  a=$0F;
var
  znak:char;
  cz:string;
  i,j,w,k,l,s:byte;
begin
  s:=10;
  while keypressed do znak:=readkey;
  clrscr;
  for w:=1 to ile_w do
   for l:=1 to ile_l do
   begin
     delay(s*s);
     j:=kol[w];
     cz:=copy(n[j],(2+(l-1)*(szer_l+ile_k)),ile_k);
     for k:=79-ile_k downto (10+(l-1)*(szer_l+ile_k)) do
     begin
       writestr(k,j+3,cz+' ',a);
       delay(s);
     end;
     if keypressed then exit;
   end;
  writestr(50,23,'Wacław Libront  Bobowa 1994',a);
  while keypressed do znak:=readkey;
  znak:=readkey;
  for w:=1 to ile_w do
   for l:=1 to ile_l do
   begin
     delay(s*s);
     cz:=copy(n[w],(3+(l-1)*(szer_l+ile_k)),ile_k);
     for k:=(10+(l-1)*(szer_l+ile_k)) downto 2 do
     begin
       writestr(k,w+3,cz+' ',a);
       delay(s);
     end;
     writestr(2,w+3,'             ',a);
     if keypressed then exit;
   end;
end;

{********************** PROGRAM GŁÓWNY ************************************}
begin
  wstawka;                                    {demo                       }
  konfiguracja;                               {odczytanie parametrów z dysku}
  nazwa_p:=parametr;                          {sprawdzamy parametr wywołania}
  randomize;
  inicjuj_graf;
  xsro:=brzeg;                                {środek ekranu dla żółwia   }
  ysro:=getmaxy-brzeg;                        {bo szachownicę rysuje żółw }
  ustaw_szachy(poziomo,pionowo,bok,wzorek,bialy);{ustawienie szachownicy  }
  szachownica(poziomo,pionowo,bok,wzorek,bialy);
  zeruj(poziomo,pionowo);
  ustaw_piona(pocz_po,pocz_pi,gr_pion);       {ustawienie pierwszego piona}
  ile_pionow:=poziomo*pionowo-ile_brakuje;    {ile pionów należy postawić }
  clearviewport;                              {żeby skończyło badanie     }
  komunikat;Libront;                          {właściciel i sprawdzenie   }
  xcor:=0;ycor:=0;                            {żeby zaczęło rysować u dołu}
  szachownica(poziomo,pionowo,bok,wzorek,bialy);
  szachy[pocz_po,pocz_pi]:=1;                 {pierwszy skok              }
  pion(pocz_po,pocz_pi,bok,bialy,gr_pion);    {narysowanie skoczka        }
  skok(2,pocz_po,pocz_pi,ok);                 {zaczynamy zabawę           }
  czekaj;
  koniec_graf;
  textmode(lastmode);                         {wracamy do trybu tekstowego}
  if not(a_zapis) then zapisz_skoki;          {zapisujemy wyniki na dysk  }
end.                                          {jeśli nie było automatu    }
{**************************************************************************}

{**************************************************************************}
unit turtle;

interface
  uses Crt,Graph;

var
  Karta : Integer;
  Tryb  : Integer;
  xcor,                 {aktualne współrzędne kursora graficznego}
  ycor,
  kat   :real;
  pisak :boolean;
  max_x,
  max_y,
  xsro,                  {punkt 0,0 ekranu graficznego}
  ysro:integer;

procedure inicjuj_graf;
procedure koniec_graf;
procedure fd(x:integer);
procedure bk(x:integer);
procedure rt(x:integer);
procedure lt(x:integer);
procedure czekaj;
procedure pu;
procedure pd;


implementation

procedure inicjuj_graf;{***************************************************}
var
  driver,mode:integer;
begin
  driver:=detect;
  initgraph(driver,mode,'');
  max_x:=getmaxx;
  max_y:=getmaxy;
end;

procedure koniec_graf;{****************************************************}
begin
  closegraph
end;

procedure fd(x:integer);
begin
  moveto(round(xsro+xcor),round(ysro-ycor));
  xcor:=xcor+x*cos(kat*pi/180);
  ycor:=ycor+x*sin(kat*pi/180);
  if pisak
    then lineto(round(xsro+xcor),round(ysro-ycor))
    else moveto(round(xsro+xcor),round(ysro-ycor))
end;

procedure bk(x:integer);
begin
  fd(-x);
end;

procedure rt(x:integer);
begin
  kat:=kat-x;
end;

procedure lt(x:integer);
begin
  rt(-x);
end;

procedure czekaj;
var ch:char;
begin
  while keypressed do ch:=readkey;
  repeat until keypressed;
  while keypressed do ch:=readkey;
end;

procedure init;
begin
  xcor:=0;
  ycor:=0;
  kat:=90;
  pisak:=true;
  xsro:=getmaxx div 2;
  ysro:=getmaxy div 2;
  {moveto(round(xsro+xcor),round(ysro-ycor));}
end;

procedure pu;
begin pisak:=false end;

procedure pd;
begin pisak:=true end;

begin
  init;
end.