Skip to content

Commit

Permalink
tetris2: added pause mode, fixed line elimination, showing next char,…
Browse files Browse the repository at this point in the history
… printing letter instead of # for pieces
  • Loading branch information
andreasbaumann committed Jan 5, 2025
1 parent 19109a2 commit 3f16ab7
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 56 deletions.
90 changes: 59 additions & 31 deletions third_party/tetris2/tetris2.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include <stdbool.h>
#include "lib/screen.h"

#define Delay 100
#define Delay 200
#define BoardHeight 20
#define BoardWidth 10
#define NofShapes 7
Expand Down Expand Up @@ -53,15 +53,16 @@ static uint8_t Shapes[NofShapes][4][4] = {
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 } }
};
static uint8_t ShapeChars[NofShapes] = {'I', 'O', 'T', 'J', 'L', 'S', 'Z' };

uint8_t Board[BoardHeight][BoardWidth];
bool GameOver;
uint8_t CurrentPiece;
uint8_t CurrentPiece, NextPiece;
int8_t PosX, PosY;

static void InitializeBoard(void)
{
memset(Board, 0, sizeof(uint8_t) * BoardWidth * sizeof(uint8_t) * BoardWidth);
memset(Board, 0xFF, sizeof(Board));
}

static void DrawBoard(void)
Expand All @@ -71,27 +72,27 @@ static void DrawBoard(void)
for (y = 1; y <= BoardHeight; y++) {
for (x = 1; x <= BoardWidth; x++) {
screen_setcursor(x,y);
if (Board[y-1][x-1] == 1)
screen_putchar('#');
if (Board[y-1][x-1] != 0xFF)
screen_putchar(ShapeChars[Board[y-1][x-1]]);
else
screen_putchar('.');
}
}
}


static void DrawPiece(bool Erase)
static void DrawPiece(uint8_t piece, int8_t x, int8_t y,bool Erase)
{
uint8_t x, y;
uint8_t nx, ny;

for (y = 0; y <= 3; y++) {
for (x = 0; x <= 3; x++) {
if (Shapes[CurrentPiece][y][x] == 1) {
screen_setcursor(PosX + x, PosY + y);
for (ny = 0; ny <= 3; ny++) {
for (nx = 0; nx <= 3; nx++) {
if (Shapes[piece][ny][nx] == 1) {
screen_setcursor(x + nx, y + ny);
if (Erase)
screen_putchar('.');
else
screen_putchar('#');
screen_putchar(ShapeChars[piece]);
}
}
}
Expand All @@ -106,17 +107,32 @@ static bool CanMove(int8_t dx, int8_t dy)
if (Shapes[CurrentPiece][y][x] == 1) {
if (PosX + x + dx < 1 || PosX + x + dx > BoardWidth ||
PosY + y + dy > BoardHeight ||
Board[PosY + y + dy - 1][PosX + x + dx - 1] == 1)
Board[PosY + y + dy - 1][PosX + x + dx - 1] != 0xFF)
return false;
}
}
}
return true;
}

static void DrawNextPiece(void)
{
int8_t x, y;

for (y = 10; y <= 13; y++) {
for (x = 12; x <= 15; x++) {
screen_setcursor(x, y);
screen_putchar('.');
}
}
DrawPiece(NextPiece, 12, 10, false);
}

static void NewPiece(void)
{
CurrentPiece = (uint8_t)rand() % NofShapes;
CurrentPiece = NextPiece;
NextPiece = (uint8_t)rand() % NofShapes;
DrawNextPiece();
PosX = BoardWidth / 2 - 2;
PosY = 1;
if (!CanMove(0, 0))
Expand Down Expand Up @@ -151,7 +167,7 @@ static void PlacePiece(void)
for (y = 0; y <= 3; y++) {
for (x = 0; x <= 3; x++) {
if (Shapes[CurrentPiece][y][x] == 1)
Board[PosY + y - 1][PosX + x - 1] = 1;
Board[PosY + y - 1][PosX + x - 1] = CurrentPiece;
}
}
}
Expand All @@ -162,10 +178,10 @@ static bool ClearLines(void)
bool Full;
bool Redraw = false;

for (y = BoardHeight; y >= 1; y--) {
for (y = 1; y <= BoardHeight; y++) {
Full = true;
for (x = 0; x < BoardWidth; x++) {
if (Board[y-1][x] == 0)
if (Board[y-1][x] == 0xFF)
Full = false;
}
if (Full) {
Expand All @@ -174,7 +190,7 @@ static bool ClearLines(void)
Board[ny-1][x] = Board[ny-2][x];
}
for (x = 0; x < BoardWidth; x++)
Board[0][x] = 0;
Board[0][x] = 0xFF;
Redraw = true;
}
}
Expand All @@ -190,40 +206,51 @@ static void HandleInput(void)
switch (c) {
case 'A': case 'a':
if (CanMove(-1, 0)) {
DrawPiece(true);
DrawPiece(CurrentPiece, PosX, PosY, true);
PosX--;
DrawPiece(false);
DrawPiece(CurrentPiece, PosX, PosY, false);
}
break;

case 'D': case 'd':
if (CanMove(1, 0)) {
DrawPiece(true);
DrawPiece(CurrentPiece, PosX, PosY, true);
PosX++;
DrawPiece(false);
DrawPiece(CurrentPiece, PosX, PosY, false);
}
break;

case 'S': case 's':
if (CanMove(0, 1)) {
DrawPiece(true);
DrawPiece(CurrentPiece, PosX, PosY, true);
PosY++;
DrawPiece(false);
DrawPiece(CurrentPiece, PosX, PosY, false);
}
break;

case ' ':
while (CanMove(0, 1)) {
DrawPiece(true);
DrawPiece(CurrentPiece, PosX, PosY, true);
PosY++;
DrawPiece(false);
DrawPiece(CurrentPiece, PosX, PosY, false);
}
break;

case 'W': case 'w':
DrawPiece(true);
DrawPiece(CurrentPiece, PosX, PosY, true);
RotatePiece();
DrawPiece(false);
DrawPiece(CurrentPiece, PosX, PosY, false);
break;

case 'P': case 'p':
screen_setcursor(12,7);
cpm_printstring("Game paused.");
screen_setcursor(12,8);
cpm_printstring("Press any key to continue.");
screen_waitchar();
screen_clear();
DrawBoard();
DrawNextPiece();
break;

case 'Q': case 'q':
Expand All @@ -246,14 +273,15 @@ int main(void)
InitializeBoard();
DrawBoard();
GameOver = false;
NextPiece = (uint8_t)rand() % NofShapes;
NewPiece();
while (!GameOver) {
DrawPiece(false);
DrawPiece(CurrentPiece, PosX, PosY, false);
HandleInput();
if (CanMove(0, 1)) {
DrawPiece(true);
DrawPiece(CurrentPiece, PosX, PosY, true);
PosY++;
DrawPiece(false);
DrawPiece(CurrentPiece, PosX, PosY, false);
} else {
PlacePiece();
while (ClearLines()) {
Expand Down
81 changes: 56 additions & 25 deletions third_party/tetris2/tetris2.pas
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
((0,0,1,0),(1,1,1,0),(0,0,0,0),(0,0,0,0)), (* L *)
((0,1,1,0),(1,1,0,0),(0,0,0,0),(0,0,0,0)), (* S *)
((1,1,0,0),(0,1,1,0),(0,0,0,0),(0,0,0,0))); (* Z *)
ShapeChars : ARRAY[0..7] OF Char =
(' ','I','O','T','J','L','S','Z');

VAR
Board : ARRAY[1..BoardHeight,1..BoardWidth] OF Byte;
GameOver : Boolean;
CurrentPiece : Integer;
CurrentPiece, NextPiece : Integer;
PosX, PosY : Integer;

PROCEDURE InitializeBoard;
Expand All @@ -37,27 +39,27 @@
FOR x := 1 TO BoardWidth DO
BEGIN
GotoXY(x,y);
IF Board[y,x] = 1 THEN
Write('#')
IF Board[y,x] >= 1 THEN
Write(ShapeChars[Board[y,x]])
ELSE
Write('.')
END
END
END;

PROCEDURE DrawPiece(Erase : Boolean);
PROCEDURE DrawPiece(Piece : Integer; x, y : Integer; Erase : Boolean);
VAR
x, y : Integer;
nx, ny : Integer;
BEGIN
FOR y := 0 TO 3 DO
FOR x := 0 TO 3 DO
IF Shapes[CurrentPiece,y,x] = 1 THEN
FOR ny := 0 TO 3 DO
FOR nx := 0 TO 3 DO
IF Shapes[Piece,ny,nx] = 1 THEN
BEGIN
GotoXY(PosX+x,PosY+y);
GotoXY(nx+x,ny+y);
IF Erase THEN
Write('.')
ELSE
Write('#')
Write(ShapeChars[Piece])
END
END;

Expand Down Expand Up @@ -89,9 +91,24 @@
END
END;

PROCEDURE DrawNextPiece;
VAR
x, y : Integer;
BEGIN
FOR y := 10 TO 13 DO
FOR x := 12 TO 15 DO
BEGIN
GotoXY(x,y);
Write('.')
END;
DrawPiece(NextPiece,12,10,False);
END;

PROCEDURE NewPiece;
BEGIN
CurrentPiece := 1+Random(NofShapes);
CurrentPiece := NextPiece;
NextPiece := 1+Random(NofShapes);
DrawNextPiece;
PosX := (BoardWidth div 2)-2;
PosY := 1;
IF NOT CanMove(0,0) THEN
Expand Down Expand Up @@ -134,7 +151,7 @@
Full : Boolean;
BEGIN
ClearLines := False;
FOR y := BoardHeight DOWNTO 1 DO
FOR y := 1 TO BoardHeight DO
BEGIN
Full := True;
FOR x := 1 TO BoardWidth DO
Expand Down Expand Up @@ -169,36 +186,48 @@
'A','a',#8:
IF CanMove(-1,0) THEN
BEGIN
DrawPiece(True);
DrawPiece(CurrentPiece,PosX,PosY,True);
PosX := PosX-1;
DrawPiece(False)
DrawPiece(CurrentPiece,PosX,PosY,False)
END;
'D','d',#9:
IF CanMove(1,0) THEN
BEGIN
DrawPiece(True);
DrawPiece(CurrentPiece,PosX,PosY,True);
PosX := PosX+1;
DrawPiece(False)
DrawPiece(CurrentPiece,PosX,PosY,False)
END;
'S','s',#10:
IF CanMove(0,1) THEN
BEGIN
DrawPiece(True);
DrawPiece(CurrentPiece,PosX,PosY,True);
PosY := PosY+1;
DrawPiece(False)
DrawPiece(CurrentPiece,PosX,PosY,False)
END;
' ':
WHILE CanMove(0,1) DO
BEGIN
DrawPiece(True);
DrawPiece(CurrentPiece,PosX,PosY,True);
PosY := PosY+1;
DrawPiece(False)
DrawPiece(CurrentPiece,PosX,PosY,False)
END;
'W','w',#11:
BEGIN
DrawPiece(True);
DrawPiece(CurrentPiece,PosX,PosY,True);
RotatePiece;
DrawPiece(False)
DrawPiece(CurrentPiece,PosX,PosY,False)
END;
'P','p':
BEGIN
GotoXY(12,7);
Write('Game paused.');
GotoXY(12,8);
Write('Press any key to continue.');
WHILE NOT KeyPressed DO
Delay(10);
ClrScr;
DrawBoard;
DrawNextPiece
END;
'Q','q':
GameOver := True;
Expand All @@ -216,16 +245,17 @@
ClrScr;
DrawBoard;
GameOver := False;
NextPiece := 1+Random(NofShapes);
NewPiece;
WHILE NOT GameOver DO
BEGIN
DrawPiece(False);
DrawPiece(CurrentPiece,PosX,PosY,False);
HandleInput;
IF CanMove(0,1) THEN
BEGIN
DrawPiece(True);
DrawPiece(CurrentPiece,PosX,PosY,True);
PosY := PosY+1;
DrawPiece(False)
DrawPiece(CurrentPiece,PosX,PosY,False)
END
ELSE
BEGIN
Expand All @@ -237,5 +267,6 @@
END;
ClrScr;
WriteLn('Thanks for playing.');
Delay(2000);
CrtExit;
END.

0 comments on commit 3f16ab7

Please sign in to comment.