home *** CD-ROM | disk | FTP | other *** search
/ Prima Shareware 3 / DuCom_Prima-Shareware-3_cd1.bin / PROGRAMO / PASCAL / HEJB / EXAM / SORT.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-04-21  |  14.1 KB  |  539 lines

  1. { ******************** Program Sort 3D ********************** }
  2. { ****** program demonstruje pouziti jednotky hejbunit ****** }
  3. {* pri nazornem zobrazeni procedury QuickSort na obrazovce * }
  4. {$define intr}
  5. uses Dos, Obraz3D, Unhejb, Unobdel, Unvokno, Unmenu, Untimer, Crt, Unpisbmp;
  6.  
  7. const N            : Integer = 60; { poçet prvkû }
  8.       Poc_Pom      : Integer = 40; { poçáteçní pomalost animace }
  9.       Metoda       : Integer = 0;  { zvolená metoda }
  10.  
  11.       _Qsort    = 1;               { çísla metod }
  12.       _Buble    = 2;
  13.       _Vyber    = 3;
  14.       _Merge    = 4;
  15.       _Qsortpar = 5;
  16.  
  17.       _Nahodna   = 1;              { çísla posloupností }
  18.       _Vzestupna = 2;
  19.       _Sestupna  = 3;
  20.  
  21.       _Posl        : Byte    = 0;  { zvolená posloupnost }
  22.  
  23.       Jit_Ven      : Boolean = False; { Tato promênná se stará o vypadnutí ze Sortu, ve kterém se nám uæ nechce bÿt }
  24.  
  25. type
  26.   Typ_Moje_Menu = object(Typ_Menu_Vyber)
  27.                     procedure Vm0;virtual;
  28.                   end;
  29.  
  30.   Typ_Prvek = object(Typ_Integer)
  31.                 Klic : Integer;
  32.                 procedure Dodel_Anim_Prohod(var S_Kym : Typ_Prvek);
  33.               end;
  34.  
  35.   Typdat   = array[0..100]of Typ_Prvek;
  36.  
  37. var  Data : Typdat; { pole t⌐ídênÿch prvkû }
  38.  
  39. procedure Cisla_Prvku(Zob : Byte);
  40. { procedura zobrazuje a zhasíná na obrazovce çísla prvkû }
  41. const Pomzob : Byte = 0;
  42. var  S    : string[5];
  43.      K    : Integer;
  44.      Pom  : _Bod3D;
  45. begin
  46.   if Pomzob <> Zob then
  47.   for K := 1 to N do
  48.     begin
  49.       Str(K, S);
  50.       Pom := Hezky_Rozmistit(K)^;
  51.       case Zob of
  52.         2 : Obrazovka.Smaz_Retez(Pom.X+2, Pom.Y, Pom.Z+1, 2, S, True);
  53.         1 : Obrazovka.Pis_Retez(Pom.X+2, Pom.Y, Pom.Z+1, 2, S, True)
  54.       end;
  55.     end;
  56.   Pomzob := Zob;
  57. end;
  58.  
  59. const Cesta : array[1..3]of Typ_Instrukce = (Vm0, Jmpa0, Endc) ;
  60.  
  61. const Menudef : string =
  62. '49 15 5  15 112 10  30 11  6 4'+ { posice [53, 11, 4] barva textu 15, barva zvyraznêného ⌐ádku 112, barva rámeçku 10}
  63.                                   { rozmêr 30x11, 6 prvkû, zaçátek na çtvrtém }
  64. 'delay~ i 42 14 7  10 10 96  40  1 400  1'+ { editace çísla, posice [46, 10, 4], barva textu 10, barva rámeçku 10,
  65.                                             { zvÿraznênÿ text téæ 96, poçáteçní hodnota 40, minimum 1 a maximum 400 }
  66. 'method~ v 31 15 9 15 112 10 20 7 5 1'+
  67.   'quicksort~o'+
  68.   'bublesort~o'+
  69.   'maxsort~o'+
  70.   'mergesort~o'+
  71.   'paralelni qsort~o';
  72.   Menudef2 : string =
  73. 'Element numbers~v 21 16 5 15 112 10 30 4 2 2'+
  74.   'on~o'+
  75.   'off~o'+
  76. 'sequence~v 36 16 3 15 112 10 15 5 3 1'+
  77.   '''random''~o'+
  78.   'increasing~o'+
  79.   'decreasing~o'+
  80. 'run~v 36 18 1 15 112 10 15 4 2 2'+
  81.   'start~o'+
  82.   'stop~o'+
  83. 'end~o';
  84.  
  85. procedure Typ_Moje_Menu.Vm0;
  86. var C : Word;
  87.     S : string[5];
  88. begin
  89.   if KeyPressed then
  90.     begin
  91.       C := Byte(ReadKey);
  92.       if C = 0 then  C := 256* Byte(ReadKey);
  93.  
  94.       Zpracuj_Key(C); { pokud je stisknuta klávesa, ovlivní se stav menu }
  95.  
  96.       { çtení hodnot menu }
  97.       if (Sub_Menu^[5]^.Out_Hodnota = 2) or
  98.          (Out_Hodnota = 6)
  99.          then Jit_Ven := True
  100.          else Jit_Ven := False;
  101.       if (Sub_Menu^[3]^.Potvrzeno)
  102.          then Cisla_Prvku(Sub_Menu^[3]^.Out_Hodnota);
  103.       if Metoda <> Sub_Menu^[2]^.Out_Hodnota then
  104.         begin
  105.           Metoda := Sub_Menu^[2]^.Out_Hodnota;
  106.           Jit_Ven := True;
  107.         end;
  108.       if Sub_Menu^[1]^.Out_Hodnota <> Poc_Pom then
  109.         begin
  110.           Poc_Pom := Sub_Menu^[1]^.Out_Hodnota;
  111.           Unfront.set_Pomalost(Poc_Pom);
  112.         end;
  113.       if Sub_Menu^[5]^.Out_Hodnota = 2 then
  114.         if Sub_Menu^[4]^.Potvrzeno then
  115.           begin
  116.             _Posl := Sub_Menu^[4]^.Out_Hodnota;
  117.             for C := 1 to N do
  118.               begin
  119.                 case _Posl of
  120.                     _Nahodna : Data[C].Klic := Random(1000);
  121.                     _Vzestupna : Data[C].Klic := C;
  122.                     _Sestupna : Data[C].Klic := N-C;
  123.                   end;
  124.                 Data[C].Vytvor(Data[C].Klic, 3, C mod 10 + 5, C mod 10 + 5, Strom_Ram);
  125.               end;
  126.             Sub_Menu^[4]^.__Stav_Menu := Sub_Menu^[4]^.__Stav_Menu and ($Ff xor __Potvrzena_Hodnota)
  127.           end;
  128.     end;
  129. end;
  130.  
  131. type Typ_Pocitani = object(Typ_Vokynko) { t⌐ída, ve které se sçítá p⌐i⌐azení a porovnání }
  132.                       Porovnani, Prohozeni : Integer;
  133.                       constructor Init;
  134.                       procedure Nuluj;
  135.                       procedure Zvets_Porovnani;
  136.                       procedure Zvets_Prohozeni;
  137.                       procedure Zapis;
  138.                     end;
  139.  
  140. constructor Typ_Pocitani.Init;
  141. begin
  142.   Typ_Vokynko.Init;
  143.   Presun(11, 18, 1);
  144.   Porovnani := 0;
  145.   Prohozeni := 0;
  146.   Vytvor_Ram(27,4,4,4,Strom_Ram);
  147.   set_Psaci_Barva(27);
  148.   GotoXY(1,1);
  149.   Pis('Num of comparisons  :');
  150.   WriteLn;
  151.   Pis('Num of assignements :');
  152.   Zobraz;
  153. end;
  154.  
  155. procedure Typ_Pocitani.Nuluj;
  156. begin
  157.   Porovnani := 0;
  158.   Prohozeni := 0;
  159.   Zapis;
  160. end;
  161.  
  162. procedure Typ_Pocitani.Zapis;
  163. begin
  164.   GotoXY(22,1);Pisint(Porovnani, 4);
  165.   GotoXY(22,2);Pisint(Prohozeni, 4);
  166. end;
  167.  
  168. procedure Typ_Pocitani.Zvets_Porovnani;
  169. begin
  170.   Inc(Porovnani);
  171.   Zapis;
  172. end;
  173.  
  174. procedure Typ_Pocitani.Zvets_Prohozeni;
  175. begin
  176.   Inc(Prohozeni);
  177.   Zapis;
  178. end;
  179.  
  180. var __Pocit : Typ_Pocitani; {objekt, ve kterém se zobrazuje poçet p⌐i⌐azení a porovnání }
  181.  
  182. function Vetsi( Jedno, Druhe : Integer ) : Boolean;
  183. begin
  184.    if Jedno > Druhe
  185.                   then Vetsi := True
  186.                   else Vetsi := False;
  187.   __Pocit.Zvets_Porovnani;
  188. end;
  189.  
  190. function Mensi( Jedno, Druhe : Integer ) : Boolean;
  191. begin
  192. if Jedno < Druhe
  193.                   then Mensi := True
  194.                   else Mensi := False;
  195.   __Pocit.Zvets_Porovnani;
  196. end;
  197.  
  198. function Rovno( Jedno, Druhe : Integer ) : Boolean;
  199. begin
  200.   if Jedno = Druhe
  201.     then Rovno := True
  202.     else Rovno := False;
  203.   __Pocit.Zvets_Porovnani;
  204. end;
  205.  
  206.  
  207. procedure Typ_Prvek.Dodel_Anim_Prohod;
  208. var Pom : Typ_Prvek;
  209. begin
  210.   Typ_Obdelnik.Dodel_Anim_Prohod(S_Kym);
  211.  
  212.   Pom.Init;
  213.   Pom   := Self;
  214.   Self  := S_Kym;
  215.   S_Kym := Pom;
  216.   __Pocit.Zvets_Prohozeni;
  217.   __Pocit.Zvets_Prohozeni;
  218.   __Pocit.Zvets_Prohozeni;
  219. end;
  220.  
  221. var  __Menu : Typ_Moje_Menu;
  222.      K      : Integer;
  223.      S      : string;
  224.  
  225. procedure Maxsort(var Data : Typdat);
  226. var I, J : Integer;
  227. begin
  228.   for I := 1 to N-1 do
  229.     for J := I to N-1 do
  230.       if Vetsi(Data[I].Klic, Data[J].Klic) then
  231.         begin
  232.           Data[I].Dodel_Anim_Prohod(Data[J]);
  233.           if Jit_Ven then Exit;{ aby se nemuselo dlouho cekat, nemusí bÿt }
  234.         end;
  235. end;
  236.  
  237. procedure Bublesort(var Data : Typdat);
  238. var I, J : Integer;
  239. begin
  240.   for I := 1 to N-1 do
  241.     for J := N-1 downto I do
  242.       if Vetsi(Data[J].Klic, Data[J+1].Klic) then
  243.         begin
  244.           Data[J+1].Dodel_Anim_Prohod(Data[J]);
  245.           if Jit_Ven then Exit;{ aby se nemuselo dlouho cekat, nemusí bÿt }
  246.         end;
  247. end;
  248.  
  249. procedure Quicksortpar(var Data : Typdat);
  250. { demonstruje moænost paralelního zpracování p⌐i qsotu }
  251. var Pom : Typ_Prvek;
  252.     I   : Integer;
  253. procedure Castecne_Usporadani(K,M:Integer);
  254.  
  255.  var I, J, Y, Fn : Integer;
  256.  
  257.  begin
  258.   I := K;
  259.   J := M;
  260.   Y := Data[(K + M) div 2].Klic;
  261.   repeat
  262.     while Mensi(Data[I].Klic, Y) do I := I+1;
  263.     while Vetsi(Data[J].Klic, Y) do J := J-1;
  264.     if I <= J then
  265.      begin
  266.        if not Rovno(Data[J].Klic, Data[I].Klic) then
  267.          begin
  268.            repeat
  269.            until (not Data[I].Hejbe_Se) and (not Data[J].Hejbe_Se);
  270.  
  271.            Data[I].Anim_Prohod(Data[J]);
  272.            __Timer.Zarad_Prvek(Data[I]);
  273.            __Timer.Zarad_Prvek(Data[J]);
  274.             { prohozeni na obrazovce }
  275.  
  276.            Pom     := Data[I];
  277.            Data[I] := Data[J];
  278.            Data[J] := Pom;
  279.             { prohozeni v pameti }
  280.            __Pocit.Zvets_Prohozeni;
  281.            __Pocit.Zvets_Prohozeni;
  282.            __Pocit.Zvets_Prohozeni;
  283.  
  284.            if Jit_Ven then Exit;{ aby se nemuselo dlouho cekat, nemusí bÿt }
  285.          end;
  286.        I := I+1;
  287.        J := J-1;
  288.      end;
  289.   until I>J;
  290.  
  291.   if K < J then Castecne_Usporadani(K, J);
  292.   if I < M then Castecne_Usporadani(I, M);
  293.  
  294.  end;  {pomocne procedury Castecne_usporadani}
  295.  
  296. begin
  297.    Pom.Init;
  298.    Castecne_Usporadani(1,N);
  299.    __Timer.Dodelej_Pohyb_Na_Pocet(1); { ve frontê __timer zûstane pouze prvek - menu }
  300. end;
  301.  
  302. procedure Quicksort(var Data : Typdat);
  303. { demonstruje klasickÿ qsort }
  304. var Pom : Typ_Prvek;
  305.  
  306. procedure Castecne_Usporadani(K, M : Integer);
  307.  
  308.  var I, J, Y, Fn : Integer;
  309.  
  310.  begin
  311.   I := K;
  312.   J := M;
  313.   Y := Data[(K + M) div 2].Klic;
  314.   repeat
  315.     while Mensi(Data[I].Klic, Y) do I := I+1;
  316.     while Vetsi(Data[J].Klic, Y) do J := J-1;
  317.     if I <= J then
  318.      begin
  319.        if not Rovno(Data[J].Klic, Data[I].Klic) then
  320.          begin
  321.            Data[I].Dodel_Anim_Prohod(Data[J]);
  322.  
  323.            if Jit_Ven then Exit;{ aby se nemuselo dlouho cekat, nemusí bÿt }
  324.          end;
  325.        I := I+1;
  326.        J := J-1;
  327.      end;
  328.   until I>J;
  329.  
  330.   if K < J then Castecne_Usporadani(K, J);
  331.   if I < M then Castecne_Usporadani(I, M);
  332.  
  333.  end;  {pomocne procedury Castecne_usporadani}
  334.  
  335. begin
  336.    Pom.Init;
  337.    Castecne_Usporadani(1,N);
  338. end;
  339.  
  340. procedure Mergesort(var Data : Typdat);
  341. var J : Integer;
  342.  
  343. procedure Vnitrek;
  344. var Pompole : array[0..9]of Integer;
  345.     Pomdata : Typdat;
  346.     Pomind  : array[0..9,1..30]of Integer;
  347.     I, J, Pom, Pomid : Integer;
  348.  
  349.  
  350.   procedure Trida(var Prvek : Typ_Prvek; Ktera : Integer);
  351.   begin
  352.     Prvek.Dodel_Anim_Posun_Bod(Xyz_Bod(Ktera*5, Obrazovka.Y_Obr- 5- (Pompole[Ktera]*2+1), -Pompole[Ktera])^);
  353.     Inc(Pompole[Ktera]);
  354.     Pomind[Ktera, Pompole[Ktera]] := J;
  355.     Pomind[Ktera, Pompole[Ktera]+1] := 0;
  356.     __Pocit.Zvets_Prohozeni;
  357.   end;
  358.  
  359.   function Moc(Co, Nakolik : Integer):Integer;
  360.   var I, A : Integer;
  361.   begin
  362.     A := 1;
  363.     for I := 1 to Nakolik do A := A*Co;
  364.     Moc := A;
  365.   end;
  366.  
  367. begin
  368.   for J := 1 to N do Pomdata[J].Init;
  369.   for I := 0 to 2 do
  370.     begin
  371.       for J := 0 to 9 do
  372.         begin
  373.           Pompole[J] := 0;
  374.           Pomind[J,1]:=0;
  375.         end;
  376.  
  377.       for J := 1 to N do
  378.         begin { rozmístêní objektû do t⌐íd podle I-té çíslice }
  379.           Trida(Data[J], (Data[J].Klic div Moc(10,I)) mod 10);
  380.           if Jit_Ven then Exit;{ aby se nemuselo dlouho cekat, nemusí bÿt }
  381.         end;
  382.  
  383.       Pomid := 1;
  384.       for J := 0 to 9 do
  385.         begin
  386.           Pom := 1;
  387.           while Pomind[J, Pom] <> 0 do
  388.             begin
  389.               Pomdata[Pomid] := Data[Pomind[J, Pom]];
  390.               Inc(Pomid);
  391.               Inc(Pom)
  392.             end;
  393.         end;
  394.       for J := 1 to N do Data[J] := Pomdata[J];
  395.       delay(1400);
  396.       for J := 1 to N do
  397.         begin
  398.           Data[J].Dodel_Anim_Posun_Bod(Hezky_Rozmistit(J)^);
  399.           if Jit_Ven then Exit;{ aby se nemuselo dlouho cekat, nemusí bÿt }
  400.           __Pocit.Zvets_Prohozeni;
  401.         end;
  402.     end;
  403. end;
  404.  
  405. begin
  406.   Vnitrek;
  407.   for J := 1 to N do Data[J].Presun_Bod(Hezky_Rozmistit(J)^);
  408. end;
  409.  
  410.  
  411.  
  412.  
  413.  
  414.  
  415.  
  416.  
  417.  
  418.  
  419.  
  420. var P    : Pchar;
  421.     I, J : Word;
  422.  
  423. begin
  424.   J := Length(Menudef)+Length(Menudef2);
  425.   GetMem(P, J+1);
  426.   for I := 0 to Length(Menudef) do
  427.     P^[I] := Menudef[I+1];
  428.   for I := Length(Menudef)  to J-1 do
  429.     P^[I] := Menudef2[I-Length(Menudef)+1];
  430.  
  431.   Randomize;
  432.  
  433.   Obrazovka.Nastav_mod(3+__Sada_3D_8X8);   { nastavi hezky vypadajici sadu }
  434.   Obrazovka.ClrScr;
  435.   I := 0;
  436.   Unfront.set_Pomalost(Poc_Pom);
  437.   __Menu.Init(P,I);
  438.   __Menu.Hejbej(Cesta);
  439.   __Timer.Zarad_Prvek(__Menu);
  440.   __Menu.GotoXY(1,7);
  441.   __Menu.set_Psaci_Barva(LightRed);
  442.   __Menu.Pis('   Demo k jednotce Unhejb');
  443.   __Menu.WriteLn;
  444.   __Menu.Pis('   Vyrobeno ve Praze 1993');
  445.   __Menu.WriteLn;
  446.   __Menu.Pis('PrScr uloæí obrazovku do BMP');
  447.  
  448.    { Pro zkopírování obrazovky na disk, viz UnPisBMP }
  449.    { Obrazovkové soubory na disku se jmenují postupnê sort1.bmp, sort2.bmp }
  450.  
  451.   set_Par_Pisbmp('sort',nil);
  452.   On_Pisbmp;
  453.  
  454.    { Inicializace poçítadla porovnání a prohození }
  455.   __Pocit.Init;
  456.  
  457.   {$ifdef intr}
  458.   __Timer.On;
  459.   {$endif}
  460.  
  461.    { Zobrazení menu }
  462.   __Menu.Otevri;
  463.  
  464.   for K := 1 to N do
  465.     begin
  466.        { inicialisace data[k]  - nutná ! }
  467.       Data[K].Init;
  468.       Data[K].Presun_Bod(Hezky_Rozmistit(K)^);
  469.        { prirazeni klice }
  470.       Data[K].Klic := {1000-k}Random(1000);
  471.            { vytvoreni tvaru tak, aby to hezky vypadalo }
  472.       Data[K].Vytvor(Data[K].Klic, 3, K mod 10 + 5, K mod 10 + 5, Strom_Ram);
  473.       Data[K].Zobraz;
  474.     end;
  475.  
  476.  
  477.   repeat
  478.   {$ifndef intr}
  479.     __Menu.Krok;
  480.   {$endif}
  481.     if __Menu.Sub_Menu^[5]^.Out_Hodnota = 1 then
  482.       begin { Pokud je vybráno Run - Start, vunuluje se poçítadlo a spustí se p⌐íslu¿nÿ SORT }
  483.         __Pocit.Nuluj;
  484.         case Metoda of
  485.           _Qsort    : Quicksort(Data);
  486.           _Qsortpar : Quicksortpar(Data);
  487.           _Buble    : Bublesort(Data);
  488.           _Vyber    : Maxsort(Data);
  489.           _Merge    : Mergesort(Data);
  490.         end;
  491.         Jit_Ven := False;
  492.           { Skonçeno t⌐ídêní, tak se nastaví Run - Stop }
  493.         __Menu.Sub_Menu^[5]^.Pom_set(2);
  494.         __Menu.Prekresli;
  495.       end;
  496.   until (__Menu.Out_Hodnota = 6);
  497.  
  498.     { vypnutí tisku obrazovky }
  499.   Off_Pisbmp;
  500.  
  501.     { Likvidace odpadkû }
  502.   __Timer.Off;
  503.   __Menu.Zrus;
  504.   __Pocit.Zrus;
  505.  
  506.   for K := 1 to N do Data[K].Zrus;
  507.    { vyruseni pameti, kterou zabiraji objekty a zhasnuti }
  508.  
  509.   Konec;    { vyruseni pameti, kterou zabirá obrazovka }
  510. end.
  511.  
  512. procedure Bublesortpar(var Data : Typdat);
  513. var I, J : Integer;
  514.     Pom  : Typ_Prvek;
  515. begin
  516.   Pom.Init;
  517.   for I := 1 to N-1 do
  518.     for J := N-1 downto I do
  519.       if Vetsi(Data[J].Klic, Data[J+1].Klic) then
  520.         begin
  521.           repeat
  522.           until (not Data[J+1].Hejbe_Se) and (not Data[J].Hejbe_Se);
  523.           Data[J+1].Anim_Prohod(Data[J]);
  524.            __Timer.Zarad_Prvek(Data[J+1]);
  525.            __Timer.Zarad_Prvek(Data[J]);
  526.            Pom     := Data[J+1];
  527.            Data[J+1] := Data[J];
  528.            Data[J] := Pom;
  529.             { prohozeni v pameti }
  530.            __Pocit.Zvets_Prohozeni;
  531.            __Pocit.Zvets_Prohozeni;
  532.            __Pocit.Zvets_Prohozeni;
  533.  
  534.           if Jit_Ven then Break;{ aby se nemuselo dlouho cekat, nemusí bÿt }
  535.         end;
  536.   __Timer.Dodelej_Pohyb_Na_Pocet(1); { ve frontê __timer zûstane pouze prvek - menu }
  537. end;
  538.  
  539.