一共三个文件
实现得很恶心,很多代码没效率
SCR.c
SCR.h
TETRIS.c
编译输入 gcc TETRIS.c SCR.c -o TETRIS
这程序是终端下运行的 写这程序时 还不会QT
实现得很恶心,很多代码没效率
SCR.c
#include "SCR.h"
typedef enum mode_t {
CHARACTER = 3,
BACKGROUND = 4
} mode_t;
static struct termios orig;
static unsigned int term_init = 0;
void clear(void)
{
fprintf(stderr, "\033[2J");
}
int start_iaction(int sec, int usec, void (*action)(int))
{
struct itimerval itimer;
struct sigaction sa;
int ret;
sa.sa_handler = action;
sigemptyset(&(sa.sa_mask));
sa.sa_flags = 0;
ret = sigaction(SIGALRM, &sa, NULL);
if (ret != 0) {
perror("sigaction");
return -1;
}
itimer.it_value.tv_sec = sec;
itimer.it_value.tv_usec = usec;
itimer.it_interval.tv_sec = sec;
itimer.it_interval.tv_usec = usec;
ret = setitimer(ITIMER_REAL, &itimer, NULL);
if (ret != 0) {
perror("setitimer");
sa.sa_handler = SIG_DFL;
sigemptyset(&(sa.sa_mask));
sa.sa_flags = 0;
sigaction(SIGALRM, &sa, NULL);
return -1;
}
return 0;
}
int stop_iaction(void)
{
struct itimerval itimer;
struct sigaction sa;
int ret;
memset(&itimer, '\0', sizeof(struct itimerval));
ret = setitimer(ITIMER_REAL, &itimer, NULL);
if (ret != 0) {
perror("setitimer");
return -1;
}
sa.sa_handler = SIG_DFL;
sigemptyset(&(sa.sa_mask));
sa.sa_flags = 0;
ret = sigaction(SIGALRM, &sa, NULL);
if (ret != 0) {
perror("sigaction");
}
return ret;
}
int get_winsz(int *row, int *col)
{
struct winsize win;
int ret;
ret = ioctl(STDOUT_FILENO, TIOCGWINSZ, &win);
if (ret != 0) {
perror("ioctl");
return -1;
}
*row = win.ws_row;
*col = win.ws_col;
return 0;
}
int stty(void)
{
struct termios ttystat;
int ret;
ret = tcgetattr(STDIN_FILENO, &ttystat);
if (ret != 0) {
perror("tcgetattr");
return -1;
}
if (term_init == 0) {
memcpy(&orig, &ttystat, sizeof(struct termios));
term_init = 1;
}
ttystat.c_lflag &= ~(ECHO | ICANON);
ttystat.c_cc[VMIN] = 1;
ret = tcsetattr(STDIN_FILENO, TCSANOW, &ttystat);
if (ret != 0) {
perror("tcsetattr");
return -1;
}
printf("\033[?25l\033[?1c");
return 0;
}
int rtty(void)
{
int ret;
if (term_init == 0) {
return 0;
}
ret = tcsetattr(STDIN_FILENO, TCSANOW, &orig);
if (ret != 0) {
perror("tcsetattr");
return -1;
}
printf("\033[?25h\033[?0c");
return 0;
}
int get_input(int expected)
{
char seq[8] = {0};
int ret;
while (1) {
ret = read(STDIN_FILENO, seq, 8);
if (ret < 0 && errno != EINTR) {
perror("read");
return -1;
}
if ((expected & UP) && ret == 3 &&
seq[0] == '\033' && seq[1] == '[' && seq[2] == 'A') {
return UP;
}
if ((expected & DOWN) && ret == 3 &&
seq[0] == '\033' && seq[1] == '[' && seq[2] == 'B') {
return DOWN;
}
if ((expected & RIGHT) && ret == 3 &&
seq[0] == '\033' && seq[1] == '[' && seq[2] == 'C') {
return RIGHT;
}
if ((expected & LEFT) && ret == 3 &&
seq[0] == '\033' && seq[1] == '[' && seq[2] == 'D') {
return LEFT;
}
if ((expected & ESC) && ret == 1 && seq[0] == '\033') {
return ESC;
}
if ((expected & ENTER) && ret == 1 && seq[0] == '\n') {
return ENTER;
}
if ((expected & KEY_Q) && ret == 1 &&
(seq[0] == 'q' || seq[0] == 'Q')) {
return KEY_Q;
}
if ((expected & KEY_S) && ret == 1 &&
(seq[0] == 's' || seq[0] == 'S')) {
return KEY_S;
}
if ((expected & KEY_H) && ret == 1 &&
(seq[0] == 'h' || seq[0] == 'H')) {
return KEY_H;
}
if ((expected & KEY_J) && ret == 1 &&
(seq[0] == 'j' || seq[0] == 'J')) {
return KEY_J;
}
if ((expected & KEY_K) && ret == 1 &&
(seq[0] == 'k' || seq[0] == 'K')) {
return KEY_K;
}
if ((expected & KEY_L) && ret == 1 &&
(seq[0] == 'l' || seq[0] == 'L')) {
return KEY_L;
}
}
return 0;
}
void move_curs(int x, int y)
{
printf("\033[%d;%dH", y, x);
}
void draw_rec(rec_t *rec)
{
int i, j;
printf("\033[%d%d;%d%dm",
BACKGROUND, rec->background, CHARACTER, rec->foreground);
for (i = 0; i < rec->h; ++i) {
printf("\033[%d;%dH", rec->y + i, rec->x);
for (j = 0; j < rec->w; ++j) {
printf("%c", rec->ch);
}
}
printf("\033[0m");
fflush(NULL);
return;
}
SCR.h
#ifndef _SCR_H_
#define _SCR_H_
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <errno.h>
#include <math.h>
typedef enum ch_t {
UP = 0x00000001,
DOWN = 0x00000002,
RIGHT = 0x00000004,
LEFT = 0x00000008,
ESC = 0x00000010,
ENTER = 0x00000020,
KEY_Q = 0x00000040,
KEY_S = 0x00000080,
KEY_H = 0x00000100,
KEY_J = 0x00000200,
KEY_K = 0x00000400,
KEY_L = 0x00000800
} ch_t;
typedef enum color_t {
COLOR_MIN = 0,
BLACK = 0,
RED,
GREEN,
YELLOW,
BLUE,
MAGENTA,
CYAN,
WHITE,
COLOR_MAX = WHITE
} color_t;
typedef struct rec_t {
int x;
int y;
int w;
int h;
char ch;
color_t background;
color_t foreground;
} rec_t;
void clear(void);
int stty(void);
int rtty(void);
int start_iaction(int sec, int usec, void (*)(int));
int stop_iaction(void);
int get_winsz(int *row, int *col);
int get_input(int expected);
void move_curs(int x, int y);
void draw_rec(rec_t *);
#endif
TETRIS.c
#include "SCR.h"
enum {
SEC = 0,
USEC = 500000
};
int A[4][4]={{0,0,0,0},
{0,1,1,0},
{0,1,1,0},
{0,0,0,0}};
int B[4][4]={{0,0,1,0},
{0,0,1,0},
{0,0,1,0},
{0,0,1,0}};
int C[4][4]={{0,1,0,0},
{0,1,1,0},
{0,1,0,0},
{0,0,0,0}};
int D[4][4]={{0,0,0,0},
{0,1,1,0},
{0,0,1,1},
{0,0,0,0}};
int E[4][4]={{0,0,0,0},
{0,0,1,1},
{0,1,1,0},
{0,0,0,0}};
int F[4][4]={{0,0,0,0},
{0,1,1,0},
{0,0,1,0},
{0,0,1,0}};
int G[4][4]={{0,0,0,0},
{0,1,1,0},
{0,1,0,0},
{0,1,0,0}};
int w_col;
int w_row;
#define up 2
#define down 23
#define right 22
#define left 4
int N,top=0;
int tmp_k;
int x,y;
int matrix[10][20];
int __rec_tmp[4][4];
int color[10][20];
rec_t bg;
rec_t __rec[4];
void ___draw_frame(int x,int y){
rec_t __frame;
__frame.x=x;
__frame.y=y+1;
__frame.w = 2;
__frame.h = 20;
__frame.ch = ' ';
__frame.background = RED;
__frame.foreground = RED;
draw_rec(&__frame);
__frame.x=x;
__frame.y=y;
__frame.w = 24;
__frame.h = 1;
__frame.ch = ' ';
__frame.background = RED;
__frame.foreground = RED;
draw_rec(&__frame);
__frame.x=x+22;
__frame.y=y+1;
__frame.w = 2;
__frame.h = 20;
__frame.ch = ' ';
__frame.background = RED;
__frame.foreground = RED;
draw_rec(&__frame);
__frame.x=x;
__frame.y=y+21;
__frame.w = 24;
__frame.h = 1;
__frame.ch = ' ';
__frame.background = RED;
__frame.foreground = RED;
draw_rec(&__frame);
}
void ___draw_bg(){
int i=0;
int j=0;
rec_t tmp;
for(i=0;i<20;i++){
for(j=0;j<10;j++){
tmp.x=(j+2)*2;
tmp.y=i+3;
tmp.w = 2;
tmp.h = 1;
tmp.ch = ' ';
tmp.background = color[j][i];
tmp.foreground = color[j][i];
draw_rec(&tmp);
}
}
___draw_frame(2,2);
}
void ___draw_square(int square[4][4]){
int i,j,k=0;
tmp_k=4;
k=0;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
if(square[i][j]==1){
__rec[k].x=(i+4)*2;
__rec[k].y=(j+2)*1;
__rec[k].w = 2;
__rec[k].h = 1;
__rec[k].ch = ' ';
__rec[k].background = N;
__rec[k].foreground = N;
k++;
}
}
}
x=4;
y=2;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
__rec_tmp[i][j]=square[i][j];
for(i=0;i<4;i++){
if(matrix[(__rec[i].x-4)/2][__rec[i].y-3]==1){
top=1;
}
}
}
int MAX_Y(rec_t __rec[],int count){
int max=0,i;
for(i=0;i<count;i++){
if(__rec[i].y >= max)
max=__rec[i].y;
}
return max;
}
int MAX_X(rec_t __rec[],int count){
int max=0,i;
for(i=0;i<count;i++){
if(__rec[i].x >= max)
max=__rec[i].x;
}
return max;
}
int MIN_X(rec_t __rec[],int count){
int min=__rec[0].x;
int i;
for(i=0;i<count;i++){
if(__rec[i].x <= min)
min=__rec[i].x;
}
return min;
}
int MIN_Y(rec_t __rec[],int count){
int min=__rec[0].y;
int i;
for(i=0;i<count;i++){
if(__rec[i].y <= min)
min=__rec[i].y;
}
return min;
}
int GameOver(){
int i,j,tmp1=0,tmp2=0;
for(i=0;i<20;i++){
for(j=0;j<10;j++){
tmp1 += matrix[j][i];
}
if(tmp1>0){
tmp2++;
}
if(tmp2==20 || top==1){
fprintf(stderr,"\n\tGame Over\n");
stop_iaction();
rtty();
exit(1);
}
tmp1=0;
}
return 0;
}
void Delete(){
int i,j,m,n,tmp;
for(i=0;i<20;i++){
for(j=0;j<10;j++){
tmp += matrix[j][i];
}
if(tmp==10){
for(n=i;n>0;n--){
for(m=0;m<10;m++){
matrix[m][n]=matrix[m][n-1];
color[m][n]=color[m][n-1];
}
}
}
tmp=0;
}
}
void Change(int arr[][4]){
int i=4,j=4;
int acc[4][4];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
acc[i][j]=arr[i][j];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
arr[i][j]=acc[j][3-i];
}
int Limit_D(rec_t __rec[],int tmp_k){
int i,j,status=0;
int max;
int flag=0;
for(i=0;i<tmp_k;i++){
flag=0;
for(j=0;j<tmp_k;j++){
if(__rec[i].x==__rec[j].x){
max=(__rec[i].y >= __rec[j].y ? __rec[i].y : __rec[j].y);
flag=1;
}
}
if(flag==1){
if(matrix[(__rec[i].x-4)/2][max-2]==1)
status=1;
}
if(flag==0){
if(matrix[(__rec[i].x-4)/2][__rec[i].y-2]==1)
status=1;
}
}
return status;
}
int Limit_R(rec_t __rec[],int tmp_k){
int i,j,status=0;
int max=0;
int flag=0;
for(i=0;i<tmp_k;i++){
flag=0;
max=0;
for(j=0;j<tmp_k;j++){
if(__rec[i].y==__rec[j].y){
max=(__rec[i].x > __rec[j].x ? __rec[i].x : __rec[j].x);
flag=1;
}
}
if(flag==1){
if(matrix[(max-4)/2+1][__rec[i].y-3]==1)
status=1;
}
if(flag==0){
if(matrix[(__rec[i].x-4)/2+1][__rec[i].y-3]==1)
status=1;
}
}
return status;
}
int Limit_L(rec_t __rec[],int tmp_k){
int i,j,status=0;
int min;
int flag=0;
for(i=0;i<tmp_k;i++){
min=MAX_X(__rec,tmp_k);
flag=0;
for(j=0;j<tmp_k;j++){
if(__rec[i].y==__rec[j].y && min >= __rec[j].x){
min=__rec[j].x;
flag=1;
}
}
if(flag==1){
if(matrix[(min-4)/2-1][__rec[i].y-3]==1)
return 1;
}
if(flag==0){
if(matrix[(__rec[i].x-4)/2-1][__rec[i].y-3]==1)
return 1;
}
}
return status;
}
void Transform(){
int i,j,k;
rec_t tmp[4];
int tmp_m[4][4];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
tmp_m[i][j]=__rec_tmp[i][j];
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=0;
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=WHITE;
Change(tmp_m);
k=0;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
if(tmp_m[i][j]==1){
tmp[k].x=(i+x)*2;
tmp[k].y=(j+y)*1;
tmp[k].w = 2;
tmp[k].h = 1;
tmp[k].ch = ' ';
tmp[k].background = N;
tmp[k].foreground = N;
k++;
}
}
}
if(Limit_D(tmp,4)==0 && Limit_R(tmp,4)==0 && \
Limit_L(tmp,4)==0 && MIN_X(tmp,4)>left && \
MAX_X(tmp,4)<right && MAX_Y(tmp,4)<down && \
MIN_Y(tmp,4)>up){
for(i=0;i<4;i++)
__rec[i]=tmp[i];
for(i=0;i<4;i++)
for(j=0;j<4;j++)
__rec_tmp[i][j]=tmp_m[i][j];
}
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=1;
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=N;
}
void CALL_GATE(int sig){
int i=0;
if((Limit_D(__rec,4)==0)&&(MAX_Y(__rec,tmp_k)<22)){
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=0;
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=WHITE;
for(i=0;i<tmp_k;i++)
__rec[i].y++;
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=1;
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=N;
y++;
___draw_bg();
}else if(GameOver()==0){
Delete();
N=random()%7;
switch(N){
case 0:
___draw_square(A);
break;
case 1:
___draw_square(B);
break;
case 2:
___draw_square(C);
break;
case 3:
___draw_square(D);
break;
case 4:
___draw_square(E);
break;
case 5:
___draw_square(F);
break;
case 6:
___draw_square(G);
break;
default:
break;
}
if(GameOver()==0&&top==0){
___draw_bg();
}
}
}
void Init(void){
int i=0;
int j=0;
int ret;
for(i=0;i<10;i++)
for(j=0;j<20;j++)
matrix[i][j]=0;
for(i=0;i<10;i++)
for(j=0;j<20;j++)
color[i][j]=WHITE;
ret = get_winsz(&w_row, &w_col);
if(ret!=0){
fprintf(stderr,"ERROR\n");
exit(1);
}
clear();
bg.x = 1;
bg.y = 1;
bg.w = w_col;
bg.h = w_row;
bg.ch = ' ';
bg.background = WHITE;
bg.foreground = WHITE;
draw_rec(&bg);
N=4;
___draw_square(E);
___draw_frame(2,2);
for(i=0;i<tmp_k;i++)
draw_rec(&__rec[i]);
return;
}
void Response(void){
int out=0;
int ret=0;
int i=0;
while (out != 1) {
ret = get_input(UP | DOWN | LEFT | RIGHT | ESC);
if (ret == -1) {
printf("get input error!\n");
break;
}
switch (ret) {
case LEFT:
if (MIN_X(__rec,tmp_k) > left && Limit_L(__rec,4)==0) {
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=WHITE;
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=0;
for(i=0;i<tmp_k;i++)
__rec[i].x -= 2;
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=N;
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=1;
x--;
}
break;
case DOWN:
if (MAX_Y(__rec,tmp_k) + __rec[0].h < down && Limit_D(__rec,4)==0){
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=WHITE;
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=0;
for(i=0;i<tmp_k;i++)
__rec[i].y += 1;
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=N;
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=1;
y++;
}
break;
case UP:
Transform();
break;
case RIGHT:
if (MAX_X(__rec,tmp_k) + __rec[0].w <= right && Limit_R(__rec,4)==0){
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=WHITE;
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=0;
for(i=0;i<tmp_k;i++)
__rec[i].x += 2;
for(i=0;i<tmp_k;i++)
color[(__rec[i].x-4)/2][__rec[i].y-3]=N;
for(i=0;i<tmp_k;i++)
matrix[(__rec[i].x-4)/2][__rec[i].y-3]=1;
x++;
}
break;
case ESC:
out = 1;
break;
default:
break;
}
___draw_bg();
}
return;
}
int main(void){
Init();
stty();
start_iaction(SEC, USEC, CALL_GATE);
Response();
stop_iaction();
rtty();
move_curs(1, 1);
clear();
return 0;
}
编译输入 gcc TETRIS.c SCR.c -o TETRIS
这程序是终端下运行的 写这程序时 还不会QT