Advertisement
Guest User

ris.pas

a guest
Nov 23rd, 2014
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 8.99 KB | None | 0 0
  1. // autor: Tomasz Kacperek <tk334578@students.mimuw.edu.pl>
  2. program ris;
  3.  
  4. const wiersze = 20;
  5.       kolumny = 10;
  6.  
  7. type klocek = Array[1..4,1..4] of Boolean;
  8.      plan = Array[1..wiersze,1..kolumny] of Boolean; // plansza
  9.      przedsion = Array[1..4,1..kolumny] of Boolean;  // przedsionek
  10.      ostKlo = Array[1..2] of Integer;                // ostatniKlocek
  11.  
  12. var plansza: plan;
  13.     polecenie : String;
  14.     koniec: Boolean = false;
  15.     liczbaKlockow, kolumna: Integer; // numer kolumny z lewą krawędzią ostatnio dodanego klocka
  16.     maxKlocek: Integer = 20; // najwyższy klocek
  17.     przedsionek: przedsion;
  18.     ostatniKlocek: ostKlo; // (Y-owa współrzędna górnego końca,Y-owa współrzędna dolnego końca)
  19.     klocekI: klocek = ((true,false,false,false),(true,false,false,false),(true,false,false,false),(true,false,false,false));
  20.     klocekJ: klocek = ((false,false,false,false),(false,true,false,false),(false,true,false,false),(true,true,false,false));
  21.     klocekL: klocek = ((false,false,false,false),(true,false,false,false),(true,false,false,false),(true,true,false,false));
  22.     klocekO: klocek = ((false,false,false,false),(false,false,false,false),(true,true,false,false),(true,true,false,false));
  23.     klocekS: klocek = ((false,false,false,false),(false,false,false,false),(false,true,true,false),(true,true,false,false));
  24.     klocekT: klocek = ((false,false,false,false),(false,false,false,false),(true,true,true,false),(false,true,false,false));
  25.     klocekZ: klocek = ((false,false,false,false),(false,false,false,false),(true,true,false,false),(false,true,true,false));
  26.  
  27. // zeruje licznik klocków, planszę i przedsionek
  28. procedure start(var p: plan; var lK:Integer; var przed:przedsion);
  29. var i,j:Integer;
  30. begin
  31.   lK:=0;
  32.  
  33.   for i:=1 to wiersze do
  34.     for j:=1 to kolumny do
  35.       p[i,j]:=false;
  36.  
  37.   for i:=1 to 4 do
  38.     for j:=1 to kolumny do
  39.       przed[i,j]:=false;
  40. end;
  41.  
  42. // wypisuje zawartość planszy
  43. procedure rysuj(const p:plan; const lK:Integer);
  44. var i,j:Integer;
  45. begin
  46.   for i:=1 to wiersze do
  47.     begin
  48.       for j:=1 to kolumny do
  49.         if p[i,j]=true then
  50.           write('[]')
  51.         else write('  ');
  52.       writeln('|');
  53.     end;
  54.   writeln('0 1 2 3 4 5 6 7 8 9 | ',lK);
  55. end;
  56.  
  57. // obraca podany klocek zgodnie z ruchem wskazówek zegara
  58. procedure obrotKlocka(var kl:klocek; const obr:Char);
  59. var i,j,k,ileObr:Integer;
  60.     kopia: klocek;
  61. begin
  62.   // sprawdza ile obrotów
  63.   case obr of
  64.     'a': ileObr:=0;
  65.     'b': ileObr:=1;
  66.     'c': ileObr:=2;
  67.     'd': ileObr:=3;
  68.   end;
  69.  
  70.   // obraca
  71.   if ileObr<>0 then
  72.     for i:=1 to ileObr do
  73.       begin
  74.         kopia:=kl;
  75.         for j:=1 to 4 do
  76.           for k:=1 to 4 do
  77.             kl[j,k]:=kopia[5-k,j];
  78.       end;
  79. end;
  80.  
  81. // umieszcza klocek w lewym dolnym rogu tablicy
  82. procedure przesun(var k:klocek);
  83. var i,j,skok: Integer;
  84.     bylPierwszy: Boolean;
  85. begin
  86.   // przesuwa w lewo
  87.   bylPierwszy:=false;
  88.   for i:=1 to 4 do
  89.     for j:=1 to 4 do
  90.       begin
  91.         if (bylPierwszy=false) and (k[j,i]=true) then
  92.           begin
  93.             skok:=i-1;
  94.             bylPierwszy:=true
  95.           end;
  96.         if (bylPierwszy=true) and (k[j,i]=true) then
  97.           begin
  98.             k[j,i]:=false;
  99.             k[j,i-skok]:=true;
  100.           end;
  101.       end;
  102.  
  103.   // przesuwa w dół
  104.   bylPierwszy:=false;
  105.   for i:=4 downto 1 do
  106.     for j:=1 to 4 do
  107.       begin
  108.         if (bylPierwszy=false) and (k[i,j]=true) then
  109.           begin
  110.             skok:=4-i;
  111.             bylPierwszy:=true
  112.           end;
  113.         if (bylPierwszy=true) and (k[i,j]=true) then
  114.           begin
  115.             k[i,j]:=false;
  116.             k[i+skok,j]:=true;
  117.           end;
  118.       end;
  119. end;
  120.  
  121. // wpisuje klocek do przedsionka
  122. // zwraca numer kolumny z lewą krawędzią dodanego klocka
  123. function dodajKlocek(const parametry: String; var przed:przedsion):Integer;
  124. var typ,obrot: Char;
  125.     i,j,pozycja: Integer;
  126.     kloc: klocek;
  127. begin
  128.   typ:= parametry[1];
  129.   obrot:= parametry[2];
  130.   val(parametry[3],pozycja);
  131.  
  132.   case typ of // wybiera typ klocka
  133.     'I': kloc:=klocekI;
  134.     'J': kloc:=klocekJ;
  135.     'L': kloc:=klocekL;
  136.     'O': kloc:=klocekO;
  137.     'S': kloc:=klocekS;
  138.     'T': kloc:=klocekT;
  139.     'Z': kloc:=klocekZ;
  140.   end;
  141.  
  142.   obrotKlocka(kloc,obrot);
  143.   przesun(kloc);
  144.  
  145.   // wstawianie do przedsionka
  146.   for i:=1 to 4 do
  147.     for j:=1 to 4 do
  148.       if kloc[i,j]=true then
  149.         przed[i,pozycja+j]:=kloc[i,j];
  150.  
  151.   dodajKlocek:=pozycja+1;
  152. end;
  153.  
  154. // przenosi zawartość przedsionka w odpowiednie miejsce na planszy
  155. // zwraca true, jeżeli nie da się przenieść klocka
  156. function opuscKlocek(var przed:przedsion; var pl:plan; const kol:Integer; var lK:Integer; var oK: ostKlo; var mK:Integer):Boolean;
  157. var l,p,i,j,h,w,minSkok: Integer;
  158.     skoki: Array[1..4] of Integer = (0,0,0,0);
  159. begin
  160.   // ustala zakres, w którym mieści się klocek
  161.   l:=kol;
  162.   if l+3 < 10 then p:=l+3 else p:=10;
  163.  
  164.   //liczy h - wysokość klocka
  165.   i:=1;
  166.   while i<=3 do
  167.     begin
  168.       j:=l;
  169.       while j <=p do
  170.         begin
  171.           if przed[i,j]=true then
  172.             begin
  173.               h:=5-i;
  174.               i:=4;
  175.               j:=p+1;
  176.             end;
  177.           inc(j);
  178.         end;
  179.     inc(i);
  180.     end;
  181.   if i=4 then h:=1;
  182.  
  183.   //liczy w - szerokość klocka
  184.   i:=p;
  185.   while i>=l do
  186.     begin
  187.       j:=1;
  188.       while j <= 4 do
  189.         begin
  190.           if przed[j,i]=true then
  191.             begin
  192.               w:=i-l+1;
  193.               i:=l;
  194.               j:=4;
  195.             end;
  196.           inc(j);
  197.         end;
  198.     dec(i);
  199.     end;
  200.  
  201.   // zawęża zakres
  202.   p:=l+w-1;
  203.  
  204.   // zlicza puste pola pod klockiem (w przedsionku)
  205.   for i:=l to p do
  206.     begin
  207.       j:=4;
  208.       while j >= 5-h do
  209.         begin
  210.           if przed[j,i]=true then
  211.             begin
  212.               skoki[i-l+1]:=4-j;
  213.               j:=0;
  214.             end;
  215.           dec(j);
  216.         end;
  217.       if (j=4-h) then skoki[i-l+1]:=4;
  218.     end;
  219.  
  220.   // zlicza puste pola pod klockiem (na planszy)
  221.   for i:=l to p do
  222.     begin
  223.       j:=1;
  224.       while j <= 20 do
  225.         begin
  226.           if pl[j,i]=true then
  227.             begin
  228.               inc(skoki[i-l+1],j-1);
  229.               j:=21;
  230.             end;
  231.           inc(j);
  232.         end;
  233.       if (j<>22) then inc(skoki[i-l+1],20);
  234.     end;
  235.  
  236.   // wyznacza minimalny skok (przesunięcie)
  237.   minSkok:=24;
  238.   for i:=1 to p-l+1 do if skoki[i] < minSkok then minSkok:=skoki[i];
  239.  
  240.   // "opuszcza" klocek z przedsionka na planszę
  241.   if minSkok >= h then
  242.     begin
  243.       for i:=minSkok downto minSkok-h+1 do
  244.         for j:=l to p do
  245.           if przed[i-minSkok+4,j]=true then
  246.             begin
  247.               pl[i,j]:=przed[i-minSkok+4,j];
  248.               przed[i-minSkok+4,j]:=false;
  249.             end;
  250.       inc(lK);
  251.       opuscKlocek:=false;
  252.       oK[1]:=minSkok-h+1;
  253.       oK[2]:=minSkok;
  254.       if oK[1]<mK then mK:=oK[1];
  255.     end
  256.   else opuscKlocek:=true;
  257. end;
  258.  
  259. // usuwa zapełnione wiersze
  260. procedure usunWiersze(var pl:plan; var oK: ostKlo; var mK:Integer);
  261. var i,j,przesuniecie: Integer;
  262.     wszystkiePelne: Boolean;
  263.     doUsuniecia: Array[1..4] of Boolean = (false,false,false,false);
  264. begin
  265.   // zapisuje w tablicy doUsuniecia, które wiersze z przedziału
  266.   // zadanego przez oK należy usunąć
  267.   for i:=oK[1] to oK[2] do
  268.     begin
  269.       wszystkiePelne:=true;
  270.       j:=1;
  271.       while (j <= kolumny) and (wszystkiePelne=true) do
  272.         begin
  273.             wszystkiePelne:=pl[i,j];
  274.             inc(j);
  275.         end;
  276.       if wszystkiePelne=true then doUsuniecia[i-oK[1]+1]:=true;
  277.     end;
  278.  
  279.   // przesuwa pojedyncze wiersze i oblicza główne przesunięcie
  280.   // (wszystkich niepustych wierszy znajdujących się ponad badanymi)
  281.   przesuniecie:=0;
  282.   for i:=oK[2] downto oK[1] do
  283.     if doUsuniecia[i-oK[1]+1]=true then inc(przesuniecie)
  284.     else if przesuniecie <> 0 then
  285.       for j:=1 to kolumny do pl[i+przesuniecie,j]:=pl[i,j];
  286.  
  287.   // dokonuje głównego przesunięcia
  288.   if przesuniecie <> 0 then
  289.     begin
  290.       for i:=oK[1]-1 downto mK do
  291.         for j:=1 to kolumny do
  292.           begin
  293.             pl[i+przesuniecie,j]:=pl[i,j];
  294.             pl[i,j]:=false;
  295.           end;
  296.       if oK[1]-mK < przesuniecie then
  297.         for i:=oK[1] to przesuniecie+mK-1 do
  298.           for j:=1 to kolumny do
  299.             pl[i,j]:=false;
  300.     end;
  301. end;
  302.  
  303. // główny program
  304. begin
  305.   start(plansza,liczbaKlockow,przedsionek);
  306.   while (not eof) and (koniec=false) do
  307.         if eoln then begin
  308.             readln;
  309.             rysuj(plansza,liczbaKlockow);
  310.         end else begin
  311.             readln(polecenie);
  312.             if polecenie[1] = '>' then // wypisuje podany ciąg znaków
  313.                 writeln(copy(polecenie, 2, length(polecenie) - 1))
  314.             else begin
  315.               kolumna:= dodajKlocek(polecenie,przedsionek);
  316.               koniec:= opuscKlocek(przedsionek,plansza, kolumna, liczbaKlockow, ostatniKlocek, maxKlocek);
  317.               if koniec=true then writeln('Gra zakonczyla sie wynikiem ',liczbaKlockow,'.')
  318.               else usunWiersze(plansza,ostatniKlocek,maxKlocek);
  319.             end;
  320.         end;
  321. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement