#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#define TTY_PATH "/dev/tty"
#define STTY_US "stty raw -echo -F "
#define STTY_DEF "stty -raw echo -F "
struct Point
{
int x;
int y;
};
struct Shap
{
struct Point points[4];
};
struct Shap shaps[19] = {
{{{0,0},{-1,0},{1,0},{2,0}}},
{{{0,0},{0,-1},{0,1},{0,2}}},
{{{0,0},{-1,-1},{-1,0},{0,-1}}},
{{{0,0},{0,-1},{0,-2},{1,0}}},
{{{0,0},{0,1},{1,0},{2,0}}},
{{{0,0},{-1,0},{0,1},{0,2}}},
{{{0,0},{0,-1},{-1,0},{-2,0}}},
{{{0,0},{-1,0},{0,-1},{0,-2}}},
{{{0,0},{0,-1},{1,0},{2,0}}},
{{{0,0},{1,0},{0,1},{0,2}}},
{{{0,0},{-1,0},{-2,0},{0,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}}},
{{{0,0},{1,0},{0,-1},{-1,-1}}},
{{{0,0},{1,-1},{0,1},{1,0}}},
{{{0,0},{1,-1},{-1,0},{0,-1}}},
{{{0,0},{-1,-1},{-1,0},{0,1}}}
};
#define WIDTH 20
#define HEIGHT 30
#define CHANGE 'w'
#define RIGHT 'd'
#define LEFT 'a'
#define DOWN 's'
#define CTRL_C 3
struct Point position = {WIDTH/2, 2};
struct Shap nowShap;
int nowShapIndex;
int staticShapes[HEIGHT+2][WIDTH+2] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
};
int get_char();
void drowPoint(int x, int y);
void drowStar(int x, int y);
void drawFrame();
void userCtrl();
void createShap();
void drawShap();
void moveDown();
int collide(struct Shap shap);
void addShapToStatic();
void drawStaitcShapes();
void clearLines();
int main()
{
srand(time(0));
system( STTY_US TTY_PATH );
createShap();
while(1)
{
system("clear");
drawShap();
drawStaitcShapes();
drawFrame();
userCtrl();
moveDown();
fflush(stdout);
usleep(100000);
}
return 0;
}
void createShap()
{
position.x = WIDTH/2;
position.y = 2;
nowShapIndex = 0;
nowShap = shaps[nowShapIndex];
}
int moveDownSpeed = 0;
void moveDown()
{
if(++moveDownSpeed == 5)
{
struct Shap shap = nowShap;
int i;
for(i = 0;i < 4;i++)
{
shap.points[i].x += position.x;
shap.points[i].y += position.y+1;
}
if(collide(shap)==0)
{
position.y++;
}
else
{
addShapToStatic();
clearLines();
createShap();
}
moveDownSpeed = 0;
}
}
void changeShap()
{
int index = nowShapIndex;
switch(nowShapIndex)
{
case 0:
index++;
break;
case 1:
index = 0;
break;
case 2:
break;
case 3:
case 4:
case 5:
index++;
break;
case 6:
index = 3;
break;
case 7:
case 8:
case 9:
index++;
break;
case 10:
index = 7;
break;
case 11:
case 12:
case 13:
index++;
break;
case 14:
index = 11;
break;
case 15:
index = 16;
break;
case 16:
index = 15;
break;
case 17:
index = 18;
break;
case 18:
index = 17;
break;
}
struct Shap shap = shaps[index];
int i;
for(i = 0;i < 4;i++)
{
shap.points[i].x += position.x;
shap.points[i].y += position.y;
}
if(collide(shap) == 0)
{
nowShapIndex = index;
nowShap = shaps[index];
}
}
void addShapToStatic()
{
int i;
for(i = 0;i < 4;i++)
{
int x = nowShap.points[i].x+position.x;
int y = nowShap.points[i].y+position.y;
staticShapes[y][x] = 1;
}
}
void drawStaitcShapes()
{
int i, j;
for(i = 0;i < HEIGHT+2;i++)
{
for(j = 0;j < WIDTH+2;j++)
{
if(staticShapes[i][j] == 1)
{
drowPoint(j, i);
}
}
}
}
void drawShap()
{
int i;
for(i = 0;i < 4;i++)
{
drowPoint(position.x+nowShap.points[i].x, position.y+nowShap.points[i].y);
}
}
int collide(struct Shap shap)
{
int i;
for(i = 0;i < 4;i++)
{
int x = shap.points[i].x;
int y = shap.points[i].y;
if(shap.points[i].x < 1
|| shap.points[i].x > WIDTH
|| shap.points[i].y > HEIGHT
|| staticShapes[y][x]==1
)
{
return 1;
}
}
return 0;
}
int isLineFull(int line)
{
int i;
for(i = 1;i < WIDTH+1;i++)
{
if(staticShapes[line][i] == 0)
{
return 0;
}
}
return 1;
}
void lineCpy(int line1, int line2)
{
int i;
for(i = 1;i < WIDTH+1;i++)
{
staticShapes[line1][i] = staticShapes[line2][i];
}
}
void setLine(int line)
{
int i;
for(i = 1;i < WIDTH+1;i++)
{
staticShapes[line][i] = 0;
}
}
void clearLines()
{
int mark[HEIGHT+2] = {0};
int i;
int count = 0;
for(i = HEIGHT;i > 1;i--)
{
if(isLineFull(i) == 1)
{
mark[i] = -1;
count++;
}
else
{
mark[i] = count;
}
}
for(i = HEIGHT;i > 1;i--)
{
int len = mark[i];
if(mark[i] == -1)
{
continue;
}
if(len > 0)
{
lineCpy(i+len, i);
setLine(i);
}
}
}
void drawFrame()
{
int i;
for(i = 0;i < WIDTH+2;i++)
{
drowStar(i, 0);
drowStar(i, HEIGHT+1);
}
for(i = 0;i < HEIGHT+2;i++)
{
drowStar(0, i);
drowStar(WIDTH+1, i);
}
}
void userCtrl()
{
struct Shap shap = nowShap;
int i;
switch(get_char())
{
case CHANGE:
changeShap();
break;
case DOWN:
break;
case RIGHT:
for(i = 0;i < 4;i++)
{
shap.points[i].x += position.x+1;
shap.points[i].y += position.y;
}
if(collide(shap) == 0)
{
position.x++;
}
break;
case LEFT:
for(i = 0;i < 4;i++)
{
shap.points[i].x += position.x-1;
shap.points[i].y += position.y;
}
if(collide(shap) == 0)
{
position.x--;
}
break;
case CTRL_C:
system(STTY_DEF TTY_PATH);
exit(0);
break;
}
}
void drowPoint(int x, int y)
{
printf("\033[%d;%dH", y+1, x*2+1);
printf("\033[1;36m■ \033[0m");
}
void drowStar(int x, int y)
{
printf("\033[%d;%dH", y+1, x*2+1);
printf("\033[1;36m* \033[0m");
}
int get_char()
{
fd_set rfds;
struct timeval tv;
int ch = 0;
FD_ZERO(&rfds);
FD_SET(0, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 10;
if (select(1, &rfds, NULL, NULL, &tv) > 0)
{
ch = getchar();
}
return ch;
}