Imprimir

Tetris

// By cyrille de Brébisson HP_prime developer
//Optimisation and improvments by Mickaël Nicotera
//and Tom Lake
DoesNotFit(game, piece, p) // return true if piece does not fit
begin
  local j;
  if game(im(p), re(p)) then return 1; end;
  for j:=1 to size(piece) do
    p:= p+piece(j);
    if game(im(p), re(p)) then return 1; end;
  end;
  return 0;
end;

EXPORT Tetris()
BEGIN
  local game= makemat(J=1 or J=12 or I=1 or I=25,25,12), pause=0.200, score= 0;
  local shapes= {{(1, 0), (0, 1), (-1, 0)},
                          {(1, 0), (0, 1), (1, 0)},
                          {(-1, 0), (0, 1), (-1, 0)},
                          {(1, 0), (1, 0), (0, 1)},
                          {(-1, 0), (-1, 0), (0, 1)},
                          {(1, 0), (1, 0), (-1, 1)},
                          {(1, 0), (1, 0), (1, 0)}}; // Bar



  while 1 do
    local piece=shapes(randint(6)+1), p=(5,2), i, j; // get a random piece



    if DoesNotFit(game, piece, p) then return score; end; // test if we lose



    // create background
    dimgrob_p(G1, 320, 240);
    dimgrob_p(G2, 320, 240);
    line_p(G1,99, 0, 99, 232, #FF); line_p(G1, 99, 232, 202, 232, #FF); line_p(G1,202, 232, 202, 0, #FF);
    for i:=1 to 23 do
      for j:=1 to 10 do
        if game(i+1,j+1) then rect_p(G1, j*10+91, i*10-9, j*10+100, i*10, #0); end;
      end;
    end;



    while NOT DoesNotFit(game, piece, p) do
      // Draw the background on back buffer
      blit_p(G2, G1);
      // display score
TEXTOUT_P("Score = "+score,G2,250,7,1,#007CFFh);
      // draw the piece
      i:=p;
      rect_p(G2, i*10-(-81,19), i*10-(-90,10), #FF006Eh);
      for j:=1 to size(piece) do
        i:= i+piece(j);
        rect_p(G2, i*10-(-81,19), i*10-(-90,10), #FF006Eh);
      end;
      // draw backbuffer on screen
      blit_p(G2);
      // pause
I:=0;


WHILE I<2 DO
      wait(0.1);
      // keys?
      if iskeydown(4) then RETURN("Tetris for HP Prime"); end;
      if IsKeyDown(7) then if NOT DoesNotFit(game, piece, p-1) then p:= p-1; end; end;
      if IsKeyDown(8) then if NOT DoesNotFit(game, piece, p+1) then p:= p+1; end; end;
      if IsKeyDown(2) then
        local rotate= piece*(0, -1);
        if NOT DoesNotFit(game, rotate, p) then piece:= rotate; end;
      else
        if IsKeyDown(12) then
          local rotate= piece*(0, 1);
          if NOT DoesNotFit(game, rotate, p) then piece:= rotate; end;
        end;
      end;
I:=I+1;
END;




      // try to go down...
      if DoesNotFit(game, piece, p+(0,1)) then break; else p:= p+(0,1); end;
    end;
    // put piece in game!
    game(im(p), re(p)):= 1;
    for j:=1 to size(piece) do
      p:= p+piece(j);
      game(im(p), re(p)):=1;
    end;
    // remove lines?
    for i:=24 downto 2 do
      if game(i)=[1,1,1,1,1,1,1,1,1,1,1,1] then
        for j:=i-1 downto 2 do game(j+1):= game(j); end;
        game(2):= [1,0,0,0,0,0,0,0,0,0,0,1];
        score:= score+1;
        i:= i+1;
      end;
    end;
    // faster!
    pause:=pause-0.007;
  end;
END;