테트리스 C 소스

#include <Turboc.h>

#define LEFT 75
#define RIGHT 77
#define UP 72
#define DOWN 80
#define ESC 27
#define BX 5
#define BY 1
#define BW 10
#define BH 20

void DrawScreen();
void DrawBoard();
BOOL ProcessKey();
void PrintBrick(BOOL Show);
int GetAround(int x,int y,int b,int r);
BOOL MoveDown();
void TestFull();

struct Point {
     int x,y;
};
Point Shape[][4][4]={
     { {0,0,1,0,2,0,-1,0}, {0,0,0,1,0,-1,0,-2}, {0,0,1,0,2,0,-1,0}, {0,0,0,1,0,-1,0,-2} },
     { {0,0,1,0,0,1,1,1}, {0,0,1,0,0,1,1,1}, {0,0,1,0,0,1,1,1}, {0,0,1,0,0,1,1,1} },
     { {0,0,-1,0,0,-1,1,-1}, {0,0,0,1,-1,0,-1,-1}, {0,0,-1,0,0,-1,1,-1}, {0,0,0,1,-1,0,-1,-1} },
     { {0,0,-1,-1,0,-1,1,0}, {0,0,-1,0,-1,1,0,-1}, {0,0,-1,-1,0,-1,1,0}, {0,0,-1,0,-1,1,0,-1} },
     { {0,0,-1,0,1,0,-1,-1}, {0,0,0,-1,0,1,-1,1}, {0,0,-1,0,1,0,1,1}, {0,0,0,-1,0,1,1,-1} },
     { {0,0,1,0,-1,0,1,-1}, {0,0,0,1,0,-1,-1,-1}, {0,0,1,0,-1,0,-1,1}, {0,0,0,-1,0,1,1,1} },
     { {0,0,-1,0,1,0,0,1}, {0,0,0,-1,0,1,1,0}, {0,0,-1,0,1,0,0,-1}, {0,0,-1,0,0,-1,0,1} },
};

enum { EMPTY, BRICK, WALL };
char *arTile[]={". ","■","□"};
int board[BW+2][BH+2];
int nx,ny;
int brick,rot;

void main()
{
     int nFrame, nStay;
     int x,y;

     setcursortype(NOCURSOR);
     randomize();
     clrscr();
     for (x=0;x<BW+2;x++) {
          for (y=0;y<BH+2;y++) {
              board[x][y] = (y==0 || y==BH+1 || x==0 || x==BW+1) ? WALL:EMPTY;
          }
     }
     DrawScreen();
     nFrame=20;

     for (;1;) {
          brick=random(sizeof(Shape)/sizeof(Shape[0]));
          nx=BW/2;
          ny=3;
          rot=0;
          PrintBrick(TRUE);

          if (GetAround(nx,ny,brick,rot) != EMPTY) break;
          nStay=nFrame;
          for (;2;) {
              if (--nStay == 0) {
                   nStay=nFrame;
                   if (MoveDown()) break;
              }
              if (ProcessKey()) break;
              delay(1000/20);
          }
     }
     clrscr();
     gotoxy(30,12);puts("G A M E  O V E R");
     setcursortype(NORMALCURSOR);
}

void DrawScreen()
{
     int x,y;

     for (x=0;x<BW+2;x++) {
          for (y=0;y<BH+2;y++) {
              gotoxy(BX+x*2,BY+y);
              puts(arTile[board[x][y]]);
          }
     }

     gotoxy(50,3);puts("Tetris Ver 1.0");
     gotoxy(50,5);puts("좌우:이동, 위:회전, 아래:내림");
     gotoxy(50,6);puts("공백:전부 내림");
}

void DrawBoard()
{
     int x,y;

     for (x=1;x<BW+1;x++) {
          for (y=1;y<BH+1;y++) {
              gotoxy(BX+x*2,BY+y);
              puts(arTile[board[x][y]]);
          }
     }
}

BOOL ProcessKey()
{
     int ch,trot;

     if (kbhit()) {
          ch=getch();
          if (ch == 0xE0 || ch == 0) {
              ch=getch();
              switch (ch) {
              case LEFT:
                   if (GetAround(nx-1,ny,brick,rot) == EMPTY) {
                        PrintBrick(FALSE);
                        nx--;
                        PrintBrick(TRUE);
                   }
                   break;
              case RIGHT:
                   if (GetAround(nx+1,ny,brick,rot) == EMPTY) {
                        PrintBrick(FALSE);
                        nx++;
                        PrintBrick(TRUE);
                   }
                   break;
              case UP:
                   trot=(rot == 3 ? 0:rot+1);
                   if (GetAround(nx,ny,brick,trot) == EMPTY) {
                        PrintBrick(FALSE);
                        rot=trot;
                        PrintBrick(TRUE);
                   }
                   break;
              case DOWN:
                   if (MoveDown()) {
                        return TRUE;
                   }
                   break;
              }
          } else {
              switch (ch) {
              case ' ':
                   while(MoveDown()==FALSE) {;}
                   return TRUE;
              }
          }
     }
     return FALSE;
}

void PrintBrick(BOOL Show)
{
     int i;

     for (i=0;i<4;i++) {
          gotoxy(BX+(Shape[brick][rot][i].x+nx)*2,BY+Shape[brick][rot][i].y+ny);
          puts(arTile[Show ? BRICK:EMPTY]);
     }
}

int GetAround(int x,int y,int b,int r)
{
     int i,k=EMPTY;

     for (i=0;i<4;i++) {
          k=max(k,board[x+Shape[b][r][i].x][y+Shape[b][r][i].y]);
     }
     return k;
}

BOOL MoveDown()
{
     if (GetAround(nx,ny+1,brick,rot) != EMPTY) {
          TestFull();
          return TRUE;
     }
     PrintBrick(FALSE);
     ny++;
     PrintBrick(TRUE);
     return FALSE;
}

void TestFull()
{
     int i,x,y,ty;

     for (i=0;i<4;i++) {
          board[nx+Shape[brick][rot][i].x][ny+Shape[brick][rot][i].y]=BRICK;
     }

     for (y=1;y<BH+1;y++) {
          for (x=1;x<BW+1;x++) {
              if (board[x][y] != BRICK) break;
          }
          if (x == BW+1) {
              for (ty=y;ty>1;ty--) {
                   for (x=1;x<BW+1;x++) {
                        board[x][ty]=board[x][ty-1];
                   }
              }
              DrawBoard();
              delay(200);
          }
     }
}

댓글

이 블로그의 인기 게시물

디아2 창모드 및 명령어

vmware 최적화