Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // autor: Tomasz Kacperek <tk334578@students.mimuw.edu.pl>
- program ris;
- const wiersze = 20;
- kolumny = 10;
- type klocek = Array[1..4,1..4] of Boolean;
- plan = Array[1..wiersze,1..kolumny] of Boolean; // plansza
- przedsion = Array[1..4,1..kolumny] of Boolean; // przedsionek
- ostKlo = Array[1..2] of Integer; // ostatniKlocek
- var plansza: plan;
- polecenie : String;
- koniec: Boolean = false;
- liczbaKlockow, kolumna: Integer; // numer kolumny z lewą krawędzią ostatnio dodanego klocka
- maxKlocek: Integer = 20; // najwyższy klocek
- przedsionek: przedsion;
- ostatniKlocek: ostKlo; // (Y-owa współrzędna górnego końca,Y-owa współrzędna dolnego końca)
- klocekI: klocek = ((true,false,false,false),(true,false,false,false),(true,false,false,false),(true,false,false,false));
- klocekJ: klocek = ((false,false,false,false),(false,true,false,false),(false,true,false,false),(true,true,false,false));
- klocekL: klocek = ((false,false,false,false),(true,false,false,false),(true,false,false,false),(true,true,false,false));
- klocekO: klocek = ((false,false,false,false),(false,false,false,false),(true,true,false,false),(true,true,false,false));
- klocekS: klocek = ((false,false,false,false),(false,false,false,false),(false,true,true,false),(true,true,false,false));
- klocekT: klocek = ((false,false,false,false),(false,false,false,false),(true,true,true,false),(false,true,false,false));
- klocekZ: klocek = ((false,false,false,false),(false,false,false,false),(true,true,false,false),(false,true,true,false));
- // zeruje licznik klocków, planszę i przedsionek
- procedure start(var p: plan; var lK:Integer; var przed:przedsion);
- var i,j:Integer;
- begin
- lK:=0;
- for i:=1 to wiersze do
- for j:=1 to kolumny do
- p[i,j]:=false;
- for i:=1 to 4 do
- for j:=1 to kolumny do
- przed[i,j]:=false;
- end;
- // wypisuje zawartość planszy
- procedure rysuj(const p:plan; const lK:Integer);
- var i,j:Integer;
- begin
- for i:=1 to wiersze do
- begin
- for j:=1 to kolumny do
- if p[i,j]=true then
- write('[]')
- else write(' ');
- writeln('|');
- end;
- writeln('0 1 2 3 4 5 6 7 8 9 | ',lK);
- end;
- // obraca podany klocek zgodnie z ruchem wskazówek zegara
- procedure obrotKlocka(var kl:klocek; const obr:Char);
- var i,j,k,ileObr:Integer;
- kopia: klocek;
- begin
- // sprawdza ile obrotów
- case obr of
- 'a': ileObr:=0;
- 'b': ileObr:=1;
- 'c': ileObr:=2;
- 'd': ileObr:=3;
- end;
- // obraca
- if ileObr<>0 then
- for i:=1 to ileObr do
- begin
- kopia:=kl;
- for j:=1 to 4 do
- for k:=1 to 4 do
- kl[j,k]:=kopia[5-k,j];
- end;
- end;
- // umieszcza klocek w lewym dolnym rogu tablicy
- procedure przesun(var k:klocek);
- var i,j,skok: Integer;
- bylPierwszy: Boolean;
- begin
- // przesuwa w lewo
- bylPierwszy:=false;
- for i:=1 to 4 do
- for j:=1 to 4 do
- begin
- if (bylPierwszy=false) and (k[j,i]=true) then
- begin
- skok:=i-1;
- bylPierwszy:=true
- end;
- if (bylPierwszy=true) and (k[j,i]=true) then
- begin
- k[j,i]:=false;
- k[j,i-skok]:=true;
- end;
- end;
- // przesuwa w dół
- bylPierwszy:=false;
- for i:=4 downto 1 do
- for j:=1 to 4 do
- begin
- if (bylPierwszy=false) and (k[i,j]=true) then
- begin
- skok:=4-i;
- bylPierwszy:=true
- end;
- if (bylPierwszy=true) and (k[i,j]=true) then
- begin
- k[i,j]:=false;
- k[i+skok,j]:=true;
- end;
- end;
- end;
- // wpisuje klocek do przedsionka
- // zwraca numer kolumny z lewą krawędzią dodanego klocka
- function dodajKlocek(const parametry: String; var przed:przedsion):Integer;
- var typ,obrot: Char;
- i,j,pozycja: Integer;
- kloc: klocek;
- begin
- typ:= parametry[1];
- obrot:= parametry[2];
- val(parametry[3],pozycja);
- case typ of // wybiera typ klocka
- 'I': kloc:=klocekI;
- 'J': kloc:=klocekJ;
- 'L': kloc:=klocekL;
- 'O': kloc:=klocekO;
- 'S': kloc:=klocekS;
- 'T': kloc:=klocekT;
- 'Z': kloc:=klocekZ;
- end;
- obrotKlocka(kloc,obrot);
- przesun(kloc);
- // wstawianie do przedsionka
- for i:=1 to 4 do
- for j:=1 to 4 do
- if kloc[i,j]=true then
- przed[i,pozycja+j]:=kloc[i,j];
- dodajKlocek:=pozycja+1;
- end;
- // przenosi zawartość przedsionka w odpowiednie miejsce na planszy
- // zwraca true, jeżeli nie da się przenieść klocka
- function opuscKlocek(var przed:przedsion; var pl:plan; const kol:Integer; var lK:Integer; var oK: ostKlo; var mK:Integer):Boolean;
- var l,p,i,j,h,w,minSkok: Integer;
- skoki: Array[1..4] of Integer = (0,0,0,0);
- begin
- // ustala zakres, w którym mieści się klocek
- l:=kol;
- if l+3 < 10 then p:=l+3 else p:=10;
- //liczy h - wysokość klocka
- i:=1;
- while i<=3 do
- begin
- j:=l;
- while j <=p do
- begin
- if przed[i,j]=true then
- begin
- h:=5-i;
- i:=4;
- j:=p+1;
- end;
- inc(j);
- end;
- inc(i);
- end;
- if i=4 then h:=1;
- //liczy w - szerokość klocka
- i:=p;
- while i>=l do
- begin
- j:=1;
- while j <= 4 do
- begin
- if przed[j,i]=true then
- begin
- w:=i-l+1;
- i:=l;
- j:=4;
- end;
- inc(j);
- end;
- dec(i);
- end;
- // zawęża zakres
- p:=l+w-1;
- // zlicza puste pola pod klockiem (w przedsionku)
- for i:=l to p do
- begin
- j:=4;
- while j >= 5-h do
- begin
- if przed[j,i]=true then
- begin
- skoki[i-l+1]:=4-j;
- j:=0;
- end;
- dec(j);
- end;
- if (j=4-h) then skoki[i-l+1]:=4;
- end;
- // zlicza puste pola pod klockiem (na planszy)
- for i:=l to p do
- begin
- j:=1;
- while j <= 20 do
- begin
- if pl[j,i]=true then
- begin
- inc(skoki[i-l+1],j-1);
- j:=21;
- end;
- inc(j);
- end;
- if (j<>22) then inc(skoki[i-l+1],20);
- end;
- // wyznacza minimalny skok (przesunięcie)
- minSkok:=24;
- for i:=1 to p-l+1 do if skoki[i] < minSkok then minSkok:=skoki[i];
- // "opuszcza" klocek z przedsionka na planszę
- if minSkok >= h then
- begin
- for i:=minSkok downto minSkok-h+1 do
- for j:=l to p do
- if przed[i-minSkok+4,j]=true then
- begin
- pl[i,j]:=przed[i-minSkok+4,j];
- przed[i-minSkok+4,j]:=false;
- end;
- inc(lK);
- opuscKlocek:=false;
- oK[1]:=minSkok-h+1;
- oK[2]:=minSkok;
- if oK[1]<mK then mK:=oK[1];
- end
- else opuscKlocek:=true;
- end;
- // usuwa zapełnione wiersze
- procedure usunWiersze(var pl:plan; var oK: ostKlo; var mK:Integer);
- var i,j,przesuniecie: Integer;
- wszystkiePelne: Boolean;
- doUsuniecia: Array[1..4] of Boolean = (false,false,false,false);
- begin
- // zapisuje w tablicy doUsuniecia, które wiersze z przedziału
- // zadanego przez oK należy usunąć
- for i:=oK[1] to oK[2] do
- begin
- wszystkiePelne:=true;
- j:=1;
- while (j <= kolumny) and (wszystkiePelne=true) do
- begin
- wszystkiePelne:=pl[i,j];
- inc(j);
- end;
- if wszystkiePelne=true then doUsuniecia[i-oK[1]+1]:=true;
- end;
- // przesuwa pojedyncze wiersze i oblicza główne przesunięcie
- // (wszystkich niepustych wierszy znajdujących się ponad badanymi)
- przesuniecie:=0;
- for i:=oK[2] downto oK[1] do
- if doUsuniecia[i-oK[1]+1]=true then inc(przesuniecie)
- else if przesuniecie <> 0 then
- for j:=1 to kolumny do pl[i+przesuniecie,j]:=pl[i,j];
- // dokonuje głównego przesunięcia
- if przesuniecie <> 0 then
- begin
- for i:=oK[1]-1 downto mK do
- for j:=1 to kolumny do
- begin
- pl[i+przesuniecie,j]:=pl[i,j];
- pl[i,j]:=false;
- end;
- if oK[1]-mK < przesuniecie then
- for i:=oK[1] to przesuniecie+mK-1 do
- for j:=1 to kolumny do
- pl[i,j]:=false;
- end;
- end;
- // główny program
- begin
- start(plansza,liczbaKlockow,przedsionek);
- while (not eof) and (koniec=false) do
- if eoln then begin
- readln;
- rysuj(plansza,liczbaKlockow);
- end else begin
- readln(polecenie);
- if polecenie[1] = '>' then // wypisuje podany ciąg znaków
- writeln(copy(polecenie, 2, length(polecenie) - 1))
- else begin
- kolumna:= dodajKlocek(polecenie,przedsionek);
- koniec:= opuscKlocek(przedsionek,plansza, kolumna, liczbaKlockow, ostatniKlocek, maxKlocek);
- if koniec=true then writeln('Gra zakonczyla sie wynikiem ',liczbaKlockow,'.')
- else usunWiersze(plansza,ostatniKlocek,maxKlocek);
- end;
- end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement