Hello!
I want to make the tetris game in pascal...
here it's what i've done so far...

uses crt;
var x,y,i,c:byte;

begin x:=5;
      y:=1;
      repeat
       clrscr;
       for i:=1 to y-1 do
        writeln('|                                    |');
       if y<49 then
       begin writeln('|                a                   |');
             writeln('|                a                   |');
             writeln('|                a                   |');
             writeln('|                aaa                 |');
             for i:=y+4 to 49 do
              writeln('|                                    |');
             writeln('|____________________________________|');
             delay(100)
       end
       else
       begin writeln('|                a                   |');
             writeln('|                a                   |');
             writeln('|                a                   |');
             writeln('|________________aaa_________________|')
       end;
       y:=y+1;
     until y=50;
     readln
end.

and i want to know how to do this....
when i press a or d
to move to left(dec(x)) or to move to right(inc(x))... i tried to make repeat this until bla='a' but it doesn't work...

and there is another problem... the pieces that will hit the ground will dissapear after the first test, so i want to make them stay there and i don't know how...

can someone help me?

Recommended Answers

All 56 Replies

Maybe you need to save the pieces in some kind of data structure. I see only control variables in your program.

ok... then i'll ask something else, how can i generate shapes in pascal? (like a circle, table, something like that...)

i'm working in pascal. Now, my idea is to create a background that is meant to be the cage of the game(this is not hard), but i need to know how to create the 4 shapes: square, the 4 shape, the L shape, and the I shape... and then i could memorize in matrix the shape(4*4 matrix with 0 the empty space and with 1 the solid field) then i will rotate the matrix at the command of the user... this is the first part...

So you will be using the crt unit for text output? You must have the gotoXY style text console command in your possession.

gotoXY style text console command? what is that?

something like taht but i want to fill it with colors...

Get the basic code working first then add features. Start small. Make one of the pieces, rotation for that, use Crt's key input to get it working, add other pieces, add collision logic, full line logic, slide in the end logic (the block must not stick immediately to enable sliding at last moment).... Just use properly functions with parameters so you can generalize them to use with every kind of piece.

and don't call it Tetris. The trademark owners are known to go after anyone using the name, no matter how little.

thanks for the advice!

now...
1. to make the objects i used chr(219) and i thought it was a square, but it's not:(... when im tring to rotate this L to |- they are not equal, and it'll be a problem when i'll connect the pieces...
2. i lied when i said it's easy to make a background...i don't know how to make a background that takes only 1/3 of the view, so that can be the "cage" of the objects
3. i used clrscr at each move of the piece(rotate, fall) and it'll not be ok when i'll have the other pieces in the cage.... how can i avoid this and in the same time to look ok?

uses crt;
var i:word;
    x,y:byte;
    c:char;

procedure showtime(j,a,b:word);
begin clrscr;
      if j=0 then
      begin gotoxy(a,b); write(chr(219));
            gotoxy(a,b+1); write(chr(219));
            gotoxy(a,b+2); write(chr(219));
            gotoxy(a,b+3); write(chr(219),chr(219))
      end
      else if j=2 then
           begin gotoxy(a,b); write(chr(219),chr(219));
                 gotoxy(a,b+1); write(' ',chr(219));
                 gotoxy(a,b+2); write(' ',chr(219));
                 gotoxy(a,b+3); write(' ',chr(219))
           end
           else if j=1 then
                begin gotoxy(a,b); write(chr(219),chr(219),chr(219));
                      gotoxy(a,b+1); write(chr(219))
                end
                else
                begin gotoxy(a,b); write('  ',chr(219));
                      gotoxy(a,b+1); write(chr(219),chr(219),chr(219))
                end
end;

begin clrscr;
      x:=5;
      y:=0;
      textcolor(red);
      gotoxy(x,y+1); write(chr(219));
      gotoxy(x,y+2); write(chr(219));
      gotoxy(x,y+3); write(chr(219));
      gotoxy(x,y+4); write(chr(219),chr(219));
      i:=0;
      repeat
       y:=y+1;
       delay(150);
       if keypressed then
       begin c:=readkey;
             if c=#0 then
             begin c:=readkey;
                   if c=#72 then
                   begin showtime(i,x,y);
                         i:=i+1
                   end
                   else if c=#77 then
                        begin if x<=25 then
                              begin x:=x+1;
                                    showtime(i-1,x,y)
                              end;
                        end
                        else
                        begin if c=#75 then
                               if x>1 then
                               begin x:=x-1;
                                     showtime(i-1,x,y)
                               end;
                        end;
             end;
             if i=4 then i:=0;
       end;
       showtime(i,x,y)
      until (c='q') or (y=40);
      readln
end.

4. when i let the right or left arrow pressed it doesnt move in right or left continuously, it makes a move in the right or left and then it goes down... how can i change it?

This is what I came up with in my Lazarus Pascal environment:

program TsertitGame;

{$mode objfpc}{$H+}

uses {$IFDEF UNIX} {$IFDEF UseCThreads}
  cthreads, {$ENDIF} {$ENDIF}
  Classes,
  SysUtils,
  CustApp,
  { you can add units after this }
  Crt;

type

  { TSertit }

  TSertit = class(TCustomApplication)
  protected
    procedure DoRun; override;
  public
    constructor Create(TheOwner: TComponent); override;
    destructor Destroy; override;
  end;

  { TSertit }

  procedure TSertit.DoRun;
  var
    i: word;
    x, y: byte;
    c: char;

    procedure showtime(j, a, b: word);
    begin
      case j of
        0:
        begin
          gotoxy(a, b);     Write('*');
          gotoxy(a, b + 1); Write('*');
          gotoxy(a, b + 2); Write('**');
        end;
        1:
        begin
          gotoxy(a, b);      Write('***');
          gotoxy(a, b + 1);  Write('*');
        end;
        2:
        begin
          gotoxy(a, b);         Write('**');
          gotoxy(a + 1, b + 1); Write('*');
          gotoxy(a + 1, b + 2); Write('*');
        end;
        3:
        begin
          gotoxy(a, b);         Write('***');
          gotoxy(a + 2, b - 1); Write('*');
        end;
      end;
    end;

    procedure undraw(j, a, b: word);
    begin
      case j of
        0:
        begin
          gotoxy(a, b);     Write(' ');
          gotoxy(a, b + 1); Write(' ');
          gotoxy(a, b + 2); Write('  ');
        end;
        1:
        begin
          gotoxy(a, b);      Write('   ');
          gotoxy(a, b + 1);  Write(' ');
        end;
        2:
        begin
          gotoxy(a, b);         Write('  ');
          gotoxy(a + 1, b + 1); Write(' ');
          gotoxy(a + 1, b + 2); Write(' ');
        end;
        3:
        begin
          gotoxy(a, b);         Write('   ');
          gotoxy(a + 2, b - 1); Write(' ');
        end;
      end;
    end;

  begin
    clrscr;
    x := 10;
    y := 1;
    textcolor(white);
    cursoroff;
    i := 0;
    repeat
      showtime(i, x, y);
      delay(250);
      undraw(i, x, y);
      y := y + 1;
      if keypressed then
      begin
        c := readkey;
        if c = #0 then
        begin
          c := readkey;
          if c = #72 then
          begin
            i := (i + 1) mod 4;
          end
          else if c = #77 then
          begin
            if x <= 25 then
            begin
              x := x + 1;
            end;
          end
          else
          begin
            if c = #75 then
              if x > 1 then
              begin
                x := x - 1;
              end;
          end;
        end;
      end;
    until (c = 'q') or (y >= WindMaxY - 4);
    showtime(i, x, y);
    readln;
    Terminate;
  end;

  constructor TSertit.Create(TheOwner: TComponent);
  begin
    inherited Create(TheOwner);
    StopOnException := True;
  end;

  destructor TSertit.Destroy;
  begin
    inherited Destroy;
  end;

var
  Application: TSertit;

{$R *.res}

begin
  Application := TSertit.Create(nil);
  Application.Title := 'Sertit';
  Application.Run;
  Application.Free;
end.

how can i translate it in turbo pascal?

Just replace your code with code in 28 until 132. Lazarus (Free Pascal) is quite Delphi compatible. Had to use * because > 128 letters do not come out correctly as half graphics.

the cursoroff doesn't work, it says "Unknown identifier". I wrote uses crt; at the top of the program....
and windmaxy and terminate the same thing

cursoroff -> define as gotoXY(0,0) or remove.
windmaxy -> constant as before or user input
terminate (not Turbo Pascal stuff, remove)

i tried to use gotoxy(0,0) instead of cursoroff but it doesn't work, and it still has that thing, when you let one arrow pressed it goes down and makes only 1 move, and if you let pressed the left arrow for example it wont be good... you could say that it has "lag"


i wrote while keypressed do... instead of if keypressed do, but it still has some "lag"

To get any benefit from gotoXY(0,0) it naturally must be inside loop or most naturally at end of showtime. Then you would be able to for example write any value for debugging there.

I got my eyes twisted by those if's and replaced them with case used inc and dec functions. Without cursoroff, instead homing cursor to 1,1.

procedure TSertit.DoRun;
  const proportion = 4;
  var
    counter, i: word;
    x, y: byte;
    c: char;

    procedure showtime(j, a, b: word);
    begin
      case j of
        0:
        begin
          gotoxy(a, b);     Write('*');
          gotoxy(a, b + 1); Write('*');
          gotoxy(a, b + 2); Write('**');
        end;
        1:
        begin
          inc(b);
          gotoxy(a, b);     Write('***');
          gotoxy(a, b + 1); Write('*');
        end;
        2:
        begin
          gotoxy(a, b);         Write('**');
          gotoxy(a + 1, b + 1); Write('*');
          gotoxy(a + 1, b + 2); Write('*');
        end;
        3:
        begin
          b := b + 2;
          gotoxy(a, b);          Write('***');
          gotoxy(a + 2, b - 1);  Write('*');
        end;
      end;
      gotoxy(1, 1);
    end;

    procedure undraw(j, a, b: word);
    begin
      case j of
        0:
        begin
          gotoxy(a, b);       Write(' ');
          gotoxy(a, b + 1);   Write(' ');
          gotoxy(a, b + 2);   Write('  ');
        end;
        1:
        begin
          inc(b);
          gotoxy(a, b);      Write('   ');
          gotoxy(a, b + 1);  Write(' ');
        end;
        2:
        begin
          gotoxy(a, b);          Write('  ');
          gotoxy(a + 1, b + 1);  Write(' ');
          gotoxy(a + 1, b + 2);  Write(' ');
        end;
        3:
        begin
          b := b + 2;
          gotoxy(a, b);          Write('   ');
          gotoxy(a + 2, b - 1);  Write(' ');
        end;
      end;
    end;

  begin
    TextBackground(brown); clrscr;
    window(5, 5, 5 + 25 + 3, 5 + 30);
    textcolor(red); TextBackground(white);
    clrscr;
    counter := 0;
    i := 0; x := 10; y := 1;
    showtime(i, x, y);

    repeat
      inc(counter);
      delay(40);
      while keypressed do
        begin
          undraw(i, x, y);
          c := readkey;
          if c = #0 then
          begin
            c := readkey;
            case c of
            #72:  i := (i + 1) mod 4;
            #77: if x <= 25 then inc(x);
            #75: if x > 1 then dec(x);
            end;
          end;
          showtime(i, x, y);
          write(i);
        end;
      if counter mod proportion = 0 then
         begin
           undraw(i, x, y);
           inc(y);
           showtime(i, x, y);
         end;
    until (c = 'q') or (y > 30 - 2);
    gotoXY(1,1);
    write('Done');
    readln;
    Terminate;
  end;

it looks good, when the object is near the right wall it doesn't touch it... but in the right or bottom wall it's all ok....

and... can you explain to me what are these numbers in the window(....)?

sorry for double posting, but... i want to know if there is any other way i can make a window, without the command window() or using graph?

Why not window? Of course you can add wrapper for gotoxy by yourself and do clear screen by spaces.

i was just wandering... i'm not goint to change my source now, that im so close... but for the future... i want to know because i can't write outside of it...

You must reset the position/dimensions of the window, if you want to write outside it's borders.

is there any way i can have more than one window?

Only by saving the old values and restoring those after temporary setting those default. Do Procedure to set window correct size and call correct one for the code, like:

UseMainWindow;
{code}
UseScoreWindow;
{code}

i have a little problem.... whenever i have a char in the down-right corner the whole image moves up ....
here's an example

uses crt;

begin TextBackground(7); clrscr;
      window(5,5,4+12+4,5+30);
      TextBackground(16);
      clrscr;
      gotoxy(16,30); write('a');
      readln
end.

i tried gotoxy(16,31) and is the same thing... i think that whenever the coursor is there and it wrote something he moves.. but he cant because of the window so he lift up all that was writen... so how can i fix this? because it doesn't look good...

I did clearscreen with one smaller window and extended the window one line to prevent the scroll by wraparound.

it worked:D! but now i have another problem... is about deleting the full line and then move the hole system down with one pixel...

for x1:=0 to 31 do
begin line:=true;
      y1:=1;
      while line and (y1<=16) do                     
      begin if cage[x1,y1]=0 then line:=false;
      	     y1:=y1+1
      end; 
      if line then
      begin for i:=1 to 16 do
            begin gotoxy(i,x1); write(' ');          
                  {cage[x1,i]:=0;}
            end;
            delay(50);
            i:=0;                                    
            gmax:=false;
            while (i<=30) and not(gmax) do
            begin j:=1;
                  while (j<=16) and not(gmax) do
                  begin if cage[i,j]=1 then
                        begin max:=i;
                              gmax:=true
                        end;
                        j:=j+1
                  end;
                  i:=i+1;
            end;
            if gmax then                      
            begin for i:=x1 downto 1 do
                  begin for j:=1 to 16 do
                        cage[i,j]:=cage[i-1,j]
                  end;
                  for x2:=0 to 31 do                  
                   for y2:=1 to 16 do
                   begin if cage[x2,y2]=1 then
                         begin gotoxy(y2,x2);
                               write('Û');
                         end
                         else
                         begin if (x2<31) and (y2<2) and (cage[x2,y2]=0) then
                               begin gotoxy(y2,x2);
                                     write(' ');
                               end;
                         end;
                   end;
	    end;          
end;

this is the code... so the problem is... when the full line is deleted, the system comes down, and in the left-down corner it will be an empty space... i tried to modify the window but it didn't work....

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.