#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define WIDTH 25
#define HEIGHT 21
#define BORDER '*'
#define SQUARE '$'
#define EMPTY ' '
#define ESC 27
const int border = 2, square = 1, empty = 0;
int face[HEIGHT][WIDTH], score;
struct squ{
int squType[4][4];
}squs[7];
void initFace(int (*face)[WIDTH]);
void printFace(int (*face)[WIDTH]);
void initSquare(struct squ *sq);
int removeFull(void);
void gotoxy(int x, int y);
void drawSqu(struct squ (*sq), int x, int y);
void removeSqu(struct squ(*sq), int x, int y);
int judge(struct squ (*sq), int x, int y);
void rotateSqu(struct squ (*sq));
void help(void);
void update_info(struct squ * sq);
int main(void)
{
int x, y, t, base, next;
int ranSqu, i, j, restart;
char ch;
struct squ temp;
srand(time(NULL));
while(1)
{
restart = 1;
base = 1;
score = 0;
next = rand() % 7;
system("cls");
initFace(face);
printFace(face);
initSquare(squs);
help();
do
{
if(base)
{
x = 1;
y = (WIDTH - 2) / 2;
t = 0;
base = 0;
ranSqu = next;
next = rand() % 7;
update_info(&squs[next]);
}
if(judge(&squs[ranSqu], x, y));
drawSqu(&squs[ranSqu], x, y);
if(!t)
t = 9999;
while(--t)
{
if(kbhit())
break;
}
if(!t)
{
if(judge(&squs[ranSqu], x + 1, y))
{
removeSqu(&squs[ranSqu], x, y);
x++;
}
else
{
base = 1;
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
if(squs[ranSqu].squType[i][j])
{
face[x + i][y + j] = square;
while(removeFull());
}
}
}
}
}
else
{
ch = getch();
ch = tolower(ch);
switch(ch)
{
case 's':
if(judge(&squs[ranSqu], x + 1, y))
{
removeSqu(&squs[ranSqu], x, y);
x++;
}
break;
case 'a':
if(judge(&squs[ranSqu], x, y - 1))
{
removeSqu(&squs[ranSqu], x, y);
y--;
}
break;
case 'd':
if(judge(&squs[ranSqu], x, y + 1))
{
removeSqu(&squs[ranSqu], x, y);
y++;
}
break;
case 'p':
getch();
break;
case 'r':
restart = 0;
break;
case ' ':
if(ranSqu != 6)
{
temp = squs[ranSqu];
rotateSqu(&temp);
if(judge(&temp, x, y))
{
removeSqu(&squs[ranSqu], x, y);
squs[ranSqu] = temp;
}
}
break;
case ESC:
system("cls");
printf("Good bye!\n");
getch();
exit(0);
break;
}
}
}while(restart);
}
return 0;
}
void initFace(int (*face)[WIDTH])
{
int i, j;
for(i = 0; i < HEIGHT; i++)
{
for(j = 0; j < WIDTH; j++)
{
if(i == 0 || i == HEIGHT - 1 || j == 0 || j == WIDTH - 1)
{
face[i][j] = border;
}else{
face[i][j] = empty;
}
}
}
}
void printFace(int (*face)[WIDTH])
{
int i, j, x, y;
for(i = 0; i < HEIGHT; i++)
{
for(j = 0; j < WIDTH; j++)
{
if(face[i][j] == border)
{
printf("%c", BORDER);
}else{
printf("%c", EMPTY);
}
}
printf("\n");
}
}
void initSquare(struct squ *sq)
{
int i, j, k;
for(i = 0; i < 7; i++)
{
for(j = 0; j < 4; j++)
{
for(k = 0; k < 4; k++)
{
(sq + i)->squType[j][k] = empty;
}
}
}
for(i = 0, j = 0; j < 4; j++)
sq[i].squType[i][j] = 1;
for(i++, j = 0; j < 3; j++)
sq[i].squType[j][0] = 1;
sq[i].squType[j - 1][1] = 1;
for(i++, j = 0; j < 3; j++)
sq[i].squType[j][1] = 1;
sq[i].squType[j - 1][0] = 1;
i++;
sq[i].squType[0][1] = 1;
for(j = 0; j < 3; j++)
sq[i].squType[1][j] = 1;
for(i++, j = 0; j < 2; j++)
{
sq[i].squType[0][j] = 1;
sq[i].squType[1][j + 1] = 1;
}
for(i++, j = 0; j < 2; j++)
{
sq[i].squType[0][j + 1] = 1;
sq[i].squType[1][j] = 1;
}
for(i++, j = 0; j < 2; j++)
{
sq[i].squType[0][j] = 1;
sq[i].squType[1][j] = 1;
}
}
void rotateSqu(struct squ(*sq))
{
int i, j, temp[4][4];
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
temp[i][j] = sq->squType[i][j];
}
}
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
sq->squType[i][j] = temp[3 - j][i];
}
}
}
void gotoxy(int x, int y)
{
COORD coord;
coord.X = y;
coord.Y = x;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void drawSqu(struct squ (*sq), int x, int y)
{
int i, j;
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
if(sq->squType[i][j] == 1)
{
gotoxy(x + i, y + j);
printf("%c", SQUARE);
}
}
}
}
void removeSqu(struct squ(*sq), int x, int y)
{
int i, j;
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
if(sq->squType[i][j])
{
face[x + i][y + j] = empty;
gotoxy(x + i, y + j);
printf("%c", EMPTY);
}
}
}
}
int judge(struct squ (*sq), int x, int y)
{
int i, j;
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
if(sq->squType[i][j] == 0)
continue;
else if(face[i + x][j + y] == border || face[i + x][j + y] == square)
{
if(face[1][j + y] == square && x == 1)
{
system("cls");
printf("GAME OVER!\n");
getch();
exit(0);
}
return 0;
}
}
}
return 1;
}
int removeFull(void)
{
int i, j, k, sum;
for(i = HEIGHT - 2; i > 0; i--)
{
sum = 0;
for(j = 1; j < WIDTH - 1; j++)
{
sum += face[i][j];
}
if(!sum)
break;
if(sum == WIDTH - 2)
{
score++;
for(j = 1; j < WIDTH - 1; j++)
{
face[i][j] = empty;
gotoxy(i, j);
printf(" ");
}
for(j = i; j > 1; j--)
{
sum = 0;
for(k = 1; k < WIDTH - 1; k++)
{
sum += face[j - 1][k] + face[j][k];
face[j][k] = face[j - 1][k];
if(face[j][k] == empty)
{
gotoxy(j, k);
printf(" ");
}
else
{
gotoxy(j, k);
printf("%c", SQUARE);
}
}
if(!sum)
return 1;
}
}
}
return 0;
}
void help(void)
{
int x = HEIGHT / 2, y = WIDTH + 5;
gotoxy(x, y);
printf("?");
x++;
gotoxy(x, y);
printf("%-7s: s", "DOWN");
x++;
gotoxy(x, y);
printf("%-7s: a", "LEFT");
x++;
gotoxy(x, y);
printf("%-7s: d", "RIGHT");
x++;
gotoxy(x, y);
printf("%-7s: p", "PAUSE");
x++;
gotoxy(x, y);
printf("%-7s: ESC", "EXIT");
x++;
gotoxy(x, y);
printf("%-7s: space", "ROTATE");
x++;
gotoxy(x, y);
printf("%-7s: r", "RESTART");
x++;
gotoxy(x, y);
printf("%-7s: %1d", "score", score);
}
void update_info(struct squ * sq)
{
int i, j;
int x = HEIGHT / 2 - 8, y = WIDTH + 5;
gotoxy(x, y);
printf("NEXT:");
x += 2;
for(i = 0; i < 4; i++)
{
for(j = 0; j < 4; j++)
{
gotoxy(x + i, y + j);
printf("%c", EMPTY);
}
}
drawSqu(sq, x, y);
gotoxy(HEIGHT - 3, y);
printf("%-7s: %1d", "score", score);
}